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