DevelopmentSettings.java revision 37fb338cda1066e20a813ce0d33b38fa0840bdcb
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.development;
18
19import android.Manifest;
20import android.app.Activity;
21import android.app.ActivityManager;
22import android.app.AlertDialog;
23import android.app.AppOpsManager;
24import android.app.AppOpsManager.PackageOps;
25import android.app.Dialog;
26import android.app.backup.IBackupManager;
27import android.bluetooth.BluetoothA2dp;
28import android.bluetooth.BluetoothAdapter;
29import android.bluetooth.BluetoothCodecConfig;
30import android.bluetooth.BluetoothCodecStatus;
31import android.bluetooth.BluetoothHeadset;
32import android.bluetooth.BluetoothProfile;
33import android.content.BroadcastReceiver;
34import android.content.ContentResolver;
35import android.content.Context;
36import android.content.DialogInterface;
37import android.content.Intent;
38import android.content.IntentFilter;
39import android.content.pm.ApplicationInfo;
40import android.content.pm.IShortcutService;
41import android.content.pm.PackageManager;
42import android.content.pm.PackageManager.NameNotFoundException;
43import android.content.pm.ResolveInfo;
44import android.content.res.Resources;
45import android.hardware.usb.IUsbManager;
46import android.hardware.usb.UsbManager;
47import android.net.wifi.WifiManager;
48import android.os.AsyncTask;
49import android.os.BatteryManager;
50import android.os.Build;
51import android.os.Bundle;
52import android.os.IBinder;
53import android.os.Parcel;
54import android.os.RemoteException;
55import android.os.ServiceManager;
56import android.os.StrictMode;
57import android.os.SystemProperties;
58import android.os.UserManager;
59import android.os.storage.IStorageManager;
60import android.provider.SearchIndexableResource;
61import android.provider.Settings;
62import android.service.persistentdata.PersistentDataBlockManager;
63import android.support.annotation.VisibleForTesting;
64import android.support.v14.preference.SwitchPreference;
65import android.support.v7.preference.ListPreference;
66import android.support.v7.preference.Preference;
67import android.support.v7.preference.Preference.OnPreferenceChangeListener;
68import android.support.v7.preference.PreferenceGroup;
69import android.support.v7.preference.PreferenceScreen;
70import android.telephony.TelephonyManager;
71import android.text.TextUtils;
72import android.util.Log;
73import android.view.IWindowManager;
74import android.view.LayoutInflater;
75import android.view.ThreadedRenderer;
76import android.view.View;
77import android.view.ViewGroup;
78import android.view.accessibility.AccessibilityManager;
79import android.webkit.IWebViewUpdateService;
80import android.webkit.WebViewFactory;
81import android.widget.Switch;
82import android.widget.Toast;
83
84import com.android.internal.app.LocalePicker;
85import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
86import com.android.settings.ChooseLockSettingsHelper;
87import com.android.settings.R;
88import com.android.settings.RestrictedSettingsFragment;
89import com.android.settings.SettingsActivity;
90import com.android.settings.Utils;
91import com.android.settings.dashboard.DashboardFeatureProvider;
92import com.android.settings.overlay.FeatureFactory;
93import com.android.settings.search.BaseSearchIndexProvider;
94import com.android.settings.search.Indexable;
95import com.android.settings.webview.WebViewAppPreferenceController;
96import com.android.settings.widget.SwitchBar;
97import com.android.settingslib.RestrictedLockUtils;
98import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
99import com.android.settingslib.RestrictedSwitchPreference;
100import com.android.settingslib.drawer.CategoryKey;
101
102import java.util.ArrayList;
103import java.util.Arrays;
104import java.util.HashSet;
105import java.util.List;
106
107/*
108 * Displays preferences for application developers.
109 */
110public class DevelopmentSettings extends RestrictedSettingsFragment
111        implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener,
112        OnPreferenceChangeListener, SwitchBar.OnSwitchChangeListener, Indexable {
113    private static final String TAG = "DevelopmentSettings";
114
115    /**
116     * Preference file were development settings prefs are stored.
117     */
118    public static final String PREF_FILE = "development";
119
120    /**
121     * Whether to show the development settings to the user.  Default is false.
122     */
123    public static final String PREF_SHOW = "show";
124
125    private static final String ENABLE_ADB = "enable_adb";
126    private static final String CLEAR_ADB_KEYS = "clear_adb_keys";
127    private static final String ENABLE_TERMINAL = "enable_terminal";
128    private static final String KEEP_SCREEN_ON = "keep_screen_on";
129    private static final String BT_HCI_SNOOP_LOG = "bt_hci_snoop_log";
130    private static final String WEBVIEW_MULTIPROCESS_KEY = "enable_webview_multiprocess";
131    private static final String ENABLE_OEM_UNLOCK = "oem_unlock_enable";
132    private static final String HDCP_CHECKING_KEY = "hdcp_checking";
133    private static final String HDCP_CHECKING_PROPERTY = "persist.sys.hdcp_checking";
134    private static final String LOCAL_BACKUP_PASSWORD = "local_backup_password";
135    private static final String HARDWARE_UI_PROPERTY = "persist.sys.ui.hw";
136    private static final String MSAA_PROPERTY = "debug.egl.force_msaa";
137    private static final String OPENGL_TRACES_PROPERTY = "debug.egl.trace";
138    private static final String TUNER_UI_KEY = "tuner_ui";
139    private static final String COLOR_TEMPERATURE_PROPERTY = "persist.sys.debug.color_temp";
140
141    private static final String DEBUG_APP_KEY = "debug_app";
142    private static final String WAIT_FOR_DEBUGGER_KEY = "wait_for_debugger";
143    private static final String MOCK_LOCATION_APP_KEY = "mock_location_app";
144    private static final String VERIFY_APPS_OVER_USB_KEY = "verify_apps_over_usb";
145    private static final String DEBUG_VIEW_ATTRIBUTES = "debug_view_attributes";
146    private static final String FORCE_ALLOW_ON_EXTERNAL_KEY = "force_allow_on_external";
147    private static final String STRICT_MODE_KEY = "strict_mode";
148    private static final String POINTER_LOCATION_KEY = "pointer_location";
149    private static final String SHOW_TOUCHES_KEY = "show_touches";
150    private static final String SHOW_SCREEN_UPDATES_KEY = "show_screen_updates";
151    private static final String DISABLE_OVERLAYS_KEY = "disable_overlays";
152    private static final String SIMULATE_COLOR_SPACE = "simulate_color_space";
153    private static final String USB_AUDIO_KEY = "usb_audio";
154    private static final String FORCE_HARDWARE_UI_KEY = "force_hw_ui";
155    private static final String FORCE_MSAA_KEY = "force_msaa";
156    private static final String TRACK_FRAME_TIME_KEY = "track_frame_time";
157    private static final String SHOW_NON_RECTANGULAR_CLIP_KEY = "show_non_rect_clip";
158    private static final String SHOW_HW_SCREEN_UPDATES_KEY = "show_hw_screen_udpates";
159    private static final String SHOW_HW_LAYERS_UPDATES_KEY = "show_hw_layers_udpates";
160    private static final String DEBUG_HW_OVERDRAW_KEY = "debug_hw_overdraw";
161    private static final String DEBUG_HW_RENDERER_KEY = "debug_hw_renderer";
162    private static final String DEBUG_LAYOUT_KEY = "debug_layout";
163    private static final String FORCE_RTL_LAYOUT_KEY = "force_rtl_layout_all_locales";
164    private static final String WINDOW_ANIMATION_SCALE_KEY = "window_animation_scale";
165    private static final String TRANSITION_ANIMATION_SCALE_KEY = "transition_animation_scale";
166    private static final String ANIMATOR_DURATION_SCALE_KEY = "animator_duration_scale";
167    private static final String OVERLAY_DISPLAY_DEVICES_KEY = "overlay_display_devices";
168    private static final String DEBUG_DEBUGGING_CATEGORY_KEY = "debug_debugging_category";
169    private static final String SELECT_LOGD_SIZE_KEY = "select_logd_size";
170    private static final String SELECT_LOGD_SIZE_PROPERTY = "persist.logd.size";
171    private static final String SELECT_LOGD_TAG_PROPERTY = "persist.log.tag";
172    // Tricky, isLoggable only checks for first character, assumes silence
173    private static final String SELECT_LOGD_TAG_SILENCE = "Settings";
174    private static final String SELECT_LOGD_SNET_TAG_PROPERTY = "persist.log.tag.snet_event_log";
175    private static final String SELECT_LOGD_RUNTIME_SNET_TAG_PROPERTY = "log.tag.snet_event_log";
176    private static final String SELECT_LOGD_DEFAULT_SIZE_PROPERTY = "ro.logd.size";
177    private static final String SELECT_LOGD_DEFAULT_SIZE_VALUE = "262144";
178    private static final String SELECT_LOGD_SVELTE_DEFAULT_SIZE_VALUE = "65536";
179    // 32768 is merely a menu marker, 64K is our lowest log buffer size we replace it with.
180    private static final String SELECT_LOGD_MINIMUM_SIZE_VALUE = "65536";
181    private static final String SELECT_LOGD_OFF_SIZE_MARKER_VALUE = "32768";
182    private static final String SELECT_LOGPERSIST_KEY = "select_logpersist";
183    private static final String SELECT_LOGPERSIST_PROPERTY = "persist.logd.logpersistd";
184    private static final String ACTUAL_LOGPERSIST_PROPERTY = "logd.logpersistd";
185    private static final String SELECT_LOGPERSIST_PROPERTY_SERVICE = "logcatd";
186    private static final String SELECT_LOGPERSIST_PROPERTY_CLEAR = "clear";
187    private static final String SELECT_LOGPERSIST_PROPERTY_STOP = "stop";
188    private static final String SELECT_LOGPERSIST_PROPERTY_BUFFER =
189            "persist.logd.logpersistd.buffer";
190    private static final String ACTUAL_LOGPERSIST_PROPERTY_BUFFER = "logd.logpersistd.buffer";
191    private static final String ACTUAL_LOGPERSIST_PROPERTY_ENABLE = "logd.logpersistd.enable";
192
193    private static final String WIFI_DISPLAY_CERTIFICATION_KEY = "wifi_display_certification";
194    private static final String WIFI_VERBOSE_LOGGING_KEY = "wifi_verbose_logging";
195    private static final String WIFI_AGGRESSIVE_HANDOVER_KEY = "wifi_aggressive_handover";
196    private static final String WIFI_ALLOW_SCAN_WITH_TRAFFIC_KEY = "wifi_allow_scan_with_traffic";
197    private static final String USB_CONFIGURATION_KEY = "select_usb_configuration";
198    private static final String MOBILE_DATA_ALWAYS_ON = "mobile_data_always_on";
199    private static final String KEY_COLOR_MODE = "color_mode";
200    private static final String FORCE_RESIZABLE_KEY = "force_resizable_activities";
201    private static final String COLOR_TEMPERATURE_KEY = "color_temperature";
202
203    private static final String BLUETOOTH_DISABLE_ABSOLUTE_VOLUME_KEY =
204            "bluetooth_disable_absolute_volume";
205    private static final String BLUETOOTH_DISABLE_ABSOLUTE_VOLUME_PROPERTY =
206            "persist.bluetooth.disableabsvol";
207    private static final String BLUETOOTH_AVRCP_VERSION_PROPERTY =
208                                    "persist.bluetooth.avrcpversion";
209    private static final String BLUETOOTH_ENABLE_INBAND_RINGING_PROPERTY =
210                                    "persist.bluetooth.enableinbandringing";
211
212    private static final String BLUETOOTH_ENABLE_INBAND_RINGING_KEY = "bluetooth_enable_inband_ringing";
213    private static final String BLUETOOTH_SELECT_AVRCP_VERSION_KEY = "bluetooth_select_avrcp_version";
214    private static final String BLUETOOTH_SELECT_A2DP_CODEC_KEY = "bluetooth_select_a2dp_codec";
215    private static final String BLUETOOTH_SELECT_A2DP_SAMPLE_RATE_KEY = "bluetooth_select_a2dp_sample_rate";
216    private static final String BLUETOOTH_SELECT_A2DP_BITS_PER_SAMPLE_KEY = "bluetooth_select_a2dp_bits_per_sample";
217    private static final String BLUETOOTH_SELECT_A2DP_CHANNEL_MODE_KEY = "bluetooth_select_a2dp_channel_mode";
218    private static final String BLUETOOTH_SELECT_A2DP_LDAC_PLAYBACK_QUALITY_KEY = "bluetooth_select_a2dp_ldac_playback_quality";
219
220    private static final String INACTIVE_APPS_KEY = "inactive_apps";
221
222    private static final String IMMEDIATELY_DESTROY_ACTIVITIES_KEY
223            = "immediately_destroy_activities";
224    private static final String APP_PROCESS_LIMIT_KEY = "app_process_limit";
225
226    private static final String BACKGROUND_CHECK_KEY = "background_check";
227
228    private static final String SHOW_ALL_ANRS_KEY = "show_all_anrs";
229
230    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
231
232    private static final String TERMINAL_APP_PACKAGE = "com.android.terminal";
233
234    private static final String KEY_CONVERT_FBE = "convert_to_file_encryption";
235
236    private static final String OTA_DISABLE_AUTOMATIC_UPDATE_KEY = "ota_disable_automatic_update";
237
238    private static final int RESULT_DEBUG_APP = 1000;
239    private static final int RESULT_MOCK_LOCATION_APP = 1001;
240
241    private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst";
242    private static final String FLASH_LOCKED_PROP = "ro.boot.flash.locked";
243
244    private static final String SHORTCUT_MANAGER_RESET_KEY = "reset_shortcut_manager_throttling";
245
246    private static final int REQUEST_CODE_ENABLE_OEM_UNLOCK = 0;
247
248    private static final int[] MOCK_LOCATION_APP_OPS = new int[]{AppOpsManager.OP_MOCK_LOCATION};
249
250    private IWindowManager mWindowManager;
251    private IBackupManager mBackupManager;
252    private IWebViewUpdateService mWebViewUpdateService;
253    private UserManager mUm;
254    private WifiManager mWifiManager;
255    private PersistentDataBlockManager mOemUnlockManager;
256    private TelephonyManager mTelephonyManager;
257
258    private SwitchBar mSwitchBar;
259
260    private boolean mHaveDebugSettings;
261    private boolean mDontPokeProperties;
262    private SwitchPreference mEnableAdb;
263    private Preference mClearAdbKeys;
264    private SwitchPreference mEnableTerminal;
265    private RestrictedSwitchPreference mKeepScreenOn;
266    private SwitchPreference mBtHciSnoopLog;
267    private RestrictedSwitchPreference mEnableOemUnlock;
268    private SwitchPreference mDebugViewAttributes;
269    private SwitchPreference mForceAllowOnExternal;
270
271    private Preference mPassword;
272    private String mDebugApp;
273    private Preference mDebugAppPref;
274
275    private String mMockLocationApp;
276    private Preference mMockLocationAppPref;
277
278    private SwitchPreference mWaitForDebugger;
279    private SwitchPreference mVerifyAppsOverUsb;
280    private SwitchPreference mWifiDisplayCertification;
281    private SwitchPreference mWifiVerboseLogging;
282    private SwitchPreference mWifiAggressiveHandover;
283    private SwitchPreference mMobileDataAlwaysOn;
284    private SwitchPreference mBluetoothDisableAbsVolume;
285    private SwitchPreference mBluetoothEnableInbandRinging;
286
287    private BluetoothA2dp mBluetoothA2dp;
288    private final Object mBluetoothA2dpLock = new Object();
289    private ListPreference mBluetoothSelectAvrcpVersion;
290    private ListPreference mBluetoothSelectA2dpCodec;
291    private ListPreference mBluetoothSelectA2dpSampleRate;
292    private ListPreference mBluetoothSelectA2dpBitsPerSample;
293    private ListPreference mBluetoothSelectA2dpChannelMode;
294    private ListPreference mBluetoothSelectA2dpLdacPlaybackQuality;
295
296    private SwitchPreference mOtaDisableAutomaticUpdate;
297    private SwitchPreference mWifiAllowScansWithTraffic;
298    private SwitchPreference mStrictMode;
299    private SwitchPreference mPointerLocation;
300    private SwitchPreference mShowTouches;
301    private SwitchPreference mShowScreenUpdates;
302    private SwitchPreference mDisableOverlays;
303    private SwitchPreference mForceHardwareUi;
304    private SwitchPreference mForceMsaa;
305    private SwitchPreference mShowHwScreenUpdates;
306    private SwitchPreference mShowHwLayersUpdates;
307    private SwitchPreference mDebugLayout;
308    private SwitchPreference mForceRtlLayout;
309    private ListPreference mDebugHwOverdraw;
310    private ListPreference mDebugHwRenderer;
311    private ListPreference mLogdSize;
312    private ListPreference mLogpersist;
313    private ListPreference mUsbConfiguration;
314    private ListPreference mTrackFrameTime;
315    private ListPreference mShowNonRectClip;
316    private ListPreference mWindowAnimationScale;
317    private ListPreference mTransitionAnimationScale;
318    private ListPreference mAnimatorDurationScale;
319    private ListPreference mOverlayDisplayDevices;
320
321    private WebViewAppPreferenceController mWebViewAppPrefController;
322    private SwitchPreference mWebViewMultiprocess;
323
324    private ListPreference mSimulateColorSpace;
325
326    private SwitchPreference mUSBAudio;
327    private SwitchPreference mImmediatelyDestroyActivities;
328
329    private ListPreference mAppProcessLimit;
330
331    private SwitchPreference mShowAllANRs;
332
333    private ColorModePreference mColorModePreference;
334
335    private SwitchPreference mForceResizable;
336
337    private SwitchPreference mColorTemperaturePreference;
338
339    private final ArrayList<Preference> mAllPrefs = new ArrayList<Preference>();
340
341    private final ArrayList<SwitchPreference> mResetSwitchPrefs
342            = new ArrayList<SwitchPreference>();
343
344    private final HashSet<Preference> mDisabledPrefs = new HashSet<Preference>();
345    // To track whether a confirmation dialog was clicked.
346    private boolean mDialogClicked;
347    private Dialog mEnableDialog;
348    private Dialog mAdbDialog;
349
350    private Dialog mAdbKeysDialog;
351    private boolean mUnavailable;
352
353    private boolean mLogpersistCleared;
354    private Dialog mLogpersistClearDialog;
355    private DashboardFeatureProvider mDashboardFeatureProvider;
356    private DevelopmentSettingsEnabler mSettingsEnabler;
357    private BugReportPreferenceController mBugReportController;
358    private BugReportInPowerPreferenceController mBugReportInPowerController;
359    private TelephonyMonitorPreferenceController mTelephonyMonitorController;
360
361    public DevelopmentSettings() {
362        super(UserManager.DISALLOW_DEBUGGING_FEATURES);
363    }
364
365    @Override
366    public int getMetricsCategory() {
367        return MetricsEvent.DEVELOPMENT;
368    }
369
370    @Override
371    public void onAttach(Context context) {
372        super.onAttach(context);
373        mSettingsEnabler = new DevelopmentSettingsEnabler(context, getLifecycle());
374        mDashboardFeatureProvider = FeatureFactory.getFactory(context)
375                .getDashboardFeatureProvider(context);
376    }
377
378    @Override
379    public void onCreate(Bundle icicle) {
380        super.onCreate(icicle);
381
382        mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
383        mBackupManager = IBackupManager.Stub.asInterface(
384                ServiceManager.getService(Context.BACKUP_SERVICE));
385        mWebViewUpdateService = WebViewFactory.getUpdateService();
386        mOemUnlockManager = (PersistentDataBlockManager) getActivity()
387                .getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
388        mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
389
390        mUm = (UserManager) getSystemService(Context.USER_SERVICE);
391
392        mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
393
394        mBugReportController = new BugReportPreferenceController(getActivity());
395        mBugReportInPowerController = new BugReportInPowerPreferenceController(getActivity());
396        mTelephonyMonitorController = new TelephonyMonitorPreferenceController(getActivity());
397        mWebViewAppPrefController = new WebViewAppPreferenceController(getActivity());
398
399        setIfOnlyAvailableForAdmins(true);
400        if (isUiRestricted() || !Utils.isDeviceProvisioned(getActivity())) {
401            // Block access to developer options if the user is not the owner, if user policy
402            // restricts it, or if the device has not been provisioned
403            mUnavailable = true;
404            addPreferencesFromResource(R.xml.empty_settings);
405            return;
406        }
407
408        addPreferencesFromResource(R.xml.development_prefs);
409
410        final PreferenceGroup debugDebuggingCategory = (PreferenceGroup)
411                findPreference(DEBUG_DEBUGGING_CATEGORY_KEY);
412        mEnableAdb = findAndInitSwitchPref(ENABLE_ADB);
413        mClearAdbKeys = findPreference(CLEAR_ADB_KEYS);
414        if (!SystemProperties.getBoolean("ro.adb.secure", false)) {
415            if (debugDebuggingCategory != null) {
416                debugDebuggingCategory.removePreference(mClearAdbKeys);
417            }
418        }
419        mAllPrefs.add(mClearAdbKeys);
420        mEnableTerminal = findAndInitSwitchPref(ENABLE_TERMINAL);
421        if (!isPackageInstalled(getActivity(), TERMINAL_APP_PACKAGE)) {
422            debugDebuggingCategory.removePreference(mEnableTerminal);
423            mEnableTerminal = null;
424        }
425
426        mBugReportController.displayPreference(getPreferenceScreen());
427        mBugReportInPowerController.displayPreference(getPreferenceScreen());
428        mTelephonyMonitorController.displayPreference(getPreferenceScreen());
429        mWebViewAppPrefController.displayPreference(getPreferenceScreen());
430
431        mKeepScreenOn = (RestrictedSwitchPreference) findAndInitSwitchPref(KEEP_SCREEN_ON);
432        mBtHciSnoopLog = findAndInitSwitchPref(BT_HCI_SNOOP_LOG);
433        mEnableOemUnlock = (RestrictedSwitchPreference) findAndInitSwitchPref(ENABLE_OEM_UNLOCK);
434        if (!showEnableOemUnlockPreference()) {
435            removePreference(mEnableOemUnlock);
436            mEnableOemUnlock = null;
437        }
438
439        mDebugViewAttributes = findAndInitSwitchPref(DEBUG_VIEW_ATTRIBUTES);
440        mForceAllowOnExternal = findAndInitSwitchPref(FORCE_ALLOW_ON_EXTERNAL_KEY);
441        mPassword = findPreference(LOCAL_BACKUP_PASSWORD);
442        mAllPrefs.add(mPassword);
443
444        if (!mUm.isAdminUser()) {
445            disableForUser(mEnableAdb);
446            disableForUser(mClearAdbKeys);
447            disableForUser(mEnableTerminal);
448            disableForUser(mPassword);
449        }
450
451        mDebugAppPref = findPreference(DEBUG_APP_KEY);
452        mAllPrefs.add(mDebugAppPref);
453        mWaitForDebugger = findAndInitSwitchPref(WAIT_FOR_DEBUGGER_KEY);
454
455        mMockLocationAppPref = findPreference(MOCK_LOCATION_APP_KEY);
456        mAllPrefs.add(mMockLocationAppPref);
457
458        mVerifyAppsOverUsb = findAndInitSwitchPref(VERIFY_APPS_OVER_USB_KEY);
459        if (!showVerifierSetting()) {
460            if (debugDebuggingCategory != null) {
461                debugDebuggingCategory.removePreference(mVerifyAppsOverUsb);
462            } else {
463                mVerifyAppsOverUsb.setEnabled(false);
464            }
465        }
466        mStrictMode = findAndInitSwitchPref(STRICT_MODE_KEY);
467        mPointerLocation = findAndInitSwitchPref(POINTER_LOCATION_KEY);
468        mShowTouches = findAndInitSwitchPref(SHOW_TOUCHES_KEY);
469        mShowScreenUpdates = findAndInitSwitchPref(SHOW_SCREEN_UPDATES_KEY);
470        mDisableOverlays = findAndInitSwitchPref(DISABLE_OVERLAYS_KEY);
471        mForceHardwareUi = findAndInitSwitchPref(FORCE_HARDWARE_UI_KEY);
472        mForceMsaa = findAndInitSwitchPref(FORCE_MSAA_KEY);
473        mTrackFrameTime = addListPreference(TRACK_FRAME_TIME_KEY);
474        mShowNonRectClip = addListPreference(SHOW_NON_RECTANGULAR_CLIP_KEY);
475        mShowHwScreenUpdates = findAndInitSwitchPref(SHOW_HW_SCREEN_UPDATES_KEY);
476        mShowHwLayersUpdates = findAndInitSwitchPref(SHOW_HW_LAYERS_UPDATES_KEY);
477        mDebugLayout = findAndInitSwitchPref(DEBUG_LAYOUT_KEY);
478        mForceRtlLayout = findAndInitSwitchPref(FORCE_RTL_LAYOUT_KEY);
479        mDebugHwOverdraw = addListPreference(DEBUG_HW_OVERDRAW_KEY);
480        mDebugHwRenderer = addListPreference(DEBUG_HW_RENDERER_KEY);
481        mWifiDisplayCertification = findAndInitSwitchPref(WIFI_DISPLAY_CERTIFICATION_KEY);
482        mWifiVerboseLogging = findAndInitSwitchPref(WIFI_VERBOSE_LOGGING_KEY);
483        mWifiAggressiveHandover = findAndInitSwitchPref(WIFI_AGGRESSIVE_HANDOVER_KEY);
484        mWifiAllowScansWithTraffic = findAndInitSwitchPref(WIFI_ALLOW_SCAN_WITH_TRAFFIC_KEY);
485        mMobileDataAlwaysOn = findAndInitSwitchPref(MOBILE_DATA_ALWAYS_ON);
486        mLogdSize = addListPreference(SELECT_LOGD_SIZE_KEY);
487        if ("1".equals(SystemProperties.get("ro.debuggable", "0"))) {
488            mLogpersist = addListPreference(SELECT_LOGPERSIST_KEY);
489        } else {
490            mLogpersist = (ListPreference) findPreference(SELECT_LOGPERSIST_KEY);
491            if (mLogpersist != null) {
492                mLogpersist.setEnabled(false);
493                if (debugDebuggingCategory != null) {
494                    debugDebuggingCategory.removePreference(mLogpersist);
495                }
496            }
497            mLogpersist = null;
498        }
499        mUsbConfiguration = addListPreference(USB_CONFIGURATION_KEY);
500        mWebViewMultiprocess = findAndInitSwitchPref(WEBVIEW_MULTIPROCESS_KEY);
501        mBluetoothDisableAbsVolume = findAndInitSwitchPref(BLUETOOTH_DISABLE_ABSOLUTE_VOLUME_KEY);
502        mBluetoothEnableInbandRinging = findAndInitSwitchPref(BLUETOOTH_ENABLE_INBAND_RINGING_KEY);
503        if (!BluetoothHeadset.isInbandRingingSupported(getContext())) {
504            removePreference(mBluetoothEnableInbandRinging);
505            mBluetoothEnableInbandRinging = null;
506        }
507
508        mBluetoothSelectAvrcpVersion = addListPreference(BLUETOOTH_SELECT_AVRCP_VERSION_KEY);
509        mBluetoothSelectA2dpCodec = addListPreference(BLUETOOTH_SELECT_A2DP_CODEC_KEY);
510        mBluetoothSelectA2dpSampleRate = addListPreference(BLUETOOTH_SELECT_A2DP_SAMPLE_RATE_KEY);
511        mBluetoothSelectA2dpBitsPerSample = addListPreference(BLUETOOTH_SELECT_A2DP_BITS_PER_SAMPLE_KEY);
512        mBluetoothSelectA2dpChannelMode = addListPreference(BLUETOOTH_SELECT_A2DP_CHANNEL_MODE_KEY);
513        mBluetoothSelectA2dpLdacPlaybackQuality = addListPreference(BLUETOOTH_SELECT_A2DP_LDAC_PLAYBACK_QUALITY_KEY);
514        initBluetoothConfigurationValues();
515
516        mWindowAnimationScale = addListPreference(WINDOW_ANIMATION_SCALE_KEY);
517        mTransitionAnimationScale = addListPreference(TRANSITION_ANIMATION_SCALE_KEY);
518        mAnimatorDurationScale = addListPreference(ANIMATOR_DURATION_SCALE_KEY);
519        mOverlayDisplayDevices = addListPreference(OVERLAY_DISPLAY_DEVICES_KEY);
520        mSimulateColorSpace = addListPreference(SIMULATE_COLOR_SPACE);
521        mUSBAudio = findAndInitSwitchPref(USB_AUDIO_KEY);
522        mForceResizable = findAndInitSwitchPref(FORCE_RESIZABLE_KEY);
523
524        mImmediatelyDestroyActivities = (SwitchPreference) findPreference(
525                IMMEDIATELY_DESTROY_ACTIVITIES_KEY);
526        mAllPrefs.add(mImmediatelyDestroyActivities);
527        mResetSwitchPrefs.add(mImmediatelyDestroyActivities);
528
529        mAppProcessLimit = addListPreference(APP_PROCESS_LIMIT_KEY);
530
531        mShowAllANRs = (SwitchPreference) findPreference(
532                SHOW_ALL_ANRS_KEY);
533        mAllPrefs.add(mShowAllANRs);
534        mResetSwitchPrefs.add(mShowAllANRs);
535
536        Preference hdcpChecking = findPreference(HDCP_CHECKING_KEY);
537        if (hdcpChecking != null) {
538            mAllPrefs.add(hdcpChecking);
539            removePreferenceForProduction(hdcpChecking);
540        }
541
542        Preference convertFbePreference = findPreference(KEY_CONVERT_FBE);
543
544        try {
545            IBinder service = ServiceManager.getService("mount");
546            IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
547            if (!storageManager.isConvertibleToFBE()) {
548                removePreference(KEY_CONVERT_FBE);
549            } else if ("file".equals(SystemProperties.get("ro.crypto.type", "none"))) {
550                convertFbePreference.setEnabled(false);
551                convertFbePreference.setSummary(getResources()
552                        .getString(R.string.convert_to_file_encryption_done));
553            }
554        } catch (RemoteException e) {
555            removePreference(KEY_CONVERT_FBE);
556        }
557
558        mOtaDisableAutomaticUpdate = findAndInitSwitchPref(OTA_DISABLE_AUTOMATIC_UPDATE_KEY);
559
560        mColorModePreference = (ColorModePreference) findPreference(KEY_COLOR_MODE);
561        mColorModePreference.updateCurrentAndSupported();
562        if (mColorModePreference.getColorModeCount() < 2) {
563            removePreference(KEY_COLOR_MODE);
564            mColorModePreference = null;
565        }
566
567        mColorTemperaturePreference = (SwitchPreference) findPreference(COLOR_TEMPERATURE_KEY);
568        if (getResources().getBoolean(R.bool.config_enableColorTemperature)) {
569            mAllPrefs.add(mColorTemperaturePreference);
570            mResetSwitchPrefs.add(mColorTemperaturePreference);
571        } else {
572            removePreference(COLOR_TEMPERATURE_KEY);
573            mColorTemperaturePreference = null;
574        }
575
576        addDashboardCategoryPreferences();
577    }
578
579    @VisibleForTesting
580    void addDashboardCategoryPreferences() {
581        final PreferenceScreen screen = getPreferenceScreen();
582        final List<Preference> tilePrefs = mDashboardFeatureProvider.getPreferencesForCategory(
583                getActivity(), getPrefContext(), getMetricsCategory(),
584                CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
585        if (tilePrefs != null) {
586            for (Preference preference : tilePrefs) {
587                screen.addPreference(preference);
588            }
589        }
590    }
591
592    private ListPreference addListPreference(String prefKey) {
593        ListPreference pref = (ListPreference) findPreference(prefKey);
594        mAllPrefs.add(pref);
595        pref.setOnPreferenceChangeListener(this);
596        return pref;
597    }
598
599    private void disableForUser(Preference pref) {
600        if (pref != null) {
601            pref.setEnabled(false);
602            mDisabledPrefs.add(pref);
603        }
604    }
605
606    private SwitchPreference findAndInitSwitchPref(String key) {
607        SwitchPreference pref = (SwitchPreference) findPreference(key);
608        if (pref == null) {
609            throw new IllegalArgumentException("Cannot find preference with key = " + key);
610        }
611        mAllPrefs.add(pref);
612        mResetSwitchPrefs.add(pref);
613        return pref;
614    }
615
616    @Override
617    public void onActivityCreated(Bundle savedInstanceState) {
618        super.onActivityCreated(savedInstanceState);
619
620        final SettingsActivity activity = (SettingsActivity) getActivity();
621
622        mSwitchBar = activity.getSwitchBar();
623        if (mUnavailable) {
624            mSwitchBar.setEnabled(false);
625            return;
626        }
627
628        mSwitchBar.addOnSwitchChangeListener(this);
629    }
630
631    private boolean removePreferenceForProduction(Preference preference) {
632        if ("user".equals(Build.TYPE)) {
633            removePreference(preference);
634            return true;
635        }
636        return false;
637    }
638
639    private void removePreference(Preference preference) {
640        getPreferenceScreen().removePreference(preference);
641        mAllPrefs.remove(preference);
642        mResetSwitchPrefs.remove(preference);
643    }
644
645    private void setPrefsEnabledState(boolean enabled) {
646        for (int i = 0; i < mAllPrefs.size(); i++) {
647            Preference pref = mAllPrefs.get(i);
648            pref.setEnabled(enabled && !mDisabledPrefs.contains(pref));
649        }
650        mBugReportInPowerController.enablePreference(enabled);
651        mTelephonyMonitorController.enablePreference(enabled);
652        mWebViewAppPrefController.enablePreference(enabled);
653        updateAllOptions();
654    }
655
656    @Override
657    public void onResume() {
658        super.onResume();
659
660        if (mUnavailable) {
661            // Show error message
662            if (!isUiRestrictedByOnlyAdmin()) {
663                getEmptyTextView().setText(R.string.development_settings_not_available);
664            }
665            getPreferenceScreen().removeAll();
666            return;
667        }
668
669        // A DeviceAdmin has specified a maximum time until the device
670        // will lock...  in this case we can't allow the user to turn
671        // on "stay awake when plugged in" because that would defeat the
672        // restriction.
673        final EnforcedAdmin admin = RestrictedLockUtils.checkIfMaximumTimeToLockIsSet(
674                getActivity());
675        mKeepScreenOn.setDisabledByAdmin(admin);
676        if (admin == null) {
677            mDisabledPrefs.remove(mKeepScreenOn);
678        } else {
679            mDisabledPrefs.add(mKeepScreenOn);
680        }
681
682        final boolean lastEnabledState = mSettingsEnabler.getLastEnabledState();
683        mSwitchBar.setChecked(lastEnabledState);
684        setPrefsEnabledState(lastEnabledState);
685
686        if (mHaveDebugSettings && !lastEnabledState) {
687            // Overall debugging is disabled, but there are some debug
688            // settings that are enabled.  This is an invalid state.  Switch
689            // to debug settings being enabled, so the user knows there is
690            // stuff enabled and can turn it all off if they want.
691            mSettingsEnabler.enableDevelopmentSettings();
692            mSwitchBar.setChecked(lastEnabledState);
693            setPrefsEnabledState(lastEnabledState);
694        }
695        mSwitchBar.show();
696
697        if (mColorModePreference != null) {
698            mColorModePreference.startListening();
699            mColorModePreference.updateCurrentAndSupported();
700        }
701    }
702
703    @Override
704    public void onPause() {
705        super.onPause();
706        if (mColorModePreference != null) {
707            mColorModePreference.stopListening();
708        }
709    }
710
711    @Override
712    public View onCreateView(LayoutInflater inflater, ViewGroup container,
713            Bundle savedInstanceState) {
714        IntentFilter filter = new IntentFilter();
715        filter.addAction(UsbManager.ACTION_USB_STATE);
716        if (getActivity().registerReceiver(mUsbReceiver, filter) == null) {
717            updateUsbConfigurationValues();
718        }
719
720        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
721        if (adapter != null) {
722            adapter.getProfileProxy(getActivity(),
723                                    mBluetoothA2dpServiceListener,
724                                    BluetoothProfile.A2DP);
725        }
726        filter = new IntentFilter();
727        filter.addAction(BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED);
728        if (getActivity().registerReceiver(mBluetoothA2dpReceiver, filter) == null) {
729            updateBluetoothA2dpConfigurationValues();
730        }
731
732        return super.onCreateView(inflater, container, savedInstanceState);
733    }
734
735    @Override
736    public void onDestroyView() {
737        super.onDestroyView();
738
739        if (mUnavailable) {
740            return;
741        }
742        mSwitchBar.removeOnSwitchChangeListener(this);
743        mSwitchBar.hide();
744        getActivity().unregisterReceiver(mUsbReceiver);
745        getActivity().unregisterReceiver(mBluetoothA2dpReceiver);
746        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
747        if (adapter != null) {
748            adapter.closeProfileProxy(BluetoothProfile.A2DP, mBluetoothA2dp);
749            mBluetoothA2dp = null;
750        }
751    }
752
753    void updateSwitchPreference(SwitchPreference switchPreference, boolean value) {
754        switchPreference.setChecked(value);
755        mHaveDebugSettings |= value;
756    }
757
758    private void updateAllOptions() {
759        final Context context = getActivity();
760        final ContentResolver cr = context.getContentResolver();
761        mHaveDebugSettings = false;
762        updateSwitchPreference(mEnableAdb, Settings.Global.getInt(cr,
763                Settings.Global.ADB_ENABLED, 0) != 0);
764        if (mEnableTerminal != null) {
765            updateSwitchPreference(mEnableTerminal,
766                    context.getPackageManager().getApplicationEnabledSetting(TERMINAL_APP_PACKAGE)
767                            == PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
768        }
769        mHaveDebugSettings |= mBugReportInPowerController.updatePreference();
770        mHaveDebugSettings |= mTelephonyMonitorController.updatePreference();
771        updateSwitchPreference(mKeepScreenOn, Settings.Global.getInt(cr,
772                Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0) != 0);
773        updateSwitchPreference(mBtHciSnoopLog, Settings.Secure.getInt(cr,
774                Settings.Secure.BLUETOOTH_HCI_LOG, 0) != 0);
775        updateSwitchPreference(mDebugViewAttributes, Settings.Global.getInt(cr,
776                Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0);
777        updateSwitchPreference(mForceAllowOnExternal, Settings.Global.getInt(cr,
778                Settings.Global.FORCE_ALLOW_ON_EXTERNAL, 0) != 0);
779        updateHdcpValues();
780        updatePasswordSummary();
781        updateDebuggerOptions();
782        updateMockLocation();
783        updateStrictModeVisualOptions();
784        updatePointerLocationOptions();
785        updateShowTouchesOptions();
786        updateFlingerOptions();
787        updateHardwareUiOptions();
788        updateMsaaOptions();
789        updateTrackFrameTimeOptions();
790        updateShowNonRectClipOptions();
791        updateShowHwScreenUpdatesOptions();
792        updateShowHwLayersUpdatesOptions();
793        updateDebugHwOverdrawOptions();
794        updateDebugHwRendererOptions();
795        updateDebugLayoutOptions();
796        updateAnimationScaleOptions();
797        updateOverlayDisplayDevicesOptions();
798        updateImmediatelyDestroyActivitiesOptions();
799        updateAppProcessLimitOptions();
800        updateShowAllANRsOptions();
801        updateVerifyAppsOverUsbOptions();
802        updateOtaDisableAutomaticUpdateOptions();
803        updateBugreportOptions();
804        updateForceRtlOptions();
805        updateLogdSizeValues();
806        updateLogpersistValues();
807        updateWifiDisplayCertificationOptions();
808        updateWifiVerboseLoggingOptions();
809        updateWifiAggressiveHandoverOptions();
810        updateWifiAllowScansWithTrafficOptions();
811        updateMobileDataAlwaysOnOptions();
812        updateSimulateColorSpace();
813        updateUSBAudioOptions();
814        updateForceResizableOptions();
815        Preference webViewAppPref = findPreference(mWebViewAppPrefController.getPreferenceKey());
816        mWebViewAppPrefController.updateState(webViewAppPref);
817        updateWebViewMultiprocessOptions();
818        updateOemUnlockOptions();
819        if (mColorTemperaturePreference != null) {
820            updateColorTemperature();
821        }
822        updateBluetoothDisableAbsVolumeOptions();
823        updateBluetoothEnableInbandRingingOptions();
824        updateBluetoothA2dpConfigurationValues();
825    }
826
827    private void resetDangerousOptions() {
828        mDontPokeProperties = true;
829        for (int i = 0; i < mResetSwitchPrefs.size(); i++) {
830            SwitchPreference cb = mResetSwitchPrefs.get(i);
831            if (cb.isChecked()) {
832                cb.setChecked(false);
833                onPreferenceTreeClick(cb);
834            }
835        }
836        mBugReportInPowerController.resetPreference();
837        resetDebuggerOptions();
838        writeLogpersistOption(null, true);
839        writeLogdSizeOption(null);
840        writeAnimationScaleOption(0, mWindowAnimationScale, null);
841        writeAnimationScaleOption(1, mTransitionAnimationScale, null);
842        writeAnimationScaleOption(2, mAnimatorDurationScale, null);
843        // Only poke the color space setting if we control it.
844        if (usingDevelopmentColorSpace()) {
845            writeSimulateColorSpace(-1);
846        }
847        writeOverlayDisplayDevicesOptions(null);
848        writeAppProcessLimitOptions(null);
849        mHaveDebugSettings = false;
850        updateAllOptions();
851        mDontPokeProperties = false;
852        pokeSystemProperties();
853    }
854
855    private void updateWebViewMultiprocessOptions() {
856        try {
857            updateSwitchPreference(mWebViewMultiprocess,
858                                   mWebViewUpdateService.isMultiProcessEnabled());
859        } catch (RemoteException e) {
860        }
861    }
862
863    private void writeWebViewMultiprocessOptions() {
864        try {
865            mWebViewUpdateService.enableMultiProcess(mWebViewMultiprocess.isChecked());
866        } catch (RemoteException e) {
867        }
868    }
869
870    private void updateHdcpValues() {
871        ListPreference hdcpChecking = (ListPreference) findPreference(HDCP_CHECKING_KEY);
872        if (hdcpChecking != null) {
873            String currentValue = SystemProperties.get(HDCP_CHECKING_PROPERTY);
874            String[] values = getResources().getStringArray(R.array.hdcp_checking_values);
875            String[] summaries = getResources().getStringArray(R.array.hdcp_checking_summaries);
876            int index = 1; // Defaults to drm-only. Needs to match with R.array.hdcp_checking_values
877            for (int i = 0; i < values.length; i++) {
878                if (currentValue.equals(values[i])) {
879                    index = i;
880                    break;
881                }
882            }
883            hdcpChecking.setValue(values[index]);
884            hdcpChecking.setSummary(summaries[index]);
885            hdcpChecking.setOnPreferenceChangeListener(this);
886        }
887    }
888
889    private void updatePasswordSummary() {
890        try {
891            if (mBackupManager.hasBackupPassword()) {
892                mPassword.setSummary(R.string.local_backup_password_summary_change);
893            } else {
894                mPassword.setSummary(R.string.local_backup_password_summary_none);
895            }
896        } catch (RemoteException e) {
897            // Not much we can do here
898        }
899    }
900
901    private void writeBtHciSnoopLogOptions() {
902        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
903        adapter.configHciSnoopLog(mBtHciSnoopLog.isChecked());
904        Settings.Secure.putInt(getActivity().getContentResolver(),
905                Settings.Secure.BLUETOOTH_HCI_LOG,
906                mBtHciSnoopLog.isChecked() ? 1 : 0);
907    }
908
909    private void writeDebuggerOptions() {
910        try {
911            ActivityManager.getService().setDebugApp(
912                    mDebugApp, mWaitForDebugger.isChecked(), true);
913        } catch (RemoteException ex) {
914        }
915    }
916
917    private void writeMockLocation() {
918        AppOpsManager appOpsManager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
919
920        // Disable the app op of the previous mock location app if such.
921        List<PackageOps> packageOps = appOpsManager.getPackagesForOps(MOCK_LOCATION_APP_OPS);
922        if (packageOps != null) {
923            // Should be one but in case we are in a bad state due to use of command line tools.
924            for (PackageOps packageOp : packageOps) {
925                if (packageOp.getOps().get(0).getMode() != AppOpsManager.MODE_ERRORED) {
926                    String oldMockLocationApp = packageOp.getPackageName();
927                    try {
928                        ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(
929                                oldMockLocationApp, PackageManager.GET_DISABLED_COMPONENTS);
930                        appOpsManager.setMode(AppOpsManager.OP_MOCK_LOCATION, ai.uid,
931                                oldMockLocationApp, AppOpsManager.MODE_ERRORED);
932                    } catch (NameNotFoundException e) {
933                        /* ignore */
934                    }
935                }
936            }
937        }
938
939        // Enable the app op of the new mock location app if such.
940        if (!TextUtils.isEmpty(mMockLocationApp)) {
941            try {
942                ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(
943                        mMockLocationApp, PackageManager.GET_DISABLED_COMPONENTS);
944                appOpsManager.setMode(AppOpsManager.OP_MOCK_LOCATION, ai.uid,
945                        mMockLocationApp, AppOpsManager.MODE_ALLOWED);
946            } catch (NameNotFoundException e) {
947                /* ignore */
948            }
949        }
950    }
951
952    private static void resetDebuggerOptions() {
953        try {
954            ActivityManager.getService().setDebugApp(
955                    null, false, true);
956        } catch (RemoteException ex) {
957        }
958    }
959
960    private void updateDebuggerOptions() {
961        mDebugApp = Settings.Global.getString(
962                getActivity().getContentResolver(), Settings.Global.DEBUG_APP);
963        updateSwitchPreference(mWaitForDebugger, Settings.Global.getInt(
964                getActivity().getContentResolver(), Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0);
965        if (mDebugApp != null && mDebugApp.length() > 0) {
966            String label;
967            try {
968                ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(mDebugApp,
969                        PackageManager.GET_DISABLED_COMPONENTS);
970                CharSequence lab = getActivity().getPackageManager().getApplicationLabel(ai);
971                label = lab != null ? lab.toString() : mDebugApp;
972            } catch (PackageManager.NameNotFoundException e) {
973                label = mDebugApp;
974            }
975            mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_set, label));
976            mWaitForDebugger.setEnabled(true);
977            mHaveDebugSettings = true;
978        } else {
979            mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_not_set));
980            mWaitForDebugger.setEnabled(false);
981        }
982    }
983
984    private void updateMockLocation() {
985        AppOpsManager appOpsManager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
986
987        List<PackageOps> packageOps = appOpsManager.getPackagesForOps(MOCK_LOCATION_APP_OPS);
988        if (packageOps != null) {
989            for (PackageOps packageOp : packageOps) {
990                if (packageOp.getOps().get(0).getMode() == AppOpsManager.MODE_ALLOWED) {
991                    mMockLocationApp = packageOps.get(0).getPackageName();
992                    break;
993                }
994            }
995        }
996
997        if (!TextUtils.isEmpty(mMockLocationApp)) {
998            String label = mMockLocationApp;
999            try {
1000                ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(
1001                        mMockLocationApp, PackageManager.GET_DISABLED_COMPONENTS);
1002                CharSequence appLabel = getPackageManager().getApplicationLabel(ai);
1003                if (appLabel != null) {
1004                    label = appLabel.toString();
1005                }
1006            } catch (PackageManager.NameNotFoundException e) {
1007                /* ignore */
1008            }
1009
1010            mMockLocationAppPref.setSummary(getString(R.string.mock_location_app_set, label));
1011            mHaveDebugSettings = true;
1012        } else {
1013            mMockLocationAppPref.setSummary(getString(R.string.mock_location_app_not_set));
1014        }
1015    }
1016
1017    private void updateVerifyAppsOverUsbOptions() {
1018        updateSwitchPreference(mVerifyAppsOverUsb,
1019                Settings.Global.getInt(getActivity().getContentResolver(),
1020                        Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) != 0);
1021        mVerifyAppsOverUsb.setEnabled(enableVerifierSetting());
1022    }
1023
1024    private void writeVerifyAppsOverUsbOptions() {
1025        Settings.Global.putInt(getActivity().getContentResolver(),
1026                Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB,
1027                mVerifyAppsOverUsb.isChecked() ? 1 : 0);
1028    }
1029
1030    private void updateOtaDisableAutomaticUpdateOptions() {
1031        // We use the "disabled status" in code, but show the opposite text
1032        // "Automatic system updates" on screen. So a value 0 indicates the
1033        // automatic update is enabled.
1034        updateSwitchPreference(mOtaDisableAutomaticUpdate, Settings.Global.getInt(
1035                getActivity().getContentResolver(),
1036                Settings.Global.OTA_DISABLE_AUTOMATIC_UPDATE, 0) != 1);
1037    }
1038
1039    private void writeOtaDisableAutomaticUpdateOptions() {
1040        // We use the "disabled status" in code, but show the opposite text
1041        // "Automatic system updates" on screen. So a value 0 indicates the
1042        // automatic update is enabled.
1043        Settings.Global.putInt(getActivity().getContentResolver(),
1044                Settings.Global.OTA_DISABLE_AUTOMATIC_UPDATE,
1045                mOtaDisableAutomaticUpdate.isChecked() ? 0 : 1);
1046    }
1047
1048    private boolean enableVerifierSetting() {
1049        final ContentResolver cr = getActivity().getContentResolver();
1050        if (Settings.Global.getInt(cr, Settings.Global.ADB_ENABLED, 0) == 0) {
1051            return false;
1052        }
1053        if (Settings.Global.getInt(cr, Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 0) {
1054            return false;
1055        } else {
1056            final PackageManager pm = getActivity().getPackageManager();
1057            final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
1058            verification.setType(PACKAGE_MIME_TYPE);
1059            verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
1060            final List<ResolveInfo> receivers = pm.queryBroadcastReceivers(verification, 0);
1061            if (receivers.size() == 0) {
1062                return false;
1063            }
1064        }
1065        return true;
1066    }
1067
1068    private boolean showVerifierSetting() {
1069        return Settings.Global.getInt(getActivity().getContentResolver(),
1070                Settings.Global.PACKAGE_VERIFIER_SETTING_VISIBLE, 1) > 0;
1071    }
1072
1073    private static boolean showEnableOemUnlockPreference() {
1074        return !SystemProperties.get(PERSISTENT_DATA_BLOCK_PROP).equals("");
1075    }
1076
1077    private boolean enableOemUnlockPreference() {
1078        return !isBootloaderUnlocked() && OemUnlockUtils.isOemUnlockAllowed(mUm);
1079    }
1080
1081    private void updateOemUnlockOptions() {
1082        if (mEnableOemUnlock != null) {
1083            updateSwitchPreference(mEnableOemUnlock,
1084                    OemUnlockUtils.isOemUnlockEnabled(getActivity()));
1085            updateOemUnlockSettingDescription();
1086            // Showing mEnableOemUnlock preference as device has persistent data block.
1087            mEnableOemUnlock.setDisabledByAdmin(null);
1088            mEnableOemUnlock.setEnabled(enableOemUnlockPreference());
1089            if (mEnableOemUnlock.isEnabled()) {
1090                // Check restriction, disable mEnableOemUnlock and apply policy transparency.
1091                mEnableOemUnlock.checkRestrictionAndSetDisabled(UserManager.DISALLOW_FACTORY_RESET);
1092            }
1093            if (mEnableOemUnlock.isEnabled()) {
1094                // Check restriction, disable mEnableOemUnlock and apply policy transparency.
1095                mEnableOemUnlock.checkRestrictionAndSetDisabled(UserManager.DISALLOW_OEM_UNLOCK);
1096            }
1097        }
1098    }
1099
1100    private void updateBugreportOptions() {
1101        mBugReportController.enablePreference(true);
1102        mBugReportInPowerController.updateBugreportOptions();
1103    }
1104
1105    // Returns the current state of the system property that controls
1106    // strictmode flashes.  One of:
1107    //    0: not explicitly set one way or another
1108    //    1: on
1109    //    2: off
1110    private static int currentStrictModeActiveIndex() {
1111        if (TextUtils.isEmpty(SystemProperties.get(StrictMode.VISUAL_PROPERTY))) {
1112            return 0;
1113        }
1114        boolean enabled = SystemProperties.getBoolean(StrictMode.VISUAL_PROPERTY, false);
1115        return enabled ? 1 : 2;
1116    }
1117
1118    private void writeStrictModeVisualOptions() {
1119        try {
1120            mWindowManager.setStrictModeVisualIndicatorPreference(mStrictMode.isChecked()
1121                    ? "1" : "");
1122        } catch (RemoteException e) {
1123        }
1124    }
1125
1126    private void updateStrictModeVisualOptions() {
1127        updateSwitchPreference(mStrictMode, currentStrictModeActiveIndex() == 1);
1128    }
1129
1130    private void writePointerLocationOptions() {
1131        Settings.System.putInt(getActivity().getContentResolver(),
1132                Settings.System.POINTER_LOCATION, mPointerLocation.isChecked() ? 1 : 0);
1133    }
1134
1135    private void updatePointerLocationOptions() {
1136        updateSwitchPreference(mPointerLocation,
1137                Settings.System.getInt(getActivity().getContentResolver(),
1138                        Settings.System.POINTER_LOCATION, 0) != 0);
1139    }
1140
1141    private void writeShowTouchesOptions() {
1142        Settings.System.putInt(getActivity().getContentResolver(),
1143                Settings.System.SHOW_TOUCHES, mShowTouches.isChecked() ? 1 : 0);
1144    }
1145
1146    private void updateShowTouchesOptions() {
1147        updateSwitchPreference(mShowTouches,
1148                Settings.System.getInt(getActivity().getContentResolver(),
1149                        Settings.System.SHOW_TOUCHES, 0) != 0);
1150    }
1151
1152    private void updateFlingerOptions() {
1153        // magic communication with surface flinger.
1154        try {
1155            IBinder flinger = ServiceManager.getService("SurfaceFlinger");
1156            if (flinger != null) {
1157                Parcel data = Parcel.obtain();
1158                Parcel reply = Parcel.obtain();
1159                data.writeInterfaceToken("android.ui.ISurfaceComposer");
1160                flinger.transact(1010, data, reply, 0);
1161                @SuppressWarnings("unused")
1162                int showCpu = reply.readInt();
1163                @SuppressWarnings("unused")
1164                int enableGL = reply.readInt();
1165                int showUpdates = reply.readInt();
1166                updateSwitchPreference(mShowScreenUpdates, showUpdates != 0);
1167                @SuppressWarnings("unused")
1168                int showBackground = reply.readInt();
1169                int disableOverlays = reply.readInt();
1170                updateSwitchPreference(mDisableOverlays, disableOverlays != 0);
1171                reply.recycle();
1172                data.recycle();
1173            }
1174        } catch (RemoteException ex) {
1175        }
1176    }
1177
1178    private void writeShowUpdatesOption() {
1179        try {
1180            IBinder flinger = ServiceManager.getService("SurfaceFlinger");
1181            if (flinger != null) {
1182                Parcel data = Parcel.obtain();
1183                data.writeInterfaceToken("android.ui.ISurfaceComposer");
1184                final int showUpdates = mShowScreenUpdates.isChecked() ? 1 : 0;
1185                data.writeInt(showUpdates);
1186                flinger.transact(1002, data, null, 0);
1187                data.recycle();
1188
1189                updateFlingerOptions();
1190            }
1191        } catch (RemoteException ex) {
1192        }
1193    }
1194
1195    private void writeDisableOverlaysOption() {
1196        try {
1197            IBinder flinger = ServiceManager.getService("SurfaceFlinger");
1198            if (flinger != null) {
1199                Parcel data = Parcel.obtain();
1200                data.writeInterfaceToken("android.ui.ISurfaceComposer");
1201                final int disableOverlays = mDisableOverlays.isChecked() ? 1 : 0;
1202                data.writeInt(disableOverlays);
1203                flinger.transact(1008, data, null, 0);
1204                data.recycle();
1205
1206                updateFlingerOptions();
1207            }
1208        } catch (RemoteException ex) {
1209        }
1210    }
1211
1212    private void updateHardwareUiOptions() {
1213        updateSwitchPreference(mForceHardwareUi,
1214                SystemProperties.getBoolean(HARDWARE_UI_PROPERTY, false));
1215    }
1216
1217    private void writeHardwareUiOptions() {
1218        SystemProperties.set(HARDWARE_UI_PROPERTY, mForceHardwareUi.isChecked() ? "true" : "false");
1219        pokeSystemProperties();
1220    }
1221
1222    private void updateMsaaOptions() {
1223        updateSwitchPreference(mForceMsaa, SystemProperties.getBoolean(MSAA_PROPERTY, false));
1224    }
1225
1226    private void writeMsaaOptions() {
1227        SystemProperties.set(MSAA_PROPERTY, mForceMsaa.isChecked() ? "true" : "false");
1228        pokeSystemProperties();
1229    }
1230
1231    private void updateTrackFrameTimeOptions() {
1232        String value = SystemProperties.get(ThreadedRenderer.PROFILE_PROPERTY);
1233        if (value == null) {
1234            value = "";
1235        }
1236
1237        CharSequence[] values = mTrackFrameTime.getEntryValues();
1238        for (int i = 0; i < values.length; i++) {
1239            if (value.contentEquals(values[i])) {
1240                mTrackFrameTime.setValueIndex(i);
1241                mTrackFrameTime.setSummary(mTrackFrameTime.getEntries()[i]);
1242                return;
1243            }
1244        }
1245        mTrackFrameTime.setValueIndex(0);
1246        mTrackFrameTime.setSummary(mTrackFrameTime.getEntries()[0]);
1247    }
1248
1249    private void writeTrackFrameTimeOptions(Object newValue) {
1250        SystemProperties.set(ThreadedRenderer.PROFILE_PROPERTY,
1251                newValue == null ? "" : newValue.toString());
1252        pokeSystemProperties();
1253        updateTrackFrameTimeOptions();
1254    }
1255
1256    private void updateShowNonRectClipOptions() {
1257        String value = SystemProperties.get(
1258                ThreadedRenderer.DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY);
1259        if (value == null) {
1260            value = "hide";
1261        }
1262
1263        CharSequence[] values = mShowNonRectClip.getEntryValues();
1264        for (int i = 0; i < values.length; i++) {
1265            if (value.contentEquals(values[i])) {
1266                mShowNonRectClip.setValueIndex(i);
1267                mShowNonRectClip.setSummary(mShowNonRectClip.getEntries()[i]);
1268                return;
1269            }
1270        }
1271        mShowNonRectClip.setValueIndex(0);
1272        mShowNonRectClip.setSummary(mShowNonRectClip.getEntries()[0]);
1273    }
1274
1275    private void writeShowNonRectClipOptions(Object newValue) {
1276        SystemProperties.set(ThreadedRenderer.DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY,
1277                newValue == null ? "" : newValue.toString());
1278        pokeSystemProperties();
1279        updateShowNonRectClipOptions();
1280    }
1281
1282    private void updateShowHwScreenUpdatesOptions() {
1283        updateSwitchPreference(mShowHwScreenUpdates,
1284                SystemProperties.getBoolean(ThreadedRenderer.DEBUG_DIRTY_REGIONS_PROPERTY, false));
1285    }
1286
1287    private void writeShowHwScreenUpdatesOptions() {
1288        SystemProperties.set(ThreadedRenderer.DEBUG_DIRTY_REGIONS_PROPERTY,
1289                mShowHwScreenUpdates.isChecked() ? "true" : null);
1290        pokeSystemProperties();
1291    }
1292
1293    private void updateShowHwLayersUpdatesOptions() {
1294        updateSwitchPreference(mShowHwLayersUpdates, SystemProperties.getBoolean(
1295                ThreadedRenderer.DEBUG_SHOW_LAYERS_UPDATES_PROPERTY, false));
1296    }
1297
1298    private void writeShowHwLayersUpdatesOptions() {
1299        SystemProperties.set(ThreadedRenderer.DEBUG_SHOW_LAYERS_UPDATES_PROPERTY,
1300                mShowHwLayersUpdates.isChecked() ? "true" : null);
1301        pokeSystemProperties();
1302    }
1303
1304    private void updateDebugHwOverdrawOptions() {
1305        String value = SystemProperties.get(ThreadedRenderer.DEBUG_OVERDRAW_PROPERTY);
1306        if (value == null) {
1307            value = "";
1308        }
1309
1310        CharSequence[] values = mDebugHwOverdraw.getEntryValues();
1311        for (int i = 0; i < values.length; i++) {
1312            if (value.contentEquals(values[i])) {
1313                mDebugHwOverdraw.setValueIndex(i);
1314                mDebugHwOverdraw.setSummary(mDebugHwOverdraw.getEntries()[i]);
1315                return;
1316            }
1317        }
1318        mDebugHwOverdraw.setValueIndex(0);
1319        mDebugHwOverdraw.setSummary(mDebugHwOverdraw.getEntries()[0]);
1320    }
1321
1322    private void writeDebugHwOverdrawOptions(Object newValue) {
1323        SystemProperties.set(ThreadedRenderer.DEBUG_OVERDRAW_PROPERTY,
1324                newValue == null ? "" : newValue.toString());
1325        pokeSystemProperties();
1326        updateDebugHwOverdrawOptions();
1327    }
1328
1329    private void updateDebugHwRendererOptions() {
1330        String value = SystemProperties.get(ThreadedRenderer.DEBUG_RENDERER_PROPERTY);
1331        if (value == null) {
1332            value = "";
1333        }
1334
1335        CharSequence[] values = mDebugHwRenderer.getEntryValues();
1336        for (int i = 0; i < values.length; i++) {
1337            if (value.contentEquals(values[i])) {
1338                mDebugHwRenderer.setValueIndex(i);
1339                mDebugHwRenderer.setSummary(mDebugHwRenderer.getEntries()[i]);
1340                return;
1341            }
1342        }
1343        mDebugHwRenderer.setValueIndex(0);
1344        mDebugHwRenderer.setSummary(mDebugHwRenderer.getEntries()[0]);
1345    }
1346
1347    private void writeDebugHwRendererOptions(Object newValue) {
1348        SystemProperties.set(ThreadedRenderer.DEBUG_RENDERER_PROPERTY,
1349                newValue == null ? "" : newValue.toString());
1350        pokeSystemProperties();
1351        updateDebugHwRendererOptions();
1352    }
1353
1354    private void updateDebugLayoutOptions() {
1355        updateSwitchPreference(mDebugLayout,
1356                SystemProperties.getBoolean(View.DEBUG_LAYOUT_PROPERTY, false));
1357    }
1358
1359    private void writeDebugLayoutOptions() {
1360        SystemProperties.set(View.DEBUG_LAYOUT_PROPERTY,
1361                mDebugLayout.isChecked() ? "true" : "false");
1362        pokeSystemProperties();
1363    }
1364
1365    private void updateSimulateColorSpace() {
1366        final ContentResolver cr = getContentResolver();
1367        final boolean enabled = Settings.Secure.getInt(
1368                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0) != 0;
1369        if (enabled) {
1370            final String mode = Integer.toString(Settings.Secure.getInt(
1371                    cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER,
1372                    AccessibilityManager.DALTONIZER_DISABLED));
1373            mSimulateColorSpace.setValue(mode);
1374            final int index = mSimulateColorSpace.findIndexOfValue(mode);
1375            if (index < 0) {
1376                // We're using a mode controlled by accessibility preferences.
1377                mSimulateColorSpace.setSummary(getString(R.string.daltonizer_type_overridden,
1378                        getString(R.string.accessibility_display_daltonizer_preference_title)));
1379            } else {
1380                mSimulateColorSpace.setSummary("%s");
1381            }
1382        } else {
1383            mSimulateColorSpace.setValue(
1384                    Integer.toString(AccessibilityManager.DALTONIZER_DISABLED));
1385        }
1386    }
1387
1388    /**
1389     * @return <code>true</code> if the color space preference is currently
1390     * controlled by development settings
1391     */
1392    private boolean usingDevelopmentColorSpace() {
1393        final ContentResolver cr = getContentResolver();
1394        final boolean enabled = Settings.Secure.getInt(
1395                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0) != 0;
1396        if (enabled) {
1397            final String mode = Integer.toString(Settings.Secure.getInt(
1398                    cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER,
1399                    AccessibilityManager.DALTONIZER_DISABLED));
1400            final int index = mSimulateColorSpace.findIndexOfValue(mode);
1401            if (index >= 0) {
1402                // We're using a mode controlled by developer preferences.
1403                return true;
1404            }
1405        }
1406        return false;
1407    }
1408
1409    private void writeSimulateColorSpace(Object value) {
1410        final ContentResolver cr = getContentResolver();
1411        final int newMode = Integer.parseInt(value.toString());
1412        if (newMode < 0) {
1413            Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0);
1414        } else {
1415            Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 1);
1416            Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, newMode);
1417        }
1418    }
1419
1420    private void updateColorTemperature() {
1421        updateSwitchPreference(mColorTemperaturePreference,
1422                SystemProperties.getBoolean(COLOR_TEMPERATURE_PROPERTY, false));
1423    }
1424
1425    private void writeColorTemperature() {
1426        SystemProperties.set(COLOR_TEMPERATURE_PROPERTY,
1427                mColorTemperaturePreference.isChecked() ? "1" : "0");
1428        pokeSystemProperties();
1429        Toast.makeText(getActivity(), R.string.color_temperature_toast, Toast.LENGTH_LONG).show();
1430    }
1431
1432    private void updateUSBAudioOptions() {
1433        updateSwitchPreference(mUSBAudio, Settings.Secure.getInt(getContentResolver(),
1434                Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED, 0) != 0);
1435    }
1436
1437    private void writeUSBAudioOptions() {
1438        Settings.Secure.putInt(getContentResolver(),
1439                Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED,
1440                mUSBAudio.isChecked() ? 1 : 0);
1441    }
1442
1443    private void updateForceResizableOptions() {
1444        updateSwitchPreference(mForceResizable, Settings.Global.getInt(getContentResolver(),
1445                Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0);
1446    }
1447
1448    private void writeForceResizableOptions() {
1449        Settings.Global.putInt(getContentResolver(),
1450                Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES,
1451                mForceResizable.isChecked() ? 1 : 0);
1452    }
1453
1454    private void updateForceRtlOptions() {
1455        updateSwitchPreference(mForceRtlLayout,
1456                Settings.Global.getInt(getActivity().getContentResolver(),
1457                        Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0);
1458    }
1459
1460    private void writeForceRtlOptions() {
1461        boolean value = mForceRtlLayout.isChecked();
1462        Settings.Global.putInt(getActivity().getContentResolver(),
1463                Settings.Global.DEVELOPMENT_FORCE_RTL, value ? 1 : 0);
1464        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, value ? "1" : "0");
1465        LocalePicker.updateLocales(getActivity().getResources().getConfiguration().getLocales());
1466    }
1467
1468    private void updateWifiDisplayCertificationOptions() {
1469        updateSwitchPreference(mWifiDisplayCertification, Settings.Global.getInt(
1470                getActivity().getContentResolver(),
1471                Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON, 0) != 0);
1472    }
1473
1474    private void writeWifiDisplayCertificationOptions() {
1475        Settings.Global.putInt(getActivity().getContentResolver(),
1476                Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON,
1477                mWifiDisplayCertification.isChecked() ? 1 : 0);
1478    }
1479
1480    private void updateWifiVerboseLoggingOptions() {
1481        boolean enabled = mWifiManager.getVerboseLoggingLevel() > 0;
1482        updateSwitchPreference(mWifiVerboseLogging, enabled);
1483    }
1484
1485    private void writeWifiVerboseLoggingOptions() {
1486        mWifiManager.enableVerboseLogging(mWifiVerboseLogging.isChecked() ? 1 : 0);
1487    }
1488
1489    private void updateWifiAggressiveHandoverOptions() {
1490        boolean enabled = mWifiManager.getAggressiveHandover() > 0;
1491        updateSwitchPreference(mWifiAggressiveHandover, enabled);
1492    }
1493
1494    private void writeWifiAggressiveHandoverOptions() {
1495        mWifiManager.enableAggressiveHandover(mWifiAggressiveHandover.isChecked() ? 1 : 0);
1496    }
1497
1498    private void updateWifiAllowScansWithTrafficOptions() {
1499        boolean enabled = mWifiManager.getAllowScansWithTraffic() > 0;
1500        updateSwitchPreference(mWifiAllowScansWithTraffic, enabled);
1501    }
1502
1503    private void writeWifiAllowScansWithTrafficOptions() {
1504        mWifiManager.setAllowScansWithTraffic(mWifiAllowScansWithTraffic.isChecked() ? 1 : 0);
1505    }
1506
1507    private void updateBluetoothDisableAbsVolumeOptions() {
1508        updateSwitchPreference(mBluetoothDisableAbsVolume,
1509                SystemProperties.getBoolean(BLUETOOTH_DISABLE_ABSOLUTE_VOLUME_PROPERTY, false));
1510    }
1511
1512    private void writeBluetoothDisableAbsVolumeOptions() {
1513        SystemProperties.set(BLUETOOTH_DISABLE_ABSOLUTE_VOLUME_PROPERTY,
1514                mBluetoothDisableAbsVolume.isChecked() ? "true" : "false");
1515    }
1516
1517    private void updateBluetoothEnableInbandRingingOptions() {
1518        if (mBluetoothEnableInbandRinging != null) {
1519            updateSwitchPreference(mBluetoothEnableInbandRinging,
1520                SystemProperties.getBoolean(BLUETOOTH_ENABLE_INBAND_RINGING_PROPERTY, false));
1521        }
1522    }
1523
1524    private void writeBluetoothEnableInbandRingingOptions() {
1525        if (mBluetoothEnableInbandRinging != null) {
1526            SystemProperties.set(BLUETOOTH_ENABLE_INBAND_RINGING_PROPERTY,
1527                mBluetoothEnableInbandRinging.isChecked() ? "true" : "false");
1528        }
1529    }
1530
1531    private void updateMobileDataAlwaysOnOptions() {
1532        updateSwitchPreference(mMobileDataAlwaysOn, Settings.Global.getInt(
1533                getActivity().getContentResolver(),
1534                Settings.Global.MOBILE_DATA_ALWAYS_ON, 1) != 0);
1535    }
1536
1537    private void writeMobileDataAlwaysOnOptions() {
1538        Settings.Global.putInt(getActivity().getContentResolver(),
1539                Settings.Global.MOBILE_DATA_ALWAYS_ON,
1540                mMobileDataAlwaysOn.isChecked() ? 1 : 0);
1541    }
1542
1543    private String defaultLogdSizeValue() {
1544        String defaultValue = SystemProperties.get(SELECT_LOGD_DEFAULT_SIZE_PROPERTY);
1545        if ((defaultValue == null) || (defaultValue.length() == 0)) {
1546            if (SystemProperties.get("ro.config.low_ram").equals("true")) {
1547                defaultValue = SELECT_LOGD_SVELTE_DEFAULT_SIZE_VALUE;
1548            } else {
1549                defaultValue = SELECT_LOGD_DEFAULT_SIZE_VALUE;
1550            }
1551        }
1552        return defaultValue;
1553    }
1554
1555    private void updateLogdSizeValues() {
1556        if (mLogdSize != null) {
1557            String currentTag = SystemProperties.get(SELECT_LOGD_TAG_PROPERTY);
1558            String currentValue = SystemProperties.get(SELECT_LOGD_SIZE_PROPERTY);
1559            if ((currentTag != null) && currentTag.startsWith(SELECT_LOGD_TAG_SILENCE)) {
1560                currentValue = SELECT_LOGD_OFF_SIZE_MARKER_VALUE;
1561            }
1562            if (mLogpersist != null) {
1563                String currentLogpersistEnable
1564                        = SystemProperties.get(ACTUAL_LOGPERSIST_PROPERTY_ENABLE);
1565                if ((currentLogpersistEnable == null)
1566                        || !currentLogpersistEnable.equals("true")
1567                        || currentValue.equals(SELECT_LOGD_OFF_SIZE_MARKER_VALUE)) {
1568                    writeLogpersistOption(null, true);
1569                    mLogpersist.setEnabled(false);
1570                } else if (mSettingsEnabler.getLastEnabledState()) {
1571                    mLogpersist.setEnabled(true);
1572                }
1573            }
1574            if ((currentValue == null) || (currentValue.length() == 0)) {
1575                currentValue = defaultLogdSizeValue();
1576            }
1577            String[] values = getResources().getStringArray(R.array.select_logd_size_values);
1578            String[] titles = getResources().getStringArray(R.array.select_logd_size_titles);
1579            int index = 2; // punt to second entry if not found
1580            if (SystemProperties.get("ro.config.low_ram").equals("true")) {
1581                mLogdSize.setEntries(R.array.select_logd_size_lowram_titles);
1582                titles = getResources().getStringArray(R.array.select_logd_size_lowram_titles);
1583                index = 1;
1584            }
1585            String[] summaries = getResources().getStringArray(R.array.select_logd_size_summaries);
1586            for (int i = 0; i < titles.length; i++) {
1587                if (currentValue.equals(values[i])
1588                        || currentValue.equals(titles[i])) {
1589                    index = i;
1590                    break;
1591                }
1592            }
1593            mLogdSize.setValue(values[index]);
1594            mLogdSize.setSummary(summaries[index]);
1595            mLogdSize.setOnPreferenceChangeListener(this);
1596        }
1597    }
1598
1599    private void writeLogdSizeOption(Object newValue) {
1600        boolean disable = (newValue != null) &&
1601                (newValue.toString().equals(SELECT_LOGD_OFF_SIZE_MARKER_VALUE));
1602        String currentTag = SystemProperties.get(SELECT_LOGD_TAG_PROPERTY);
1603        if (currentTag == null) {
1604            currentTag = "";
1605        }
1606        // filter clean and unstack all references to our setting
1607        String newTag = currentTag.replaceAll(
1608                ",+" + SELECT_LOGD_TAG_SILENCE, "").replaceFirst(
1609                "^" + SELECT_LOGD_TAG_SILENCE + ",*", "").replaceAll(
1610                ",+", ",").replaceFirst(
1611                ",+$", "");
1612        if (disable) {
1613            newValue = SELECT_LOGD_MINIMUM_SIZE_VALUE;
1614            // Make sure snet_event_log get through first, but do not override
1615            String snetValue = SystemProperties.get(SELECT_LOGD_SNET_TAG_PROPERTY);
1616            if ((snetValue == null) || (snetValue.length() == 0)) {
1617                snetValue = SystemProperties.get(SELECT_LOGD_RUNTIME_SNET_TAG_PROPERTY);
1618                if ((snetValue == null) || (snetValue.length() == 0)) {
1619                    SystemProperties.set(SELECT_LOGD_SNET_TAG_PROPERTY, "I");
1620                }
1621            }
1622            // Silence all log sources, security logs notwithstanding
1623            if (newTag.length() != 0) {
1624                newTag = "," + newTag;
1625            }
1626            // Stack settings, stack to help preserve original value
1627            newTag = SELECT_LOGD_TAG_SILENCE + newTag;
1628        }
1629        if (!newTag.equals(currentTag)) {
1630            SystemProperties.set(SELECT_LOGD_TAG_PROPERTY, newTag);
1631        }
1632        String defaultValue = defaultLogdSizeValue();
1633        final String size = ((newValue != null) && (newValue.toString().length() != 0)) ?
1634                newValue.toString() : defaultValue;
1635        SystemProperties.set(SELECT_LOGD_SIZE_PROPERTY, defaultValue.equals(size) ? "" : size);
1636        SystemProperties.set("ctl.start", "logd-reinit");
1637        pokeSystemProperties();
1638        updateLogdSizeValues();
1639    }
1640
1641    private void updateLogpersistValues() {
1642        if (mLogpersist == null) {
1643            return;
1644        }
1645        String currentValue = SystemProperties.get(ACTUAL_LOGPERSIST_PROPERTY);
1646        if (currentValue == null) {
1647            currentValue = "";
1648        }
1649        String currentBuffers = SystemProperties.get(ACTUAL_LOGPERSIST_PROPERTY_BUFFER);
1650        if ((currentBuffers == null) || (currentBuffers.length() == 0)) {
1651            currentBuffers = "all";
1652        }
1653        int index = 0;
1654        if (currentValue.equals(SELECT_LOGPERSIST_PROPERTY_SERVICE)) {
1655            index = 1;
1656            if (currentBuffers.equals("kernel")) {
1657                index = 3;
1658            } else if (!currentBuffers.equals("all") &&
1659                    !currentBuffers.contains("radio") &&
1660                    currentBuffers.contains("security") &&
1661                    currentBuffers.contains("kernel")) {
1662                index = 2;
1663                if (!currentBuffers.contains("default")) {
1664                    String[] contains = {"main", "events", "system", "crash"};
1665                    for (int i = 0; i < contains.length; i++) {
1666                        if (!currentBuffers.contains(contains[i])) {
1667                            index = 1;
1668                            break;
1669                        }
1670                    }
1671                }
1672            }
1673        }
1674        mLogpersist.setValue(
1675                getResources().getStringArray(R.array.select_logpersist_values)[index]);
1676        mLogpersist.setSummary(
1677                getResources().getStringArray(R.array.select_logpersist_summaries)[index]);
1678        mLogpersist.setOnPreferenceChangeListener(this);
1679        if (index != 0) {
1680            mLogpersistCleared = false;
1681        } else if (!mLogpersistCleared) {
1682            // would File.delete() directly but need to switch uid/gid to access
1683            SystemProperties.set(ACTUAL_LOGPERSIST_PROPERTY, SELECT_LOGPERSIST_PROPERTY_CLEAR);
1684            pokeSystemProperties();
1685            mLogpersistCleared = true;
1686        }
1687    }
1688
1689    private void setLogpersistOff(boolean update) {
1690        SystemProperties.set(SELECT_LOGPERSIST_PROPERTY_BUFFER, "");
1691        // deal with trampoline of empty properties
1692        SystemProperties.set(ACTUAL_LOGPERSIST_PROPERTY_BUFFER, "");
1693        SystemProperties.set(SELECT_LOGPERSIST_PROPERTY, "");
1694        SystemProperties.set(ACTUAL_LOGPERSIST_PROPERTY,
1695                update ? "" : SELECT_LOGPERSIST_PROPERTY_STOP);
1696        pokeSystemProperties();
1697        if (update) {
1698            updateLogpersistValues();
1699        } else {
1700            for (int i = 0; i < 3; i++) {
1701                String currentValue = SystemProperties.get(ACTUAL_LOGPERSIST_PROPERTY);
1702                if ((currentValue == null) || currentValue.equals("")) {
1703                    break;
1704                }
1705                try {
1706                    Thread.sleep(100);
1707                } catch (InterruptedException e) {
1708                }
1709            }
1710        }
1711    }
1712
1713    private void writeLogpersistOption(Object newValue, boolean skipWarning) {
1714        if (mLogpersist == null) {
1715            return;
1716        }
1717        String currentTag = SystemProperties.get(SELECT_LOGD_TAG_PROPERTY);
1718        if ((currentTag != null) && currentTag.startsWith(SELECT_LOGD_TAG_SILENCE)) {
1719            newValue = null;
1720            skipWarning = true;
1721        }
1722
1723        if ((newValue == null) || newValue.toString().equals("")) {
1724            if (skipWarning) {
1725                mLogpersistCleared = false;
1726            } else if (!mLogpersistCleared) {
1727                // if transitioning from on to off, pop up an are you sure?
1728                String currentValue = SystemProperties.get(ACTUAL_LOGPERSIST_PROPERTY);
1729                if ((currentValue != null) &&
1730                        currentValue.equals(SELECT_LOGPERSIST_PROPERTY_SERVICE)) {
1731                    if (mLogpersistClearDialog != null) dismissDialogs();
1732                    mLogpersistClearDialog = new AlertDialog.Builder(getActivity()).setMessage(
1733                            getActivity().getResources().getString(
1734                                    R.string.dev_logpersist_clear_warning_message))
1735                            .setTitle(R.string.dev_logpersist_clear_warning_title)
1736                            .setPositiveButton(android.R.string.yes, this)
1737                            .setNegativeButton(android.R.string.no, this)
1738                            .show();
1739                    mLogpersistClearDialog.setOnDismissListener(this);
1740                    return;
1741                }
1742            }
1743            setLogpersistOff(true);
1744            return;
1745        }
1746
1747        String currentBuffer = SystemProperties.get(ACTUAL_LOGPERSIST_PROPERTY_BUFFER);
1748        if ((currentBuffer != null) && !currentBuffer.equals(newValue.toString())) {
1749            setLogpersistOff(false);
1750        }
1751        SystemProperties.set(SELECT_LOGPERSIST_PROPERTY_BUFFER, newValue.toString());
1752        SystemProperties.set(SELECT_LOGPERSIST_PROPERTY, SELECT_LOGPERSIST_PROPERTY_SERVICE);
1753        pokeSystemProperties();
1754        for (int i = 0; i < 3; i++) {
1755            String currentValue = SystemProperties.get(ACTUAL_LOGPERSIST_PROPERTY);
1756            if ((currentValue != null)
1757                    && currentValue.equals(SELECT_LOGPERSIST_PROPERTY_SERVICE)) {
1758                break;
1759            }
1760            try {
1761                Thread.sleep(100);
1762            } catch (InterruptedException e) {
1763            }
1764        }
1765        updateLogpersistValues();
1766    }
1767
1768    private void updateUsbConfigurationValues() {
1769        if (mUsbConfiguration != null) {
1770            UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
1771
1772            String[] values = getResources().getStringArray(R.array.usb_configuration_values);
1773            String[] titles = getResources().getStringArray(R.array.usb_configuration_titles);
1774            int index = 0;
1775            for (int i = 0; i < titles.length; i++) {
1776                if (manager.isFunctionEnabled(values[i])) {
1777                    index = i;
1778                    break;
1779                }
1780            }
1781            mUsbConfiguration.setValue(values[index]);
1782            mUsbConfiguration.setSummary(titles[index]);
1783            mUsbConfiguration.setOnPreferenceChangeListener(this);
1784        }
1785    }
1786
1787    private void writeUsbConfigurationOption(Object newValue) {
1788        UsbManager manager = (UsbManager) getActivity().getSystemService(Context.USB_SERVICE);
1789        String function = newValue.toString();
1790        if (function.equals("none")) {
1791            manager.setCurrentFunction(function, false);
1792        } else {
1793            manager.setCurrentFunction(function, true);
1794        }
1795    }
1796
1797    private void initBluetoothConfigurationValues() {
1798        String[] values;
1799        String[] summaries;
1800        int index;
1801
1802        // Init the AVRCP Version - Default
1803        values = getResources().getStringArray(R.array.bluetooth_avrcp_version_values);
1804        summaries = getResources().getStringArray(R.array.bluetooth_avrcp_versions);
1805        String value = SystemProperties.get(BLUETOOTH_AVRCP_VERSION_PROPERTY, values[0]);
1806        index = mBluetoothSelectAvrcpVersion.findIndexOfValue(value);
1807        mBluetoothSelectAvrcpVersion.setValue(values[index]);
1808        mBluetoothSelectAvrcpVersion.setSummary(summaries[index]);
1809
1810        // Init the Codec Type - Default
1811        values = getResources().getStringArray(R.array.bluetooth_a2dp_codec_values);
1812        summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_summaries);
1813        index = 0;
1814        mBluetoothSelectA2dpCodec.setValue(values[index]);
1815        mBluetoothSelectA2dpCodec.setSummary(summaries[index]);
1816
1817        // Init the Sample Rate - Default
1818        values = getResources().getStringArray(R.array.bluetooth_a2dp_codec_sample_rate_values);
1819        summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_sample_rate_summaries);
1820        index = 0;
1821        mBluetoothSelectA2dpSampleRate.setValue(values[index]);
1822        mBluetoothSelectA2dpSampleRate.setSummary(summaries[index]);
1823
1824        // Init the Bits Per Sample - Default
1825        values = getResources().getStringArray(R.array.bluetooth_a2dp_codec_bits_per_sample_values);
1826        summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_bits_per_sample_summaries);
1827        index = 0;
1828        mBluetoothSelectA2dpBitsPerSample.setValue(values[index]);
1829        mBluetoothSelectA2dpBitsPerSample.setSummary(summaries[index]);
1830
1831        // Init the Channel Mode - Default
1832        values = getResources().getStringArray(R.array.bluetooth_a2dp_codec_channel_mode_values);
1833        summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_channel_mode_summaries);
1834        index = 0;
1835        mBluetoothSelectA2dpChannelMode.setValue(values[index]);
1836        mBluetoothSelectA2dpChannelMode.setSummary(summaries[index]);
1837
1838        // Init the LDAC Playback Quality - ABR
1839        values = getResources().getStringArray(R.array.bluetooth_a2dp_codec_ldac_playback_quality_values);
1840        summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_ldac_playback_quality_summaries);
1841        index = 3;
1842        mBluetoothSelectA2dpLdacPlaybackQuality.setValue(values[index]);
1843        mBluetoothSelectA2dpLdacPlaybackQuality.setSummary(summaries[index]);
1844    }
1845
1846    private void writeBluetoothAvrcpVersion(Object newValue) {
1847        SystemProperties.set(BLUETOOTH_AVRCP_VERSION_PROPERTY, newValue.toString());
1848        int index = mBluetoothSelectAvrcpVersion.findIndexOfValue(newValue.toString());
1849        if (index >= 0) {
1850            String[] titles = getResources().getStringArray(R.array.bluetooth_avrcp_versions);
1851            mBluetoothSelectAvrcpVersion.setSummary(titles[index]);
1852        }
1853    }
1854
1855    private void updateBluetoothA2dpConfigurationValues() {
1856        int index;
1857        String[] summaries;
1858        BluetoothCodecStatus codecStatus = null;
1859        BluetoothCodecConfig codecConfig = null;
1860        BluetoothCodecConfig[] codecsLocalCapabilities = null;
1861        BluetoothCodecConfig[] codecsSelectableCapabilities = null;
1862        String streaming;
1863        Resources resources = null;
1864
1865        synchronized (mBluetoothA2dpLock) {
1866            if (mBluetoothA2dp != null) {
1867                codecStatus = mBluetoothA2dp.getCodecStatus();
1868                if (codecStatus != null) {
1869                    codecConfig = codecStatus.getCodecConfig();
1870                    codecsLocalCapabilities = codecStatus.getCodecsLocalCapabilities();
1871                    codecsSelectableCapabilities = codecStatus.getCodecsSelectableCapabilities();
1872                }
1873            }
1874        }
1875        if (codecConfig == null) {
1876            return;
1877        }
1878
1879        try {
1880            resources = getResources();
1881        } catch (IllegalStateException e) {
1882            return;
1883        }
1884        if (resources == null) {
1885            return;
1886        }
1887
1888        // Update the Codec Type
1889        index = -1;
1890        switch (codecConfig.getCodecType()) {
1891        case BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC:
1892            index = 1;
1893            break;
1894        case BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC:
1895            index = 2;
1896            break;
1897        case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX:
1898            index = 3;
1899            break;
1900        case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD:
1901            index = 4;
1902            break;
1903        case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC:
1904            index = 5;
1905            break;
1906        case BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID:
1907        default:
1908            break;
1909        }
1910        if (index >= 0 && mBluetoothSelectA2dpCodec != null) {
1911            summaries = resources.getStringArray(R.array.bluetooth_a2dp_codec_summaries);
1912            streaming = resources.getString(R.string.bluetooth_select_a2dp_codec_streaming_label, summaries[index]);
1913            mBluetoothSelectA2dpCodec.setSummary(streaming);
1914        }
1915
1916        // Update the Sample Rate
1917        index = -1;
1918        switch (codecConfig.getSampleRate()) {
1919        case BluetoothCodecConfig.SAMPLE_RATE_44100:
1920            index = 1;
1921            break;
1922        case BluetoothCodecConfig.SAMPLE_RATE_48000:
1923            index = 2;
1924            break;
1925        case BluetoothCodecConfig.SAMPLE_RATE_88200:
1926            index = 3;
1927            break;
1928        case BluetoothCodecConfig.SAMPLE_RATE_96000:
1929            index = 4;
1930            break;
1931        case BluetoothCodecConfig.SAMPLE_RATE_176400:
1932        case BluetoothCodecConfig.SAMPLE_RATE_192000:
1933        case BluetoothCodecConfig.SAMPLE_RATE_NONE:
1934        default:
1935            break;
1936        }
1937        if (index >= 0 && mBluetoothSelectA2dpSampleRate != null) {
1938            summaries = resources.getStringArray(R.array.bluetooth_a2dp_codec_sample_rate_summaries);
1939            streaming = resources.getString(R.string.bluetooth_select_a2dp_codec_streaming_label, summaries[index]);
1940             mBluetoothSelectA2dpSampleRate.setSummary(streaming);
1941        }
1942
1943        // Update the Bits Per Sample
1944        index = -1;
1945        switch (codecConfig.getBitsPerSample()) {
1946        case BluetoothCodecConfig.BITS_PER_SAMPLE_16:
1947            index = 1;
1948            break;
1949        case BluetoothCodecConfig.BITS_PER_SAMPLE_24:
1950            index = 2;
1951            break;
1952        case BluetoothCodecConfig.BITS_PER_SAMPLE_32:
1953            index = 3;
1954            break;
1955        case BluetoothCodecConfig.BITS_PER_SAMPLE_NONE:
1956        default:
1957            break;
1958        }
1959        if (index >= 0 && mBluetoothSelectA2dpBitsPerSample != null) {
1960            summaries = resources.getStringArray(R.array.bluetooth_a2dp_codec_bits_per_sample_summaries);
1961            streaming = resources.getString(R.string.bluetooth_select_a2dp_codec_streaming_label, summaries[index]);
1962            mBluetoothSelectA2dpBitsPerSample.setSummary(streaming);
1963        }
1964
1965        // Update the Channel Mode
1966        index = -1;
1967        switch (codecConfig.getChannelMode()) {
1968        case BluetoothCodecConfig.CHANNEL_MODE_MONO:
1969            index = 1;
1970            break;
1971        case BluetoothCodecConfig.CHANNEL_MODE_STEREO:
1972            index = 2;
1973            break;
1974        case BluetoothCodecConfig.CHANNEL_MODE_NONE:
1975        default:
1976            break;
1977        }
1978        if (index >= 0 && mBluetoothSelectA2dpChannelMode != null) {
1979            summaries = resources.getStringArray(R.array.bluetooth_a2dp_codec_channel_mode_summaries);
1980            streaming = resources.getString(R.string.bluetooth_select_a2dp_codec_streaming_label, summaries[index]);
1981             mBluetoothSelectA2dpChannelMode.setSummary(streaming);
1982        }
1983
1984        // Update the LDAC Playback Quality
1985        // The actual values are 0, 1, 2 - those are extracted
1986        // as mod-10 remainders of a larger value.
1987        // The reason is because within BluetoothCodecConfig we cannot use
1988        // a codec-specific value of zero.
1989        index = (int)codecConfig.getCodecSpecific1();
1990        if (index > 0) {
1991            index %= 10;
1992        } else {
1993            index = -1;
1994        }
1995        switch (index) {
1996        case 0:
1997        case 1:
1998        case 2:
1999        case 3:
2000            break;
2001        default:
2002            index = -1;
2003            break;
2004        }
2005        if (index >= 0 && mBluetoothSelectA2dpLdacPlaybackQuality != null) {
2006            summaries = resources.getStringArray(R.array.bluetooth_a2dp_codec_ldac_playback_quality_summaries);
2007            streaming = resources.getString(R.string.bluetooth_select_a2dp_codec_streaming_label, summaries[index]);
2008            mBluetoothSelectA2dpLdacPlaybackQuality.setSummary(streaming);
2009        }
2010    }
2011
2012    private void writeBluetoothConfigurationOption(Preference preference,
2013                                                   Object newValue) {
2014        String[] summaries;
2015        int index;
2016        int codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID;
2017        int codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT;
2018        int sampleRateValue = BluetoothCodecConfig.SAMPLE_RATE_NONE;
2019        int bitsPerSampleValue = BluetoothCodecConfig.BITS_PER_SAMPLE_NONE;
2020        int channelModeValue = BluetoothCodecConfig.CHANNEL_MODE_NONE;
2021        long codecSpecific1Value = 0;
2022        long codecSpecific2Value = 0;
2023        long codecSpecific3Value = 0;
2024        long codecSpecific4Value = 0;
2025
2026        // Codec Type
2027        String codecType = mBluetoothSelectA2dpCodec.getValue();
2028        if (preference == mBluetoothSelectA2dpCodec) {
2029            codecType = newValue.toString();
2030            index = mBluetoothSelectA2dpCodec.findIndexOfValue(newValue.toString());
2031            if (index >= 0) {
2032                summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_summaries);
2033                mBluetoothSelectA2dpCodec.setSummary(summaries[index]);
2034            }
2035        }
2036        index = mBluetoothSelectA2dpCodec.findIndexOfValue(codecType);
2037        switch (index) {
2038        case 0:
2039            // Reset the priority of the current codec to default
2040            String oldValue = mBluetoothSelectA2dpCodec.getValue();
2041            switch (mBluetoothSelectA2dpCodec.findIndexOfValue(oldValue)) {
2042            case 0:
2043                break;      // No current codec
2044            case 1:
2045                codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC;
2046                break;
2047            case 2:
2048                codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC;
2049                break;
2050            case 3:
2051                codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX;
2052                break;
2053            case 4:
2054                codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD;
2055                break;
2056            case 5:
2057                codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC;
2058                break;
2059            default:
2060                break;
2061            }
2062            break;
2063        case 1:
2064            codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC;
2065            codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
2066            break;
2067        case 2:
2068            codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC;
2069            codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
2070            break;
2071        case 3:
2072            codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX;
2073            codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
2074            break;
2075        case 4:
2076            codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD;
2077            codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
2078            break;
2079        case 5:
2080            codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC;
2081            codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
2082            break;
2083        case 6:
2084        synchronized (mBluetoothA2dpLock) {
2085            if (mBluetoothA2dp != null) {
2086                mBluetoothA2dp.enableOptionalCodecs();
2087            }
2088        }
2089        return;
2090        case 7:
2091        synchronized (mBluetoothA2dpLock) {
2092            if (mBluetoothA2dp != null) {
2093                mBluetoothA2dp.disableOptionalCodecs();
2094            }
2095        }
2096        return;
2097        default:
2098            break;
2099        }
2100
2101        // Sample Rate
2102        String sampleRate = mBluetoothSelectA2dpSampleRate.getValue();
2103        if (preference == mBluetoothSelectA2dpSampleRate) {
2104            sampleRate = newValue.toString();
2105            index = mBluetoothSelectA2dpSampleRate.findIndexOfValue(newValue.toString());
2106            if (index >= 0) {
2107                summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_sample_rate_summaries);
2108                mBluetoothSelectA2dpSampleRate.setSummary(summaries[index]);
2109            }
2110        }
2111        index = mBluetoothSelectA2dpSampleRate.findIndexOfValue(sampleRate);
2112        switch (index) {
2113        case 0:
2114            // Reset to default
2115            break;
2116        case 1:
2117            sampleRateValue = BluetoothCodecConfig.SAMPLE_RATE_44100;
2118            break;
2119        case 2:
2120            sampleRateValue = BluetoothCodecConfig.SAMPLE_RATE_48000;
2121            break;
2122        case 3:
2123            sampleRateValue = BluetoothCodecConfig.SAMPLE_RATE_88200;
2124            break;
2125        case 4:
2126            sampleRateValue = BluetoothCodecConfig.SAMPLE_RATE_96000;
2127            break;
2128        default:
2129            break;
2130        }
2131
2132        // Bits Per Sample
2133        String bitsPerSample = mBluetoothSelectA2dpBitsPerSample.getValue();
2134        if (preference == mBluetoothSelectA2dpBitsPerSample) {
2135            bitsPerSample = newValue.toString();
2136            index = mBluetoothSelectA2dpBitsPerSample.findIndexOfValue(newValue.toString());
2137            if (index >= 0) {
2138                summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_bits_per_sample_summaries);
2139                mBluetoothSelectA2dpBitsPerSample.setSummary(summaries[index]);
2140            }
2141        }
2142        index = mBluetoothSelectA2dpBitsPerSample.findIndexOfValue(bitsPerSample);
2143        switch (index) {
2144        case 0:
2145            // Reset to default
2146            break;
2147        case 1:
2148            bitsPerSampleValue = BluetoothCodecConfig.BITS_PER_SAMPLE_16;
2149            break;
2150        case 2:
2151            bitsPerSampleValue = BluetoothCodecConfig.BITS_PER_SAMPLE_24;
2152            break;
2153        case 3:
2154            bitsPerSampleValue = BluetoothCodecConfig.BITS_PER_SAMPLE_32;
2155            break;
2156        default:
2157            break;
2158        }
2159
2160        // Channel Mode
2161        String channelMode = mBluetoothSelectA2dpChannelMode.getValue();
2162        if (preference == mBluetoothSelectA2dpChannelMode) {
2163            channelMode = newValue.toString();
2164            index = mBluetoothSelectA2dpChannelMode.findIndexOfValue(newValue.toString());
2165            if (index >= 0) {
2166                summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_channel_mode_summaries);
2167                mBluetoothSelectA2dpChannelMode.setSummary(summaries[index]);
2168            }
2169        }
2170        index = mBluetoothSelectA2dpChannelMode.findIndexOfValue(channelMode);
2171        switch (index) {
2172        case 0:
2173            // Reset to default
2174            break;
2175        case 1:
2176            channelModeValue = BluetoothCodecConfig.CHANNEL_MODE_MONO;
2177            break;
2178        case 2:
2179            channelModeValue = BluetoothCodecConfig.CHANNEL_MODE_STEREO;
2180            break;
2181        default:
2182            break;
2183        }
2184
2185        // LDAC Playback Quality
2186        String ldacPlaybackQuality = mBluetoothSelectA2dpLdacPlaybackQuality.getValue();
2187        if (preference == mBluetoothSelectA2dpLdacPlaybackQuality) {
2188            ldacPlaybackQuality = newValue.toString();
2189            index = mBluetoothSelectA2dpLdacPlaybackQuality.findIndexOfValue(newValue.toString());
2190            if (index >= 0) {
2191                summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_ldac_playback_quality_summaries);
2192                mBluetoothSelectA2dpLdacPlaybackQuality.setSummary(summaries[index]);
2193            }
2194        }
2195        index = mBluetoothSelectA2dpLdacPlaybackQuality.findIndexOfValue(ldacPlaybackQuality);
2196        switch (index) {
2197        case 0:
2198        case 1:
2199        case 2:
2200        case 3:
2201            codecSpecific1Value = 1000 + index;
2202            break;
2203        default:
2204            break;
2205        }
2206
2207        BluetoothCodecConfig codecConfig =
2208            new BluetoothCodecConfig(codecTypeValue, codecPriorityValue,
2209                                     sampleRateValue, bitsPerSampleValue,
2210                                     channelModeValue, codecSpecific1Value,
2211                                     codecSpecific2Value, codecSpecific3Value,
2212                                     codecSpecific4Value);
2213
2214        synchronized (mBluetoothA2dpLock) {
2215            if (mBluetoothA2dp != null) {
2216                mBluetoothA2dp.setCodecConfigPreference(codecConfig);
2217            }
2218        }
2219    }
2220
2221    private void writeImmediatelyDestroyActivitiesOptions() {
2222        try {
2223            ActivityManager.getService().setAlwaysFinish(
2224                    mImmediatelyDestroyActivities.isChecked());
2225        } catch (RemoteException ex) {
2226        }
2227    }
2228
2229    private void updateImmediatelyDestroyActivitiesOptions() {
2230        updateSwitchPreference(mImmediatelyDestroyActivities, Settings.Global.getInt(
2231                getActivity().getContentResolver(), Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0)
2232                != 0);
2233    }
2234
2235    private void updateAnimationScaleValue(int which, ListPreference pref) {
2236        try {
2237            float scale = mWindowManager.getAnimationScale(which);
2238            if (scale != 1) {
2239                mHaveDebugSettings = true;
2240            }
2241            CharSequence[] values = pref.getEntryValues();
2242            for (int i = 0; i < values.length; i++) {
2243                float val = Float.parseFloat(values[i].toString());
2244                if (scale <= val) {
2245                    pref.setValueIndex(i);
2246                    pref.setSummary(pref.getEntries()[i]);
2247                    return;
2248                }
2249            }
2250            pref.setValueIndex(values.length - 1);
2251            pref.setSummary(pref.getEntries()[0]);
2252        } catch (RemoteException e) {
2253        }
2254    }
2255
2256    private void updateAnimationScaleOptions() {
2257        updateAnimationScaleValue(0, mWindowAnimationScale);
2258        updateAnimationScaleValue(1, mTransitionAnimationScale);
2259        updateAnimationScaleValue(2, mAnimatorDurationScale);
2260    }
2261
2262    private void writeAnimationScaleOption(int which, ListPreference pref, Object newValue) {
2263        try {
2264            float scale = newValue != null ? Float.parseFloat(newValue.toString()) : 1;
2265            mWindowManager.setAnimationScale(which, scale);
2266            updateAnimationScaleValue(which, pref);
2267        } catch (RemoteException e) {
2268        }
2269    }
2270
2271    private void updateOverlayDisplayDevicesOptions() {
2272        String value = Settings.Global.getString(getActivity().getContentResolver(),
2273                Settings.Global.OVERLAY_DISPLAY_DEVICES);
2274        if (value == null) {
2275            value = "";
2276        }
2277
2278        CharSequence[] values = mOverlayDisplayDevices.getEntryValues();
2279        for (int i = 0; i < values.length; i++) {
2280            if (value.contentEquals(values[i])) {
2281                mOverlayDisplayDevices.setValueIndex(i);
2282                mOverlayDisplayDevices.setSummary(mOverlayDisplayDevices.getEntries()[i]);
2283                return;
2284            }
2285        }
2286        mOverlayDisplayDevices.setValueIndex(0);
2287        mOverlayDisplayDevices.setSummary(mOverlayDisplayDevices.getEntries()[0]);
2288    }
2289
2290    private void writeOverlayDisplayDevicesOptions(Object newValue) {
2291        Settings.Global.putString(getActivity().getContentResolver(),
2292                Settings.Global.OVERLAY_DISPLAY_DEVICES, (String) newValue);
2293        updateOverlayDisplayDevicesOptions();
2294    }
2295
2296    private void updateAppProcessLimitOptions() {
2297        try {
2298            int limit = ActivityManager.getService().getProcessLimit();
2299            CharSequence[] values = mAppProcessLimit.getEntryValues();
2300            for (int i = 0; i < values.length; i++) {
2301                int val = Integer.parseInt(values[i].toString());
2302                if (val >= limit) {
2303                    if (i != 0) {
2304                        mHaveDebugSettings = true;
2305                    }
2306                    mAppProcessLimit.setValueIndex(i);
2307                    mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[i]);
2308                    return;
2309                }
2310            }
2311            mAppProcessLimit.setValueIndex(0);
2312            mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[0]);
2313        } catch (RemoteException e) {
2314        }
2315    }
2316
2317    private void writeAppProcessLimitOptions(Object newValue) {
2318        try {
2319            int limit = newValue != null ? Integer.parseInt(newValue.toString()) : -1;
2320            ActivityManager.getService().setProcessLimit(limit);
2321            updateAppProcessLimitOptions();
2322        } catch (RemoteException e) {
2323        }
2324    }
2325
2326    private void writeShowAllANRsOptions() {
2327        Settings.Secure.putInt(getActivity().getContentResolver(),
2328                Settings.Secure.ANR_SHOW_BACKGROUND,
2329                mShowAllANRs.isChecked() ? 1 : 0);
2330    }
2331
2332    private void updateShowAllANRsOptions() {
2333        updateSwitchPreference(mShowAllANRs, Settings.Secure.getInt(
2334                getActivity().getContentResolver(), Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0);
2335    }
2336
2337    private void confirmEnableOemUnlock() {
2338        DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() {
2339            @Override
2340            public void onClick(DialogInterface dialog, int which) {
2341                if (which == DialogInterface.BUTTON_POSITIVE) {
2342                    OemUnlockUtils.setOemUnlockEnabled(getActivity(), true);
2343                }
2344            }
2345        };
2346
2347        DialogInterface.OnDismissListener onDismissListener =
2348                new DialogInterface.OnDismissListener() {
2349                    @Override
2350                    public void onDismiss(DialogInterface dialog) {
2351                        if (getActivity() == null) {
2352                            return;
2353                        }
2354                        updateAllOptions();
2355                    }
2356                };
2357
2358        new AlertDialog.Builder(getActivity())
2359                .setTitle(R.string.confirm_enable_oem_unlock_title)
2360                .setMessage(R.string.confirm_enable_oem_unlock_text)
2361                .setPositiveButton(R.string.enable_text, onClickListener)
2362                .setNegativeButton(android.R.string.cancel, null)
2363                .setOnDismissListener(onDismissListener)
2364                .create()
2365                .show();
2366    }
2367
2368    @Override
2369    public void onSwitchChanged(Switch switchView, boolean isChecked) {
2370        if (switchView != mSwitchBar.getSwitch()) {
2371            return;
2372        }
2373        final boolean lastEnabledState = mSettingsEnabler.getLastEnabledState();
2374        if (isChecked != lastEnabledState) {
2375            if (isChecked) {
2376                mDialogClicked = false;
2377                if (mEnableDialog != null) dismissDialogs();
2378                mEnableDialog = new AlertDialog.Builder(getActivity()).setMessage(
2379                        getActivity().getResources().getString(
2380                                R.string.dev_settings_warning_message))
2381                        .setTitle(R.string.dev_settings_warning_title)
2382                        .setPositiveButton(android.R.string.yes, this)
2383                        .setNegativeButton(android.R.string.no, this)
2384                        .show();
2385                mEnableDialog.setOnDismissListener(this);
2386            } else {
2387                resetDangerousOptions();
2388                mSettingsEnabler.disableDevelopmentSettings();
2389                setPrefsEnabledState(false);
2390            }
2391        }
2392    }
2393
2394    @Override
2395    public void onActivityResult(int requestCode, int resultCode, Intent data) {
2396        if (requestCode == RESULT_DEBUG_APP) {
2397            if (resultCode == Activity.RESULT_OK) {
2398                mDebugApp = data.getAction();
2399                writeDebuggerOptions();
2400                updateDebuggerOptions();
2401            }
2402        } else if (requestCode == RESULT_MOCK_LOCATION_APP) {
2403            if (resultCode == Activity.RESULT_OK) {
2404                mMockLocationApp = data.getAction();
2405                writeMockLocation();
2406                updateMockLocation();
2407            }
2408        } else if (requestCode == REQUEST_CODE_ENABLE_OEM_UNLOCK) {
2409            if (resultCode == Activity.RESULT_OK) {
2410                if (mEnableOemUnlock.isChecked()) {
2411                    confirmEnableOemUnlock();
2412                } else {
2413                    OemUnlockUtils.setOemUnlockEnabled(getActivity(), false);
2414                }
2415            }
2416        } else {
2417            super.onActivityResult(requestCode, resultCode, data);
2418        }
2419    }
2420
2421    @Override
2422    public boolean onPreferenceTreeClick(Preference preference) {
2423        if (Utils.isMonkeyRunning()) {
2424            return false;
2425        }
2426
2427        if (mBugReportInPowerController.handlePreferenceTreeClick(preference)) {
2428            return true;
2429        }
2430
2431        if (mTelephonyMonitorController.handlePreferenceTreeClick(preference)) {
2432            return true;
2433        }
2434
2435        if (mWebViewAppPrefController.handlePreferenceTreeClick(preference)) {
2436            return true;
2437        }
2438
2439        if (preference == mEnableAdb) {
2440            if (mEnableAdb.isChecked()) {
2441                mDialogClicked = false;
2442                if (mAdbDialog != null) dismissDialogs();
2443                mAdbDialog = new AlertDialog.Builder(getActivity()).setMessage(
2444                        getActivity().getResources().getString(R.string.adb_warning_message))
2445                        .setTitle(R.string.adb_warning_title)
2446                        .setPositiveButton(android.R.string.yes, this)
2447                        .setNegativeButton(android.R.string.no, this)
2448                        .show();
2449                mAdbDialog.setOnDismissListener(this);
2450            } else {
2451                Settings.Global.putInt(getActivity().getContentResolver(),
2452                        Settings.Global.ADB_ENABLED, 0);
2453                mVerifyAppsOverUsb.setEnabled(false);
2454                mVerifyAppsOverUsb.setChecked(false);
2455                updateBugreportOptions();
2456            }
2457        } else if (preference == mClearAdbKeys) {
2458            if (mAdbKeysDialog != null) dismissDialogs();
2459            mAdbKeysDialog = new AlertDialog.Builder(getActivity())
2460                    .setMessage(R.string.adb_keys_warning_message)
2461                    .setPositiveButton(android.R.string.ok, this)
2462                    .setNegativeButton(android.R.string.cancel, null)
2463                    .show();
2464        } else if (preference == mEnableTerminal) {
2465            final PackageManager pm = getActivity().getPackageManager();
2466            pm.setApplicationEnabledSetting(TERMINAL_APP_PACKAGE,
2467                    mEnableTerminal.isChecked() ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
2468                            : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 0);
2469        } else if (preference == mKeepScreenOn) {
2470            Settings.Global.putInt(getActivity().getContentResolver(),
2471                    Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
2472                    mKeepScreenOn.isChecked() ?
2473                            (BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB
2474                                    | BatteryManager.BATTERY_PLUGGED_WIRELESS) : 0);
2475        } else if (preference == mBtHciSnoopLog) {
2476            writeBtHciSnoopLogOptions();
2477        } else if (preference == mEnableOemUnlock && mEnableOemUnlock.isEnabled()) {
2478            if (mEnableOemUnlock.isChecked()) {
2479                if (!showKeyguardConfirmation(getResources(), REQUEST_CODE_ENABLE_OEM_UNLOCK)) {
2480                    confirmEnableOemUnlock();
2481                }
2482            } else {
2483                OemUnlockUtils.setOemUnlockEnabled(getActivity(), false);
2484            }
2485        } else if (preference == mMockLocationAppPref) {
2486            Intent intent = new Intent(getActivity(), AppPicker.class);
2487            intent.putExtra(AppPicker.EXTRA_REQUESTIING_PERMISSION,
2488                    Manifest.permission.ACCESS_MOCK_LOCATION);
2489            startActivityForResult(intent, RESULT_MOCK_LOCATION_APP);
2490        } else if (preference == mDebugViewAttributes) {
2491            Settings.Global.putInt(getActivity().getContentResolver(),
2492                    Settings.Global.DEBUG_VIEW_ATTRIBUTES,
2493                    mDebugViewAttributes.isChecked() ? 1 : 0);
2494        } else if (preference == mForceAllowOnExternal) {
2495            Settings.Global.putInt(getActivity().getContentResolver(),
2496                    Settings.Global.FORCE_ALLOW_ON_EXTERNAL,
2497                    mForceAllowOnExternal.isChecked() ? 1 : 0);
2498        } else if (preference == mDebugAppPref) {
2499            Intent intent = new Intent(getActivity(), AppPicker.class);
2500            intent.putExtra(AppPicker.EXTRA_DEBUGGABLE, true);
2501            startActivityForResult(intent, RESULT_DEBUG_APP);
2502        } else if (preference == mWaitForDebugger) {
2503            writeDebuggerOptions();
2504        } else if (preference == mVerifyAppsOverUsb) {
2505            writeVerifyAppsOverUsbOptions();
2506        } else if (preference == mOtaDisableAutomaticUpdate) {
2507            writeOtaDisableAutomaticUpdateOptions();
2508        } else if (preference == mStrictMode) {
2509            writeStrictModeVisualOptions();
2510        } else if (preference == mPointerLocation) {
2511            writePointerLocationOptions();
2512        } else if (preference == mShowTouches) {
2513            writeShowTouchesOptions();
2514        } else if (preference == mShowScreenUpdates) {
2515            writeShowUpdatesOption();
2516        } else if (preference == mDisableOverlays) {
2517            writeDisableOverlaysOption();
2518        } else if (preference == mImmediatelyDestroyActivities) {
2519            writeImmediatelyDestroyActivitiesOptions();
2520        } else if (preference == mShowAllANRs) {
2521            writeShowAllANRsOptions();
2522        } else if (preference == mForceHardwareUi) {
2523            writeHardwareUiOptions();
2524        } else if (preference == mForceMsaa) {
2525            writeMsaaOptions();
2526        } else if (preference == mShowHwScreenUpdates) {
2527            writeShowHwScreenUpdatesOptions();
2528        } else if (preference == mShowHwLayersUpdates) {
2529            writeShowHwLayersUpdatesOptions();
2530        } else if (preference == mDebugLayout) {
2531            writeDebugLayoutOptions();
2532        } else if (preference == mForceRtlLayout) {
2533            writeForceRtlOptions();
2534        } else if (preference == mWifiDisplayCertification) {
2535            writeWifiDisplayCertificationOptions();
2536        } else if (preference == mWifiVerboseLogging) {
2537            writeWifiVerboseLoggingOptions();
2538        } else if (preference == mWifiAggressiveHandover) {
2539            writeWifiAggressiveHandoverOptions();
2540        } else if (preference == mWifiAllowScansWithTraffic) {
2541            writeWifiAllowScansWithTrafficOptions();
2542        } else if (preference == mMobileDataAlwaysOn) {
2543            writeMobileDataAlwaysOnOptions();
2544        } else if (preference == mColorTemperaturePreference) {
2545            writeColorTemperature();
2546        } else if (preference == mUSBAudio) {
2547            writeUSBAudioOptions();
2548        } else if (preference == mForceResizable) {
2549            writeForceResizableOptions();
2550        } else if (preference == mBluetoothDisableAbsVolume) {
2551            writeBluetoothDisableAbsVolumeOptions();
2552        } else if (preference == mBluetoothEnableInbandRinging) {
2553            writeBluetoothEnableInbandRingingOptions();
2554        } else if (preference == mWebViewMultiprocess) {
2555            writeWebViewMultiprocessOptions();
2556        } else if (SHORTCUT_MANAGER_RESET_KEY.equals(preference.getKey())) {
2557            resetShortcutManagerThrottling();
2558        } else {
2559            return super.onPreferenceTreeClick(preference);
2560        }
2561
2562        return false;
2563    }
2564
2565    private boolean showKeyguardConfirmation(Resources resources, int requestCode) {
2566        return new ChooseLockSettingsHelper(getActivity(), this).launchConfirmationActivity(
2567                requestCode, resources.getString(R.string.oem_unlock_enable));
2568    }
2569
2570    @Override
2571    public boolean onPreferenceChange(Preference preference, Object newValue) {
2572        if (HDCP_CHECKING_KEY.equals(preference.getKey())) {
2573            SystemProperties.set(HDCP_CHECKING_PROPERTY, newValue.toString());
2574            updateHdcpValues();
2575            pokeSystemProperties();
2576            return true;
2577        } else if (preference == mBluetoothSelectAvrcpVersion) {
2578           writeBluetoothAvrcpVersion(newValue);
2579           return true;
2580        } else if ((preference == mBluetoothSelectA2dpCodec) ||
2581                   (preference == mBluetoothSelectA2dpSampleRate) ||
2582                   (preference == mBluetoothSelectA2dpBitsPerSample) ||
2583                   (preference == mBluetoothSelectA2dpChannelMode) ||
2584                   (preference == mBluetoothSelectA2dpLdacPlaybackQuality)) {
2585            writeBluetoothConfigurationOption(preference, newValue);
2586            return true;
2587        } else if (preference == mLogdSize) {
2588            writeLogdSizeOption(newValue);
2589            return true;
2590        } else if (preference == mLogpersist) {
2591            writeLogpersistOption(newValue, false);
2592            return true;
2593        } else if (preference == mUsbConfiguration) {
2594            writeUsbConfigurationOption(newValue);
2595            return true;
2596        } else if (preference == mWindowAnimationScale) {
2597            writeAnimationScaleOption(0, mWindowAnimationScale, newValue);
2598            return true;
2599        } else if (preference == mTransitionAnimationScale) {
2600            writeAnimationScaleOption(1, mTransitionAnimationScale, newValue);
2601            return true;
2602        } else if (preference == mAnimatorDurationScale) {
2603            writeAnimationScaleOption(2, mAnimatorDurationScale, newValue);
2604            return true;
2605        } else if (preference == mOverlayDisplayDevices) {
2606            writeOverlayDisplayDevicesOptions(newValue);
2607            return true;
2608        } else if (preference == mTrackFrameTime) {
2609            writeTrackFrameTimeOptions(newValue);
2610            return true;
2611        } else if (preference == mDebugHwOverdraw) {
2612            writeDebugHwOverdrawOptions(newValue);
2613            return true;
2614        } else if (preference == mDebugHwRenderer) {
2615            writeDebugHwRendererOptions(newValue);
2616            return true;
2617        } else if (preference == mShowNonRectClip) {
2618            writeShowNonRectClipOptions(newValue);
2619            return true;
2620        } else if (preference == mAppProcessLimit) {
2621            writeAppProcessLimitOptions(newValue);
2622            return true;
2623        } else if (preference == mSimulateColorSpace) {
2624            writeSimulateColorSpace(newValue);
2625            return true;
2626        }
2627        return false;
2628    }
2629
2630    private void dismissDialogs() {
2631        if (mAdbDialog != null) {
2632            mAdbDialog.dismiss();
2633            mAdbDialog = null;
2634        }
2635        if (mAdbKeysDialog != null) {
2636            mAdbKeysDialog.dismiss();
2637            mAdbKeysDialog = null;
2638        }
2639        if (mEnableDialog != null) {
2640            mEnableDialog.dismiss();
2641            mEnableDialog = null;
2642        }
2643        if (mLogpersistClearDialog != null) {
2644            mLogpersistClearDialog.dismiss();
2645            mLogpersistClearDialog = null;
2646        }
2647    }
2648
2649    public void onClick(DialogInterface dialog, int which) {
2650        if (dialog == mAdbDialog) {
2651            if (which == DialogInterface.BUTTON_POSITIVE) {
2652                mDialogClicked = true;
2653                Settings.Global.putInt(getActivity().getContentResolver(),
2654                        Settings.Global.ADB_ENABLED, 1);
2655                mVerifyAppsOverUsb.setEnabled(true);
2656                updateVerifyAppsOverUsbOptions();
2657                updateBugreportOptions();
2658            } else {
2659                // Reset the toggle
2660                mEnableAdb.setChecked(false);
2661            }
2662        } else if (dialog == mAdbKeysDialog) {
2663            if (which == DialogInterface.BUTTON_POSITIVE) {
2664                try {
2665                    IBinder b = ServiceManager.getService(Context.USB_SERVICE);
2666                    IUsbManager service = IUsbManager.Stub.asInterface(b);
2667                    service.clearUsbDebuggingKeys();
2668                } catch (RemoteException e) {
2669                    Log.e(TAG, "Unable to clear adb keys", e);
2670                }
2671            }
2672        } else if (dialog == mEnableDialog) {
2673            if (which == DialogInterface.BUTTON_POSITIVE) {
2674                mDialogClicked = true;
2675                mSettingsEnabler.enableDevelopmentSettings();
2676                setPrefsEnabledState(true);
2677            } else {
2678                // Reset the toggle
2679                mSwitchBar.setChecked(false);
2680            }
2681        } else if (dialog == mLogpersistClearDialog) {
2682            if (which == DialogInterface.BUTTON_POSITIVE) {
2683                setLogpersistOff(true);
2684            } else {
2685                updateLogpersistValues();
2686            }
2687        }
2688    }
2689
2690    public void onDismiss(DialogInterface dialog) {
2691        // Assuming that onClick gets called first
2692        if (dialog == mAdbDialog) {
2693            if (!mDialogClicked) {
2694                mEnableAdb.setChecked(false);
2695            }
2696            mAdbDialog = null;
2697        } else if (dialog == mEnableDialog) {
2698            if (!mDialogClicked) {
2699                mSwitchBar.setChecked(false);
2700            }
2701            mEnableDialog = null;
2702        } else if (dialog == mLogpersistClearDialog) {
2703            mLogpersistClearDialog = null;
2704        }
2705    }
2706
2707    @Override
2708    public void onDestroy() {
2709        dismissDialogs();
2710        super.onDestroy();
2711    }
2712
2713    void pokeSystemProperties() {
2714        if (!mDontPokeProperties) {
2715            //noinspection unchecked
2716            (new SystemPropPoker()).execute();
2717        }
2718    }
2719
2720    private BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
2721        @Override
2722        public void onReceive(Context context, Intent intent) {
2723            updateUsbConfigurationValues();
2724        }
2725    };
2726
2727    private BroadcastReceiver mBluetoothA2dpReceiver = new BroadcastReceiver() {
2728        @Override
2729        public void onReceive(Context context, Intent intent) {
2730            Log.d(TAG, "mBluetoothA2dpReceiver.onReceive intent=" + intent);
2731            String action = intent.getAction();
2732
2733            if (BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED.equals(action)) {
2734                BluetoothCodecStatus codecStatus =
2735                    (BluetoothCodecStatus)intent.getParcelableExtra(BluetoothCodecStatus.EXTRA_CODEC_STATUS);
2736                Log.d(TAG, "Received BluetoothCodecStatus=" + codecStatus);
2737                updateBluetoothA2dpConfigurationValues();
2738            }
2739        }
2740    };
2741
2742    private BluetoothProfile.ServiceListener mBluetoothA2dpServiceListener =
2743        new BluetoothProfile.ServiceListener() {
2744            public void onServiceConnected(int profile,
2745                                           BluetoothProfile proxy) {
2746                synchronized (mBluetoothA2dpLock) {
2747                    mBluetoothA2dp = (BluetoothA2dp) proxy;
2748                }
2749                updateBluetoothA2dpConfigurationValues();
2750            }
2751
2752            public void onServiceDisconnected(int profile) {
2753                synchronized (mBluetoothA2dpLock) {
2754                    mBluetoothA2dp = null;
2755                }
2756                updateBluetoothA2dpConfigurationValues();
2757            }
2758        };
2759
2760    public static class SystemPropPoker extends AsyncTask<Void, Void, Void> {
2761        @Override
2762        protected Void doInBackground(Void... params) {
2763            String[] services = ServiceManager.listServices();
2764            for (String service : services) {
2765                IBinder obj = ServiceManager.checkService(service);
2766                if (obj != null) {
2767                    Parcel data = Parcel.obtain();
2768                    try {
2769                        obj.transact(IBinder.SYSPROPS_TRANSACTION, data, null, 0);
2770                    } catch (RemoteException e) {
2771                    } catch (Exception e) {
2772                        Log.i(TAG, "Someone wrote a bad service '" + service
2773                                + "' that doesn't like to be poked: " + e);
2774                    }
2775                    data.recycle();
2776                }
2777            }
2778            return null;
2779        }
2780    }
2781
2782    private static boolean isPackageInstalled(Context context, String packageName) {
2783        try {
2784            return context.getPackageManager().getPackageInfo(packageName, 0) != null;
2785        } catch (NameNotFoundException e) {
2786            return false;
2787        }
2788    }
2789
2790
2791    /**
2792     * For Search.
2793     */
2794    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
2795            new BaseSearchIndexProvider() {
2796
2797                private boolean isShowingDeveloperOptions(Context context) {
2798                    return context.getSharedPreferences(DevelopmentSettings.PREF_FILE,
2799                            Context.MODE_PRIVATE).getBoolean(
2800                            DevelopmentSettings.PREF_SHOW,
2801                            android.os.Build.TYPE.equals("eng"));
2802                }
2803
2804                @Override
2805                public List<SearchIndexableResource> getXmlResourcesToIndex(
2806                        Context context, boolean enabled) {
2807
2808                    if (!isShowingDeveloperOptions(context)) {
2809                        return null;
2810                    }
2811
2812                    final SearchIndexableResource sir = new SearchIndexableResource(context);
2813                    sir.xmlResId = R.xml.development_prefs;
2814                    return Arrays.asList(sir);
2815                }
2816
2817                @Override
2818                public List<String> getNonIndexableKeys(Context context) {
2819                    if (!isShowingDeveloperOptions(context)) {
2820                        return null;
2821                    }
2822
2823                    final List<String> keys = new ArrayList<String>();
2824                    if (!showEnableOemUnlockPreference()) {
2825                        keys.add(ENABLE_OEM_UNLOCK);
2826                    }
2827                    return keys;
2828                }
2829            };
2830
2831    private void resetShortcutManagerThrottling() {
2832        final IShortcutService service = IShortcutService.Stub.asInterface(
2833                ServiceManager.getService(Context.SHORTCUT_SERVICE));
2834        if (service != null) {
2835            try {
2836                service.resetThrottling();
2837                Toast.makeText(getActivity(), R.string.reset_shortcut_manager_throttling_complete,
2838                        Toast.LENGTH_SHORT).show();
2839            } catch (RemoteException e) {
2840                Log.e(TAG, "Failed to reset rate limiting", e);
2841            }
2842        }
2843    }
2844
2845    private void updateOemUnlockSettingDescription() {
2846        if (mEnableOemUnlock != null) {
2847            int oemUnlockSummary = R.string.oem_unlock_enable_summary;
2848            if (isBootloaderUnlocked()) {
2849                oemUnlockSummary = R.string.oem_unlock_enable_disabled_summary_bootloader_unlocked;
2850            } else if (isSimLockedDevice()) {
2851                oemUnlockSummary = R.string.oem_unlock_enable_disabled_summary_sim_locked_device;
2852            } else if (!OemUnlockUtils.isOemUnlockAllowed(mUm)) {
2853                // If the device isn't SIM-locked but OEM unlock is disabled by the system via the
2854                // user restriction, this means either some other carrier restriction is in place or
2855                // the device hasn't been able to confirm which restrictions (SIM-lock or otherwise)
2856                // apply.
2857                oemUnlockSummary =
2858                        R.string.oem_unlock_enable_disabled_summary_connectivity_or_locked;
2859            }
2860            mEnableOemUnlock.setSummary(getString(oemUnlockSummary));
2861        }
2862    }
2863
2864    /** Returns {@code true} if the device is SIM-locked. Otherwise, returns {@code false}. */
2865    private boolean isSimLockedDevice() {
2866        int phoneCount = mTelephonyManager.getPhoneCount();
2867        for (int i = 0; i < phoneCount; i++) {
2868            if (mTelephonyManager.getAllowedCarriers(i).size() > 0) {
2869                return true;
2870            }
2871        }
2872        return false;
2873    }
2874
2875    /**
2876     * Returns {@code true} if the bootloader has been unlocked. Otherwise, returns {code false}.
2877     */
2878    private boolean isBootloaderUnlocked() {
2879        int flashLockState = PersistentDataBlockManager.FLASH_LOCK_UNKNOWN;
2880        if (mOemUnlockManager != null) {
2881            flashLockState = mOemUnlockManager.getFlashLockState();
2882        }
2883
2884        return flashLockState == PersistentDataBlockManager.FLASH_LOCK_UNLOCKED;
2885    }
2886
2887
2888}
2889