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