diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 53cc046..54bdc77 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -16,10 +16,7 @@
 
 package com.android.settings;
 
-import static com.android.settings.core.FeatureFlags.DEV_OPTION_V1;
-
 import android.os.Bundle;
-import android.util.FeatureFlagUtils;
 
 import com.android.settings.enterprise.EnterprisePrivacySettings;
 
@@ -60,16 +57,6 @@
     public static class HighPowerApplicationsActivity extends SettingsActivity { /* empty */ }
     public static class BackgroundCheckSummaryActivity extends SettingsActivity { /* empty */ }
     public static class StorageUseActivity extends SettingsActivity { /* empty */ }
-
-    /**
-     * @deprecated in favor of {@link DevelopmentSettingsDashboardActivity}.
-     */
-    @Deprecated
-    public static class DevelopmentSettingsActivity extends SettingsActivity {
-        public static final boolean isEnabled() {
-            return FeatureFlagUtils.isEnabled(null /* context */, DEV_OPTION_V1);
-        }
-    }
     public static class DevelopmentSettingsDashboardActivity extends SettingsActivity { /* empty */ }
     public static class AccessibilitySettingsActivity extends SettingsActivity { /* empty */ }
     public static class CaptioningSettingsActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index f1c2a0a..78c9c21 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -55,7 +55,6 @@
 import com.android.settings.Settings.WifiSettingsActivity;
 import com.android.settings.applications.manageapplications.ManageApplications;
 import com.android.settings.backup.BackupSettingsActivity;
-import com.android.settings.core.InstrumentedPreferenceFragment;
 import com.android.settings.core.gateway.SettingsGateway;
 import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.core.instrumentation.SharedPreferencesLogger;
@@ -827,16 +826,10 @@
 
         final boolean showDev = DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(this)
                 && !um.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES);
-        final boolean useDevOptionV1 = Settings.DevelopmentSettingsActivity.isEnabled();
-        // Enable old Dev option if v2 is disabled
-        somethingChanged = setTileEnabled(new ComponentName(packageName,
-                        Settings.DevelopmentSettingsActivity.class.getName()),
-                showDev && useDevOptionV1, isAdmin)
-                || somethingChanged;
-        // Enable new Dev option if v2 is enable
+
         somethingChanged = setTileEnabled(new ComponentName(packageName,
                         Settings.DevelopmentSettingsDashboardActivity.class.getName()),
-                showDev && !useDevOptionV1, isAdmin)
+                showDev, isAdmin)
                 || somethingChanged;
 
         // Enable/disable backup settings depending on whether the user is admin.
diff --git a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java
index 9d47c65..2e29db8 100644
--- a/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java
+++ b/src/com/android/settings/bluetooth/DeviceListPreferenceFragment.java
@@ -27,8 +27,8 @@
 import android.text.BidiFormatter;
 import android.util.Log;
 
-import com.android.settings.dashboard.RestrictedDashboardFragment;
 import com.android.settings.R;
+import com.android.settings.dashboard.RestrictedDashboardFragment;
 import com.android.settingslib.bluetooth.BluetoothCallback;
 import com.android.settingslib.bluetooth.BluetoothDeviceFilter;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
diff --git a/src/com/android/settings/core/FeatureFlags.java b/src/com/android/settings/core/FeatureFlags.java
index 91699d4..2fefa06 100644
--- a/src/com/android/settings/core/FeatureFlags.java
+++ b/src/com/android/settings/core/FeatureFlags.java
@@ -21,7 +21,6 @@
  */
 public class FeatureFlags {
     public static final String DEVICE_INFO_V2 = "device_info_v2";
-    public static final String DEV_OPTION_V1 = "dev_option_v1";
     public static final String SEARCH_V2 = "settings_search_v2";
     public static final String SUGGESTIONS_V2 = "new_settings_suggestion";
 }
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 3b5604b..76561f2 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -62,7 +62,6 @@
 import com.android.settings.datausage.DataUsageList;
 import com.android.settings.datausage.DataUsageSummary;
 import com.android.settings.deletionhelper.AutomaticStorageManagerSettings;
-import com.android.settings.development.DevelopmentSettings;
 import com.android.settings.development.DevelopmentSettingsDashboardFragment;
 import com.android.settings.deviceinfo.ImeiInformation;
 import com.android.settings.deviceinfo.PrivateVolumeForget;
@@ -176,7 +175,6 @@
             PrivateVolumeForget.class.getName(),
             PrivateVolumeSettings.class.getName(),
             PublicVolumeSettings.class.getName(),
-            DevelopmentSettings.class.getName(),
             DevelopmentSettingsDashboardFragment.class.getName(),
             AndroidBeam.class.getName(),
             WifiDisplaySettings.class.getName(),
diff --git a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
index 42eea2d..d56a402 100644
--- a/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
+++ b/src/com/android/settings/dashboard/DashboardFragmentRegistry.java
@@ -19,13 +19,11 @@
 import android.util.ArrayMap;
 
 import com.android.settings.DisplaySettings;
-import com.android.settings.Settings;
 import com.android.settings.accounts.AccountDetailDashboardFragment;
 import com.android.settings.accounts.UserAndAccountDashboardFragment;
 import com.android.settings.applications.AppAndNotificationDashboardFragment;
 import com.android.settings.applications.DefaultAppSettings;
 import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
-import com.android.settings.development.DevelopmentSettings;
 import com.android.settings.development.DevelopmentSettingsDashboardFragment;
 import com.android.settings.deviceinfo.StorageDashboardFragment;
 import com.android.settings.fuelgauge.PowerUsageSummary;
@@ -85,13 +83,8 @@
                 SystemDashboardFragment.class.getName(), CategoryKey.CATEGORY_SYSTEM);
         PARENT_TO_CATEGORY_KEY_MAP.put(LanguageAndInputSettings.class.getName(),
                 CategoryKey.CATEGORY_SYSTEM_LANGUAGE);
-        if (Settings.DevelopmentSettingsActivity.isEnabled()) {
-            PARENT_TO_CATEGORY_KEY_MAP.put(DevelopmentSettings.class.getName(),
-                    CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
-        } else {
-            PARENT_TO_CATEGORY_KEY_MAP.put(DevelopmentSettingsDashboardFragment.class.getName(),
-                    CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
-        }
+        PARENT_TO_CATEGORY_KEY_MAP.put(DevelopmentSettingsDashboardFragment.class.getName(),
+                CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
         PARENT_TO_CATEGORY_KEY_MAP.put(ConfigureNotificationSettings.class.getName(),
                 CategoryKey.CATEGORY_NOTIFICATIONS);
         PARENT_TO_CATEGORY_KEY_MAP.put(LockscreenDashboardFragment.class.getName(),
diff --git a/src/com/android/settings/development/BugReportInPowerPreferenceController.java b/src/com/android/settings/development/BugReportInPowerPreferenceController.java
deleted file mode 100644
index 2c448f5..0000000
--- a/src/com/android/settings/development/BugReportInPowerPreferenceController.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.development;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.core.AbstractPreferenceController;
-
-/**
- * deprecated in favor of {@link BugReportInPowerPreferenceControllerV2}
- */
-@Deprecated
-public class BugReportInPowerPreferenceController extends AbstractPreferenceController
-        implements PreferenceControllerMixin {
-
-    private static final String KEY_BUGREPORT_IN_POWER = "bugreport_in_power";
-
-    private UserManager mUserManager;
-    private SwitchPreference mPreference;
-
-    public BugReportInPowerPreferenceController(Context context) {
-        super(context);
-        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
-    }
-
-    @Override
-    public boolean handlePreferenceTreeClick(Preference preference) {
-        if (KEY_BUGREPORT_IN_POWER.equals(preference.getKey())) {
-            final SwitchPreference switchPreference = (SwitchPreference) preference;
-            Settings.Secure.putInt(mContext.getContentResolver(),
-                    Settings.Global.BUGREPORT_IN_POWER_MENU,
-                    switchPreference.isChecked() ? 1 : 0);
-            setBugreportStorageProviderStatus();
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        if (isAvailable()) {
-            mPreference = (SwitchPreference) screen.findPreference(KEY_BUGREPORT_IN_POWER);
-        }
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return KEY_BUGREPORT_IN_POWER;
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return !mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES);
-    }
-
-    @Override
-    public void updateState(Preference preference) {
-        updatePreference();
-    }
-
-    public void enablePreference(boolean enabled) {
-        if (isAvailable()) {
-            mPreference.setEnabled(enabled);
-        }
-    }
-
-    public void resetPreference() {
-        if (mPreference.isChecked()) {
-            mPreference.setChecked(false);
-            handlePreferenceTreeClick(mPreference);
-        }
-    }
-
-    public boolean updatePreference() {
-        if (!isAvailable()) {
-            return false;
-        }
-        final boolean enabled = Settings.Secure.getInt(
-                mContext.getContentResolver(), Settings.Global.BUGREPORT_IN_POWER_MENU, 0) != 0;
-        mPreference.setChecked(enabled);
-        return enabled;
-    }
-
-    public void updateBugreportOptions() {
-        if (!isAvailable()) {
-            return;
-        }
-        mPreference.setEnabled(true);
-        setBugreportStorageProviderStatus();
-    }
-
-    private void setBugreportStorageProviderStatus() {
-        final ComponentName componentName = new ComponentName("com.android.shell",
-                "com.android.shell.BugreportStorageProvider");
-        final boolean enabled = mPreference.isChecked();
-        mContext.getPackageManager().setComponentEnabledSetting(componentName,
-                enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
-                        : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
-                0);
-    }
-
-}
diff --git a/src/com/android/settings/development/BugReportPreferenceController.java b/src/com/android/settings/development/BugReportPreferenceController.java
deleted file mode 100644
index c05dd26..0000000
--- a/src/com/android/settings/development/BugReportPreferenceController.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.development;
-
-import android.content.Context;
-import android.os.UserManager;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.core.AbstractPreferenceController;
-
-/**
- * deprecated in favor of {@link BugReportPreferenceControllerV2}
- */
-@Deprecated
-public class BugReportPreferenceController extends AbstractPreferenceController implements
-        PreferenceControllerMixin {
-
-    private static final String KEY_BUGREPORT = "bugreport";
-
-    private UserManager mUserManager;
-    private Preference mPreference;
-
-    public BugReportPreferenceController(Context context) {
-        super(context);
-        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        if (isAvailable()) {
-            mPreference = screen.findPreference(KEY_BUGREPORT);
-        }
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return KEY_BUGREPORT;
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return !mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES);
-    }
-
-    public void enablePreference(boolean enabled) {
-        if (isAvailable()) {
-            mPreference.setEnabled(enabled);
-        }
-    }
-
-}
diff --git a/src/com/android/settings/development/CameraLaserSensorPreferenceController.java b/src/com/android/settings/development/CameraLaserSensorPreferenceController.java
deleted file mode 100644
index 3f47b88..0000000
--- a/src/com/android/settings/development/CameraLaserSensorPreferenceController.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.development;
-
-import android.content.Context;
-import android.os.SystemProperties;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-import android.widget.Toast;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.settings.R;
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.core.AbstractPreferenceController;
-
-/**
- * deprecated in favor of {@link CameraLaserSensorPreferenceControllerV2}
- */
-@Deprecated
-public class CameraLaserSensorPreferenceController extends AbstractPreferenceController
-        implements PreferenceControllerMixin {
-
-    private static final String KEY_CAMERA_LASER_SENSOR_SWITCH = "camera_laser_sensor_switch";
-    @VisibleForTesting
-    static final String BUILD_TYPE = "ro.build.type";
-    @VisibleForTesting
-    static final String PROPERTY_CAMERA_LASER_SENSOR = "persist.camera.stats.disablehaf";
-    @VisibleForTesting
-    static final int ENABLED = 0;
-    @VisibleForTesting
-    static final int DISABLED = 2;
-
-    private SwitchPreference mPreference;
-
-    public CameraLaserSensorPreferenceController(Context context) {
-        super(context);
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        mPreference = (SwitchPreference) screen.findPreference(KEY_CAMERA_LASER_SENSOR_SWITCH);
-        updatePreference();
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return KEY_CAMERA_LASER_SENSOR_SWITCH;
-    }
-
-    @Override
-    public boolean isAvailable() {
-        String buildType = SystemProperties.get(BUILD_TYPE);
-        return mContext.getResources().getBoolean(R.bool.config_show_camera_laser_sensor) &&
-               (buildType.equals("userdebug") || buildType.equals("eng"));
-    }
-
-    @Override
-    public void updateState(Preference preference) {
-        updatePreference();
-    }
-
-    @Override
-    public boolean handlePreferenceTreeClick(Preference preference) {
-        if (KEY_CAMERA_LASER_SENSOR_SWITCH.equals(preference.getKey())) {
-            final SwitchPreference switchPreference = (SwitchPreference)preference;
-            String value = Integer.toString(switchPreference.isChecked() ? ENABLED : DISABLED);
-            SystemProperties.set(PROPERTY_CAMERA_LASER_SENSOR, value);
-            return true;
-        }
-        return false;
-    }
-
-    public void enablePreference(boolean enabled) {
-        if (isAvailable()) {
-            mPreference.setEnabled(enabled);
-        }
-    }
-
-    public boolean updatePreference() {
-        if (!isAvailable()) {
-            return false;
-        }
-        final boolean enabled = isLaserSensorEnabled();
-        mPreference.setChecked(enabled);
-        return enabled;
-    }
-
-    private boolean isLaserSensorEnabled() {
-        String prop = SystemProperties.get(PROPERTY_CAMERA_LASER_SENSOR, Integer.toString(ENABLED));
-        return prop.equals(Integer.toString(ENABLED));
-    }
-}
diff --git a/src/com/android/settings/development/ConnectivityMonitorPreferenceController.java b/src/com/android/settings/development/ConnectivityMonitorPreferenceController.java
deleted file mode 100644
index e481809..0000000
--- a/src/com/android/settings/development/ConnectivityMonitorPreferenceController.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.development;
-
-import android.content.Context;
-import android.os.SystemProperties;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-import android.widget.Toast;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settings.R;
-import com.android.settingslib.core.AbstractPreferenceController;
-
-/**
- * deprecated in favor of {@link ConnectivityMonitorPreferenceControllerV2}
- */
-@Deprecated
-public class ConnectivityMonitorPreferenceController extends AbstractPreferenceController implements
-        PreferenceControllerMixin {
-
-    private static final String KEY_CONNECTIVITY_MONITOR_SWITCH = "connectivity_monitor_switch";
-    @VisibleForTesting
-    static final String BUILD_TYPE = "ro.build.type";
-    @VisibleForTesting
-    static final String PROPERTY_CONNECTIVITY_MONITOR = "persist.radio.enable_tel_mon";
-
-    @VisibleForTesting
-    static final String ENABLED_STATUS = "enabled";
-    @VisibleForTesting
-    static final String DISABLED_STATUS = "disabled";
-    @VisibleForTesting
-    static final String USER_ENABLED_STATUS = "user_enabled";
-    @VisibleForTesting
-    static final String USER_DISABLED_STATUS = "user_disabled";
-
-    private SwitchPreference mPreference;
-
-    public ConnectivityMonitorPreferenceController(Context context) {
-        super(context);
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        if (isAvailable()) {
-            mPreference = (SwitchPreference) screen.findPreference(KEY_CONNECTIVITY_MONITOR_SWITCH);
-            mPreference.setChecked(isConnectivityMonitorEnabled());
-        }
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return KEY_CONNECTIVITY_MONITOR_SWITCH;
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return mContext.getResources().getBoolean(R.bool.config_show_connectivity_monitor) &&
-                (SystemProperties.get(BUILD_TYPE).equals("userdebug") ||
-                        SystemProperties.get(BUILD_TYPE).equals("eng"));
-    }
-
-    @Override
-    public void updateState(Preference preference) {
-        updatePreference();
-    }
-
-    @Override
-    public boolean handlePreferenceTreeClick(Preference preference) {
-        if (KEY_CONNECTIVITY_MONITOR_SWITCH.equals(preference.getKey())) {
-            final SwitchPreference switchPreference = (SwitchPreference) preference;
-            SystemProperties.set(PROPERTY_CONNECTIVITY_MONITOR,
-                    switchPreference.isChecked() ? USER_ENABLED_STATUS : USER_DISABLED_STATUS);
-            Toast.makeText(mContext, R.string.connectivity_monitor_toast,
-                    Toast.LENGTH_LONG).show();
-            return true;
-        }
-        return false;
-    }
-
-    public void enablePreference(boolean enabled) {
-        if (isAvailable()) {
-            mPreference.setEnabled(enabled);
-        }
-    }
-
-    public boolean updatePreference() {
-        if (!isAvailable()) {
-            return false;
-        }
-        final boolean enabled = isConnectivityMonitorEnabled();
-        mPreference.setChecked(enabled);
-        return enabled;
-    }
-
-    private boolean isConnectivityMonitorEnabled() {
-        final String cmStatus = SystemProperties.get(PROPERTY_CONNECTIVITY_MONITOR,
-                DISABLED_STATUS);
-        return ENABLED_STATUS.equals(cmStatus) || USER_ENABLED_STATUS.equals(cmStatus);
-    }
-
-}
diff --git a/src/com/android/settings/development/DevelopmentSettings.java b/src/com/android/settings/development/DevelopmentSettings.java
deleted file mode 100644
index 1a43808..0000000
--- a/src/com/android/settings/development/DevelopmentSettings.java
+++ /dev/null
@@ -1,2644 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.development;
-
-import android.Manifest;
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.AlertDialog;
-import android.app.AppOpsManager;
-import android.app.AppOpsManager.PackageOps;
-import android.app.Dialog;
-import android.app.backup.IBackupManager;
-import android.bluetooth.BluetoothA2dp;
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothCodecConfig;
-import android.bluetooth.BluetoothCodecStatus;
-import android.bluetooth.BluetoothHeadset;
-import android.bluetooth.BluetoothProfile;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IShortcutService;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.hardware.usb.IUsbManager;
-import android.hardware.usb.UsbManager;
-import android.net.wifi.WifiManager;
-import android.os.BatteryManager;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.StrictMode;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.os.storage.IStorageManager;
-import android.provider.SearchIndexableResource;
-import android.provider.Settings;
-import android.service.oemlock.OemLockManager;
-import android.support.annotation.VisibleForTesting;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v4.content.LocalBroadcastManager;
-import android.support.v7.preference.ListPreference;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.Preference.OnPreferenceChangeListener;
-import android.support.v7.preference.PreferenceGroup;
-import android.support.v7.preference.PreferenceScreen;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.IWindowManager;
-import android.view.LayoutInflater;
-import android.view.ThreadedRenderer;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityManager;
-import android.webkit.IWebViewUpdateService;
-import android.webkit.WebViewFactory;
-import android.widget.Switch;
-import android.widget.Toast;
-
-import com.android.internal.app.LocalePicker;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.R;
-import com.android.settings.RestrictedSettingsFragment;
-import com.android.settings.SettingsActivity;
-import com.android.settings.Utils;
-import com.android.settings.dashboard.DashboardFeatureProvider;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.password.ChooseLockSettingsHelper;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-import com.android.settings.webview.WebViewAppPreferenceController;
-import com.android.settings.widget.SwitchBar;
-import com.android.settingslib.RestrictedLockUtils;
-import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-import com.android.settingslib.RestrictedSwitchPreference;
-import com.android.settingslib.core.ConfirmationDialogController;
-import com.android.settingslib.development.AbstractEnableAdbPreferenceController;
-import com.android.settingslib.development.DevelopmentSettingsEnabler;
-import com.android.settingslib.development.SystemPropPoker;
-import com.android.settingslib.drawer.CategoryKey;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-
-/*
- * Displays preferences for application developers.
- * @deprecated in favor of {@link DevelopmentSettingsDashboardFragment}
- */
-@Deprecated
-public class DevelopmentSettings extends RestrictedSettingsFragment
-        implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener,
-        OnPreferenceChangeListener, SwitchBar.OnSwitchChangeListener, Indexable {
-    private static final String TAG = "DevelopmentSettings";
-
-    private static final String CLEAR_ADB_KEYS = "clear_adb_keys";
-    private static final String ENABLE_TERMINAL = "enable_terminal";
-    private static final String KEEP_SCREEN_ON = "keep_screen_on";
-    private static final String BT_HCI_SNOOP_LOG = "bt_hci_snoop_log";
-    private static final String ENABLE_OEM_UNLOCK = "oem_unlock_enable";
-    private static final String HDCP_CHECKING_KEY = "hdcp_checking";
-    private static final String HDCP_CHECKING_PROPERTY = "persist.sys.hdcp_checking";
-    private static final String LOCAL_BACKUP_PASSWORD = "local_backup_password";
-    private static final String HARDWARE_UI_PROPERTY = "persist.sys.ui.hw";
-    private static final String MSAA_PROPERTY = "debug.egl.force_msaa";
-    private static final String COLOR_TEMPERATURE_PROPERTY = "persist.sys.debug.color_temp";
-
-    private static final String DEBUG_APP_KEY = "debug_app";
-    private static final String WAIT_FOR_DEBUGGER_KEY = "wait_for_debugger";
-    private static final String MOCK_LOCATION_APP_KEY = "mock_location_app";
-    private static final String DEBUG_VIEW_ATTRIBUTES = "debug_view_attributes";
-    private static final String FORCE_ALLOW_ON_EXTERNAL_KEY = "force_allow_on_external";
-    private static final String STRICT_MODE_KEY = "strict_mode";
-    private static final String POINTER_LOCATION_KEY = "pointer_location";
-    private static final String SHOW_TOUCHES_KEY = "show_touches";
-    private static final String SHOW_SCREEN_UPDATES_KEY = "show_screen_updates";
-    private static final String DISABLE_OVERLAYS_KEY = "disable_overlays";
-    private static final String SIMULATE_COLOR_SPACE = "simulate_color_space";
-    private static final String USB_AUDIO_KEY = "usb_audio";
-    private static final String FORCE_HARDWARE_UI_KEY = "force_hw_ui";
-    private static final String FORCE_MSAA_KEY = "force_msaa";
-    private static final String TRACK_FRAME_TIME_KEY = "track_frame_time";
-    private static final String SHOW_NON_RECTANGULAR_CLIP_KEY = "show_non_rect_clip";
-    private static final String SHOW_HW_SCREEN_UPDATES_KEY = "show_hw_screen_updates";
-    private static final String SHOW_HW_LAYERS_UPDATES_KEY = "show_hw_layers_updates";
-    private static final String DEBUG_HW_OVERDRAW_KEY = "debug_hw_overdraw";
-    private static final String DEBUG_HW_RENDERER_KEY = "debug_hw_renderer";
-    private static final String DEBUG_LAYOUT_KEY = "debug_layout";
-    private static final String FORCE_RTL_LAYOUT_KEY = "force_rtl_layout_all_locales";
-    private static final String WINDOW_ANIMATION_SCALE_KEY = "window_animation_scale";
-    private static final String TRANSITION_ANIMATION_SCALE_KEY = "transition_animation_scale";
-    private static final String ANIMATOR_DURATION_SCALE_KEY = "animator_duration_scale";
-    private static final String OVERLAY_DISPLAY_DEVICES_KEY = "overlay_display_devices";
-    private static final String DEBUG_DEBUGGING_CATEGORY_KEY = "debug_debugging_category";
-
-    private static final String WIFI_DISPLAY_CERTIFICATION_KEY = "wifi_display_certification";
-    private static final String WIFI_VERBOSE_LOGGING_KEY = "wifi_verbose_logging";
-    private static final String WIFI_AGGRESSIVE_HANDOVER_KEY = "wifi_aggressive_handover";
-    private static final String WIFI_ALLOW_SCAN_WITH_TRAFFIC_KEY = "wifi_allow_scan_with_traffic";
-    private static final String USB_CONFIGURATION_KEY = "select_usb_configuration";
-    private static final String MOBILE_DATA_ALWAYS_ON = "mobile_data_always_on";
-    private static final String TETHERING_HARDWARE_OFFLOAD = "tethering_hardware_offload";
-    private static final String KEY_COLOR_MODE = "picture_color_mode";
-    private static final String FORCE_RESIZABLE_KEY = "force_resizable_activities";
-    private static final String ENABLE_FREEFORM_SUPPORT_KEY = "enable_freeform_support";
-    private static final String COLOR_TEMPERATURE_KEY = "color_temperature";
-
-    private static final String BLUETOOTH_SHOW_DEVICES_WITHOUT_NAMES_KEY =
-            "bluetooth_show_devices_without_names";
-    private static final String BLUETOOTH_SHOW_DEVICES_WITHOUT_NAMES_PROPERTY =
-            "persist.bluetooth.showdeviceswithoutnames";
-    private static final String BLUETOOTH_DISABLE_ABSOLUTE_VOLUME_KEY =
-            "bluetooth_disable_absolute_volume";
-    private static final String BLUETOOTH_DISABLE_ABSOLUTE_VOLUME_PROPERTY =
-            "persist.bluetooth.disableabsvol";
-    private static final String BLUETOOTH_AVRCP_VERSION_PROPERTY =
-                                    "persist.bluetooth.avrcpversion";
-    private static final String BLUETOOTH_ENABLE_INBAND_RINGING_PROPERTY =
-                                    "persist.bluetooth.enableinbandringing";
-    private static final String BLUETOOTH_BTSNOOP_ENABLE_PROPERTY =
-                                    "persist.bluetooth.btsnoopenable";
-
-    private static final String BLUETOOTH_ENABLE_INBAND_RINGING_KEY = "bluetooth_enable_inband_ringing";
-    private static final String BLUETOOTH_SELECT_AVRCP_VERSION_KEY = "bluetooth_select_avrcp_version";
-    private static final String BLUETOOTH_SELECT_A2DP_CODEC_KEY = "bluetooth_select_a2dp_codec";
-    private static final String BLUETOOTH_SELECT_A2DP_SAMPLE_RATE_KEY = "bluetooth_select_a2dp_sample_rate";
-    private static final String BLUETOOTH_SELECT_A2DP_BITS_PER_SAMPLE_KEY = "bluetooth_select_a2dp_bits_per_sample";
-    private static final String BLUETOOTH_SELECT_A2DP_CHANNEL_MODE_KEY = "bluetooth_select_a2dp_channel_mode";
-    private static final String BLUETOOTH_SELECT_A2DP_LDAC_PLAYBACK_QUALITY_KEY = "bluetooth_select_a2dp_ldac_playback_quality";
-
-    private static final String INACTIVE_APPS_KEY = "inactive_apps";
-
-    private static final String IMMEDIATELY_DESTROY_ACTIVITIES_KEY
-            = "immediately_destroy_activities";
-    private static final String APP_PROCESS_LIMIT_KEY = "app_process_limit";
-
-    private static final String BACKGROUND_CHECK_KEY = "background_check";
-
-    private static final String SHOW_ALL_ANRS_KEY = "show_all_anrs";
-
-    private static final String SHOW_NOTIFICATION_CHANNEL_WARNINGS_KEY = "show_notification_channel_warnings";
-
-    private static final String TERMINAL_APP_PACKAGE = "com.android.terminal";
-
-    private static final String KEY_CONVERT_FBE = "convert_to_file_encryption";
-
-    private static final String OTA_DISABLE_AUTOMATIC_UPDATE_KEY = "ota_disable_automatic_update";
-
-    private static final int RESULT_DEBUG_APP = 1000;
-    private static final int RESULT_MOCK_LOCATION_APP = 1001;
-
-    private static final String SHORTCUT_MANAGER_RESET_KEY = "reset_shortcut_manager_throttling";
-
-    private static final int REQUEST_CODE_ENABLE_OEM_UNLOCK = 0;
-
-    private static final int[] MOCK_LOCATION_APP_OPS = new int[]{AppOpsManager.OP_MOCK_LOCATION};
-
-    private static final String STATE_SHOWING_DIALOG_KEY = "showing_dialog_key";
-
-    private String mPendingDialogKey;
-
-    private IWindowManager mWindowManager;
-    private IBackupManager mBackupManager;
-    private IWebViewUpdateService mWebViewUpdateService;
-    private UserManager mUm;
-    private WifiManager mWifiManager;
-    private OemLockManager mOemLockManager;
-    private TelephonyManager mTelephonyManager;
-
-    private SwitchBar mSwitchBar;
-
-    private boolean mHaveDebugSettings;
-    private EnableAdbPreferenceController mEnableAdbController;
-    private Preference mClearAdbKeys;
-    private SwitchPreference mEnableTerminal;
-    private RestrictedSwitchPreference mKeepScreenOn;
-    private SwitchPreference mBtHciSnoopLog;
-    private RestrictedSwitchPreference mEnableOemUnlock;
-    private SwitchPreference mDebugViewAttributes;
-    private SwitchPreference mForceAllowOnExternal;
-
-    private Preference mPassword;
-    private String mDebugApp;
-    private Preference mDebugAppPref;
-
-    private String mMockLocationApp;
-    private Preference mMockLocationAppPref;
-
-    private SwitchPreference mWaitForDebugger;
-    private VerifyAppsOverUsbPreferenceController mVerifyAppsOverUsbController;
-    private SwitchPreference mWifiDisplayCertification;
-    private SwitchPreference mWifiVerboseLogging;
-    private SwitchPreference mWifiAggressiveHandover;
-    private SwitchPreference mMobileDataAlwaysOn;
-    private SwitchPreference mTetheringHardwareOffload;
-    private SwitchPreference mBluetoothShowDevicesWithoutNames;
-    private SwitchPreference mBluetoothDisableAbsVolume;
-    private SwitchPreference mBluetoothEnableInbandRinging;
-
-    private BluetoothA2dp mBluetoothA2dp;
-    private final Object mBluetoothA2dpLock = new Object();
-    private ListPreference mBluetoothSelectAvrcpVersion;
-    private ListPreference mBluetoothSelectA2dpCodec;
-    private ListPreference mBluetoothSelectA2dpSampleRate;
-    private ListPreference mBluetoothSelectA2dpBitsPerSample;
-    private ListPreference mBluetoothSelectA2dpChannelMode;
-    private ListPreference mBluetoothSelectA2dpLdacPlaybackQuality;
-
-    private SwitchPreference mOtaDisableAutomaticUpdate;
-    private SwitchPreference mWifiAllowScansWithTraffic;
-    private SwitchPreference mStrictMode;
-    private SwitchPreference mPointerLocation;
-    private SwitchPreference mShowTouches;
-    private SwitchPreference mShowScreenUpdates;
-    private SwitchPreference mDisableOverlays;
-    private SwitchPreference mForceHardwareUi;
-    private SwitchPreference mForceMsaa;
-    private SwitchPreference mShowHwScreenUpdates;
-    private SwitchPreference mShowHwLayersUpdates;
-    private SwitchPreference mDebugLayout;
-    private SwitchPreference mForceRtlLayout;
-    private ListPreference mDebugHwOverdraw;
-    private ListPreference mDebugHwRenderer;
-    private LogdSizePreferenceController mLogdSizeController;
-    private LogpersistPreferenceController mLogpersistController;
-    private ListPreference mUsbConfiguration;
-    private ListPreference mTrackFrameTime;
-    private ListPreference mShowNonRectClip;
-    private ListPreference mWindowAnimationScale;
-    private ListPreference mTransitionAnimationScale;
-    private ListPreference mAnimatorDurationScale;
-    private ListPreference mOverlayDisplayDevices;
-
-    private WebViewAppPreferenceController mWebViewAppPrefController;
-
-    private ListPreference mSimulateColorSpace;
-
-    private SwitchPreference mUSBAudio;
-    private SwitchPreference mImmediatelyDestroyActivities;
-
-    private ListPreference mAppProcessLimit;
-
-    private SwitchPreference mShowAllANRs;
-
-    private SwitchPreference mShowNotificationChannelWarnings;
-
-    private ColorModePreference mColorModePreference;
-
-    private SwitchPreference mForceResizable;
-
-    private SwitchPreference mEnableFreeformSupport;
-
-    private SwitchPreference mColorTemperaturePreference;
-
-    private final ArrayList<Preference> mAllPrefs = new ArrayList<>();
-
-    private final ArrayList<SwitchPreference> mResetSwitchPrefs = new ArrayList<>();
-
-    private final HashSet<Preference> mDisabledPrefs = new HashSet<>();
-    // To track whether a confirmation dialog was clicked.
-    private boolean mDialogClicked;
-    private Dialog mEnableDialog;
-
-    private Dialog mAdbKeysDialog;
-    private boolean mUnavailable;
-
-    private DashboardFeatureProvider mDashboardFeatureProvider;
-    private DevelopmentSwitchBarController mSwitchBarController;
-    private BugReportPreferenceController mBugReportController;
-    private BugReportInPowerPreferenceController mBugReportInPowerController;
-    private ConnectivityMonitorPreferenceController mConnectivityMonitorController;
-    private CameraLaserSensorPreferenceController mCameraLaserSensorController;
-
-    private BroadcastReceiver mEnableAdbReceiver;
-
-    public DevelopmentSettings() {
-        super(UserManager.DISALLOW_DEBUGGING_FEATURES);
-    }
-
-    @Override
-    public int getMetricsCategory() {
-        return MetricsEvent.DEVELOPMENT;
-    }
-
-    @Override
-    public void onAttach(Context context) {
-        super.onAttach(context);
-        mDashboardFeatureProvider = FeatureFactory.getFactory(context)
-                .getDashboardFeatureProvider(context);
-    }
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        if (icicle != null) {
-            // Don't show this in onCreate since we might be on the back stack
-            mPendingDialogKey = icicle.getString(STATE_SHOWING_DIALOG_KEY);
-        }
-
-        mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
-        mBackupManager = IBackupManager.Stub.asInterface(
-                ServiceManager.getService(Context.BACKUP_SERVICE));
-        mWebViewUpdateService = WebViewFactory.getUpdateService();
-        mOemLockManager = (OemLockManager) getSystemService(Context.OEM_LOCK_SERVICE);
-        mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
-
-        mUm = (UserManager) getSystemService(Context.USER_SERVICE);
-
-        mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
-
-        mBugReportController = new BugReportPreferenceController(getActivity());
-        mBugReportInPowerController = new BugReportInPowerPreferenceController(getActivity());
-        mConnectivityMonitorController = new ConnectivityMonitorPreferenceController(getActivity());
-        mLogdSizeController = new LogdSizePreferenceController(getActivity());
-        mLogpersistController = new LogpersistPreferenceController(getActivity(), getLifecycle());
-        mWebViewAppPrefController = new WebViewAppPreferenceController(getActivity());
-        mVerifyAppsOverUsbController = new VerifyAppsOverUsbPreferenceController(getActivity());
-        mCameraLaserSensorController = new CameraLaserSensorPreferenceController(getActivity());
-
-        setIfOnlyAvailableForAdmins(true);
-        if (isUiRestricted() || !Utils.isDeviceProvisioned(getActivity())) {
-            // Block access to developer options if the user is not the owner, if user policy
-            // restricts it, or if the device has not been provisioned
-            mUnavailable = true;
-            addPreferencesFromResource(R.xml.placeholder_prefs);
-            return;
-        }
-
-        addPreferencesFromResource(R.xml.development_settings);
-        final PreferenceScreen preferenceScreen = getPreferenceScreen();
-
-        final PreferenceGroup debugDebuggingCategory = (PreferenceGroup)
-                findPreference(DEBUG_DEBUGGING_CATEGORY_KEY);
-        mEnableAdbController = new EnableAdbPreferenceController(getActivity());
-        mClearAdbKeys = findPreference(CLEAR_ADB_KEYS);
-        if (!SystemProperties.getBoolean("ro.adb.secure", false)) {
-            if (debugDebuggingCategory != null) {
-                debugDebuggingCategory.removePreference(mClearAdbKeys);
-            }
-        }
-        mAllPrefs.add(mClearAdbKeys);
-        mEnableTerminal = findAndInitSwitchPref(ENABLE_TERMINAL);
-        if (!isPackageInstalled(getActivity(), TERMINAL_APP_PACKAGE)) {
-            debugDebuggingCategory.removePreference(mEnableTerminal);
-            mEnableTerminal = null;
-        }
-
-        mBugReportController.displayPreference(preferenceScreen);
-        mBugReportInPowerController.displayPreference(preferenceScreen);
-        mConnectivityMonitorController.displayPreference(preferenceScreen);
-        mLogdSizeController.displayPreference(preferenceScreen);
-        mLogpersistController.displayPreference(preferenceScreen);
-        mWebViewAppPrefController.displayPreference(preferenceScreen);
-        mEnableAdbController.displayPreference(preferenceScreen);
-
-        mCameraLaserSensorController.displayPreference(getPreferenceScreen());
-
-        mKeepScreenOn = (RestrictedSwitchPreference) findAndInitSwitchPref(KEEP_SCREEN_ON);
-        mBtHciSnoopLog = findAndInitSwitchPref(BT_HCI_SNOOP_LOG);
-        mEnableOemUnlock = (RestrictedSwitchPreference) findAndInitSwitchPref(ENABLE_OEM_UNLOCK);
-        if (!showEnableOemUnlockPreference(getActivity())) {
-            removePreference(mEnableOemUnlock);
-            mEnableOemUnlock = null;
-        }
-
-        mDebugViewAttributes = findAndInitSwitchPref(DEBUG_VIEW_ATTRIBUTES);
-        mForceAllowOnExternal = findAndInitSwitchPref(FORCE_ALLOW_ON_EXTERNAL_KEY);
-        mPassword = findPreference(LOCAL_BACKUP_PASSWORD);
-        mAllPrefs.add(mPassword);
-
-        if (!mUm.isAdminUser()) {
-            disableForUser(mClearAdbKeys);
-            disableForUser(mEnableTerminal);
-            disableForUser(mPassword);
-        }
-
-        mDebugAppPref = findPreference(DEBUG_APP_KEY);
-        mAllPrefs.add(mDebugAppPref);
-        mWaitForDebugger = findAndInitSwitchPref(WAIT_FOR_DEBUGGER_KEY);
-
-        mMockLocationAppPref = findPreference(MOCK_LOCATION_APP_KEY);
-        mAllPrefs.add(mMockLocationAppPref);
-
-        mVerifyAppsOverUsbController.displayPreference(preferenceScreen);
-
-        mStrictMode = findAndInitSwitchPref(STRICT_MODE_KEY);
-        mPointerLocation = findAndInitSwitchPref(POINTER_LOCATION_KEY);
-        mShowTouches = findAndInitSwitchPref(SHOW_TOUCHES_KEY);
-        mShowScreenUpdates = findAndInitSwitchPref(SHOW_SCREEN_UPDATES_KEY);
-        mDisableOverlays = findAndInitSwitchPref(DISABLE_OVERLAYS_KEY);
-        mForceHardwareUi = findAndInitSwitchPref(FORCE_HARDWARE_UI_KEY);
-        mForceMsaa = findAndInitSwitchPref(FORCE_MSAA_KEY);
-        mTrackFrameTime = addListPreference(TRACK_FRAME_TIME_KEY);
-        mShowNonRectClip = addListPreference(SHOW_NON_RECTANGULAR_CLIP_KEY);
-        mShowHwScreenUpdates = findAndInitSwitchPref(SHOW_HW_SCREEN_UPDATES_KEY);
-        mShowHwLayersUpdates = findAndInitSwitchPref(SHOW_HW_LAYERS_UPDATES_KEY);
-        mDebugLayout = findAndInitSwitchPref(DEBUG_LAYOUT_KEY);
-        mForceRtlLayout = findAndInitSwitchPref(FORCE_RTL_LAYOUT_KEY);
-        mDebugHwOverdraw = addListPreference(DEBUG_HW_OVERDRAW_KEY);
-        mDebugHwRenderer = addListPreference(DEBUG_HW_RENDERER_KEY);
-        mWifiDisplayCertification = findAndInitSwitchPref(WIFI_DISPLAY_CERTIFICATION_KEY);
-        mWifiVerboseLogging = findAndInitSwitchPref(WIFI_VERBOSE_LOGGING_KEY);
-        mWifiAggressiveHandover = findAndInitSwitchPref(WIFI_AGGRESSIVE_HANDOVER_KEY);
-        mWifiAllowScansWithTraffic = findAndInitSwitchPref(WIFI_ALLOW_SCAN_WITH_TRAFFIC_KEY);
-        mMobileDataAlwaysOn = findAndInitSwitchPref(MOBILE_DATA_ALWAYS_ON);
-        mTetheringHardwareOffload = findAndInitSwitchPref(TETHERING_HARDWARE_OFFLOAD);
-        mUsbConfiguration = addListPreference(USB_CONFIGURATION_KEY);
-        mBluetoothShowDevicesWithoutNames =
-                findAndInitSwitchPref(BLUETOOTH_SHOW_DEVICES_WITHOUT_NAMES_KEY);
-        mBluetoothDisableAbsVolume = findAndInitSwitchPref(BLUETOOTH_DISABLE_ABSOLUTE_VOLUME_KEY);
-        mBluetoothEnableInbandRinging = findAndInitSwitchPref(BLUETOOTH_ENABLE_INBAND_RINGING_KEY);
-        if (!BluetoothHeadset.isInbandRingingSupported(getContext())) {
-            removePreference(mBluetoothEnableInbandRinging);
-            mBluetoothEnableInbandRinging = null;
-        }
-
-        mBluetoothSelectAvrcpVersion = addListPreference(BLUETOOTH_SELECT_AVRCP_VERSION_KEY);
-        mBluetoothSelectA2dpCodec = addListPreference(BLUETOOTH_SELECT_A2DP_CODEC_KEY);
-        mBluetoothSelectA2dpSampleRate = addListPreference(BLUETOOTH_SELECT_A2DP_SAMPLE_RATE_KEY);
-        mBluetoothSelectA2dpBitsPerSample = addListPreference(BLUETOOTH_SELECT_A2DP_BITS_PER_SAMPLE_KEY);
-        mBluetoothSelectA2dpChannelMode = addListPreference(BLUETOOTH_SELECT_A2DP_CHANNEL_MODE_KEY);
-        mBluetoothSelectA2dpLdacPlaybackQuality = addListPreference(BLUETOOTH_SELECT_A2DP_LDAC_PLAYBACK_QUALITY_KEY);
-        initBluetoothConfigurationValues();
-
-        mWindowAnimationScale = addListPreference(WINDOW_ANIMATION_SCALE_KEY);
-        mTransitionAnimationScale = addListPreference(TRANSITION_ANIMATION_SCALE_KEY);
-        mAnimatorDurationScale = addListPreference(ANIMATOR_DURATION_SCALE_KEY);
-        mOverlayDisplayDevices = addListPreference(OVERLAY_DISPLAY_DEVICES_KEY);
-        mSimulateColorSpace = addListPreference(SIMULATE_COLOR_SPACE);
-        mUSBAudio = findAndInitSwitchPref(USB_AUDIO_KEY);
-        mForceResizable = findAndInitSwitchPref(FORCE_RESIZABLE_KEY);
-        mEnableFreeformSupport = findAndInitSwitchPref(ENABLE_FREEFORM_SUPPORT_KEY);
-        removePreferenceForProduction(mEnableFreeformSupport);
-
-        mImmediatelyDestroyActivities = (SwitchPreference) findPreference(
-                IMMEDIATELY_DESTROY_ACTIVITIES_KEY);
-        mAllPrefs.add(mImmediatelyDestroyActivities);
-        mResetSwitchPrefs.add(mImmediatelyDestroyActivities);
-
-        mAppProcessLimit = addListPreference(APP_PROCESS_LIMIT_KEY);
-
-        mShowAllANRs = (SwitchPreference) findPreference(
-                SHOW_ALL_ANRS_KEY);
-        mAllPrefs.add(mShowAllANRs);
-        mResetSwitchPrefs.add(mShowAllANRs);
-
-        mShowNotificationChannelWarnings = (SwitchPreference) findPreference(
-                SHOW_NOTIFICATION_CHANNEL_WARNINGS_KEY);
-        mAllPrefs.add(mShowNotificationChannelWarnings);
-        mResetSwitchPrefs.add(mShowNotificationChannelWarnings);
-
-        Preference hdcpChecking = findPreference(HDCP_CHECKING_KEY);
-        if (hdcpChecking != null) {
-            mAllPrefs.add(hdcpChecking);
-            removePreferenceForProduction(hdcpChecking);
-        }
-
-        Preference convertFbePreference = findPreference(KEY_CONVERT_FBE);
-
-        try {
-            IBinder service = ServiceManager.getService("mount");
-            IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
-            if (!storageManager.isConvertibleToFBE()) {
-                removePreference(KEY_CONVERT_FBE);
-            } else if ("file".equals(SystemProperties.get("ro.crypto.type", "none"))) {
-                convertFbePreference.setEnabled(false);
-                convertFbePreference.setSummary(getResources()
-                        .getString(R.string.convert_to_file_encryption_done));
-            }
-        } catch (RemoteException e) {
-            removePreference(KEY_CONVERT_FBE);
-        }
-
-        mOtaDisableAutomaticUpdate = findAndInitSwitchPref(OTA_DISABLE_AUTOMATIC_UPDATE_KEY);
-
-        mColorModePreference = (ColorModePreference) findPreference(KEY_COLOR_MODE);
-        mColorModePreference.updateCurrentAndSupported();
-        if (mColorModePreference.getColorModeCount() < 2 ||
-                getContext().getResources().getConfiguration().isScreenWideColorGamut()) {
-            removePreference(KEY_COLOR_MODE);
-            mColorModePreference = null;
-        }
-
-        mColorTemperaturePreference = (SwitchPreference) findPreference(COLOR_TEMPERATURE_KEY);
-        if (getResources().getBoolean(R.bool.config_enableColorTemperature)) {
-            mAllPrefs.add(mColorTemperaturePreference);
-            mResetSwitchPrefs.add(mColorTemperaturePreference);
-        } else {
-            removePreference(COLOR_TEMPERATURE_KEY);
-            mColorTemperaturePreference = null;
-        }
-
-        addDashboardCategoryPreferences();
-    }
-
-    @VisibleForTesting
-    void addDashboardCategoryPreferences() {
-        final PreferenceScreen screen = getPreferenceScreen();
-        final List<Preference> tilePrefs = mDashboardFeatureProvider.getPreferencesForCategory(
-                getActivity(), getPrefContext(), getMetricsCategory(),
-                CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
-        if (tilePrefs != null) {
-            for (Preference preference : tilePrefs) {
-                screen.addPreference(preference);
-            }
-        }
-    }
-
-    private ListPreference addListPreference(String prefKey) {
-        ListPreference pref = (ListPreference) findPreference(prefKey);
-        mAllPrefs.add(pref);
-        pref.setOnPreferenceChangeListener(this);
-        return pref;
-    }
-
-    private void disableForUser(Preference pref) {
-        if (pref != null) {
-            pref.setEnabled(false);
-            mDisabledPrefs.add(pref);
-        }
-    }
-
-    private SwitchPreference findAndInitSwitchPref(String key) {
-        SwitchPreference pref = (SwitchPreference) findPreference(key);
-        if (pref == null) {
-            throw new IllegalArgumentException("Cannot find preference with key = " + key);
-        }
-        mAllPrefs.add(pref);
-        mResetSwitchPrefs.add(pref);
-        return pref;
-    }
-
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-
-        mSwitchBar = ((SettingsActivity) getActivity()).getSwitchBar();
-        mSwitchBarController = new DevelopmentSwitchBarController(
-                this /* DevelopmentSettings */, mSwitchBar, !mUnavailable,  getLifecycle());
-    }
-
-    private boolean removePreferenceForProduction(Preference preference) {
-        if ("user".equals(Build.TYPE)) {
-            removePreference(preference);
-            return true;
-        }
-        return false;
-    }
-
-    private void removePreference(Preference preference) {
-        if (preference == null) {
-            return;
-        }
-
-        final PreferenceGroup parent = preference.getParent();
-
-        if (parent != null) {
-            parent.removePreference(preference);
-        }
-
-        mAllPrefs.remove(preference);
-        mResetSwitchPrefs.remove(preference);
-    }
-
-    private void setPrefsEnabledState(boolean enabled) {
-        for (int i = 0; i < mAllPrefs.size(); i++) {
-            Preference pref = mAllPrefs.get(i);
-            pref.setEnabled(enabled && !mDisabledPrefs.contains(pref));
-        }
-        mEnableAdbController.enablePreference(enabled);
-        mBugReportInPowerController.enablePreference(enabled);
-        mConnectivityMonitorController.enablePreference(enabled);
-        mLogdSizeController.enablePreference(enabled);
-        mLogpersistController.enablePreference(enabled);
-        mWebViewAppPrefController.enablePreference(enabled);
-        mCameraLaserSensorController.enablePreference(enabled);
-        updateAllOptions();
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        if (mUnavailable) {
-            // Show error message
-            if (!isUiRestrictedByOnlyAdmin()) {
-                getEmptyTextView().setText(R.string.development_settings_not_available);
-            }
-            getPreferenceScreen().removeAll();
-            return;
-        }
-
-        // A DeviceAdmin has specified a maximum time until the device
-        // will lock...  in this case we can't allow the user to turn
-        // on "stay awake when plugged in" because that would defeat the
-        // restriction.
-        final EnforcedAdmin admin = RestrictedLockUtils.checkIfMaximumTimeToLockIsSet(
-                getActivity());
-        mKeepScreenOn.setDisabledByAdmin(admin);
-        if (admin == null) {
-            mDisabledPrefs.remove(mKeepScreenOn);
-        } else {
-            mDisabledPrefs.add(mKeepScreenOn);
-        }
-
-        final boolean developmentEnabledState =
-                DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(getContext());
-        mSwitchBar.setChecked(developmentEnabledState);
-        setPrefsEnabledState(developmentEnabledState);
-
-        if (mHaveDebugSettings && !developmentEnabledState) {
-            // Overall debugging is disabled, but there are some debug
-            // settings that are enabled.  This is an invalid state.  Switch
-            // to debug settings being enabled, so the user knows there is
-            // stuff enabled and can turn it all off if they want.
-            DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(getContext(), true);
-            mSwitchBar.setChecked(true);
-            setPrefsEnabledState(true);
-        }
-        mSwitchBar.show();
-
-        if (mColorModePreference != null) {
-            mColorModePreference.startListening();
-            mColorModePreference.updateCurrentAndSupported();
-        }
-
-        if (mPendingDialogKey != null) {
-            recreateDialogForKey(mPendingDialogKey);
-            mPendingDialogKey = null;
-        }
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        if (mColorModePreference != null) {
-            mColorModePreference.stopListening();
-        }
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        outState.putString(STATE_SHOWING_DIALOG_KEY, getKeyForShowingDialog());
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-            Bundle savedInstanceState) {
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(UsbManager.ACTION_USB_STATE);
-        if (getActivity().registerReceiver(mUsbReceiver, filter) == null) {
-            updateUsbConfigurationValues();
-        }
-
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        if (adapter != null) {
-            adapter.getProfileProxy(getActivity(),
-                                    mBluetoothA2dpServiceListener,
-                                    BluetoothProfile.A2DP);
-        }
-        filter = new IntentFilter();
-        filter.addAction(BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED);
-        if (getActivity().registerReceiver(mBluetoothA2dpReceiver, filter) == null) {
-            updateBluetoothA2dpConfigurationValues();
-        }
-
-        mEnableAdbReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                mVerifyAppsOverUsbController.updatePreference();
-                updateBugreportOptions();
-            }
-        };
-        LocalBroadcastManager.getInstance(getContext())
-                .registerReceiver(mEnableAdbReceiver, new IntentFilter(
-                        AbstractEnableAdbPreferenceController.ACTION_ENABLE_ADB_STATE_CHANGED));
-
-        return super.onCreateView(inflater, container, savedInstanceState);
-    }
-
-    @Override
-    public void onDestroyView() {
-        super.onDestroyView();
-
-        if (mUnavailable) {
-            return;
-        }
-        getActivity().unregisterReceiver(mUsbReceiver);
-        getActivity().unregisterReceiver(mBluetoothA2dpReceiver);
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        if (adapter != null) {
-            adapter.closeProfileProxy(BluetoothProfile.A2DP, mBluetoothA2dp);
-            mBluetoothA2dp = null;
-        }
-
-        if (mEnableAdbReceiver != null) {
-            LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(mEnableAdbReceiver);
-            mEnableAdbReceiver = null;
-        }
-    }
-
-    void updateSwitchPreference(SwitchPreference switchPreference, boolean value) {
-        switchPreference.setChecked(value);
-        mHaveDebugSettings |= value;
-    }
-
-    private void updateAllOptions() {
-        final Context context = getActivity();
-        final ContentResolver cr = context.getContentResolver();
-        mHaveDebugSettings = false;
-        final Preference enableAdb = findPreference(mEnableAdbController.getPreferenceKey());
-        mEnableAdbController.updateState(enableAdb);
-        mHaveDebugSettings |= mEnableAdbController.haveDebugSettings();
-        if (mEnableTerminal != null) {
-            updateSwitchPreference(mEnableTerminal,
-                    context.getPackageManager().getApplicationEnabledSetting(TERMINAL_APP_PACKAGE)
-                            == PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
-        }
-        mHaveDebugSettings |= mBugReportInPowerController.updatePreference();
-        mHaveDebugSettings |= mConnectivityMonitorController.updatePreference();
-        mHaveDebugSettings |= mCameraLaserSensorController.updatePreference();
-        updateSwitchPreference(mKeepScreenOn, Settings.Global.getInt(cr,
-                Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0) != 0);
-        updateSwitchPreference(mBtHciSnoopLog, SystemProperties.getBoolean(
-                BLUETOOTH_BTSNOOP_ENABLE_PROPERTY, false));
-        updateSwitchPreference(mDebugViewAttributes, Settings.Global.getInt(cr,
-                Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0);
-        updateSwitchPreference(mForceAllowOnExternal, Settings.Global.getInt(cr,
-                Settings.Global.FORCE_ALLOW_ON_EXTERNAL, 0) != 0);
-        updateHdcpValues();
-        updatePasswordSummary();
-        updateDebuggerOptions();
-        updateMockLocation();
-        updateStrictModeVisualOptions();
-        updatePointerLocationOptions();
-        updateShowTouchesOptions();
-        updateFlingerOptions();
-        updateHardwareUiOptions();
-        updateMsaaOptions();
-        updateTrackFrameTimeOptions();
-        updateShowNonRectClipOptions();
-        updateShowHwScreenUpdatesOptions();
-        updateShowHwLayersUpdatesOptions();
-        updateDebugHwOverdrawOptions();
-        updateDebugHwRendererOptions();
-        updateDebugLayoutOptions();
-        updateAnimationScaleOptions();
-        updateOverlayDisplayDevicesOptions();
-        updateImmediatelyDestroyActivitiesOptions();
-        updateAppProcessLimitOptions();
-        updateShowAllANRsOptions();
-        updateShowNotificationChannelWarningsOptions();
-        mVerifyAppsOverUsbController.updatePreference();
-        updateOtaDisableAutomaticUpdateOptions();
-        updateBugreportOptions();
-        updateForceRtlOptions();
-        mLogdSizeController.updateLogdSizeValues();
-        mLogpersistController.updateLogpersistValues();
-        updateWifiDisplayCertificationOptions();
-        updateWifiVerboseLoggingOptions();
-        updateWifiAggressiveHandoverOptions();
-        updateWifiAllowScansWithTrafficOptions();
-        updateMobileDataAlwaysOnOptions();
-        updateTetheringHardwareOffloadOptions();
-        updateSimulateColorSpace();
-        updateUSBAudioOptions();
-        updateForceResizableOptions();
-        updateEnableFreeformWindowsSupportOptions();
-        Preference webViewAppPref = findPreference(mWebViewAppPrefController.getPreferenceKey());
-        mWebViewAppPrefController.updateState(webViewAppPref);
-        updateOemUnlockOptions();
-        if (mColorTemperaturePreference != null) {
-            updateColorTemperature();
-        }
-        updateBluetoothShowDevicesWithoutUserFriendlyNameOptions();
-        updateBluetoothDisableAbsVolumeOptions();
-        updateBluetoothEnableInbandRingingOptions();
-        updateBluetoothA2dpConfigurationValues();
-    }
-
-    private void resetDangerousOptions() {
-        SystemPropPoker.getInstance().blockPokes();
-        for (int i = 0; i < mResetSwitchPrefs.size(); i++) {
-            SwitchPreference cb = mResetSwitchPrefs.get(i);
-            if (cb.isChecked()) {
-                cb.setChecked(false);
-                onPreferenceTreeClick(cb);
-            }
-        }
-        if (mBluetoothEnableInbandRinging != null) {
-            mBluetoothEnableInbandRinging.setChecked(true);
-            onPreferenceTreeClick(mBluetoothEnableInbandRinging);
-        }
-        mBugReportInPowerController.resetPreference();
-        mEnableAdbController.resetPreference();
-        resetDebuggerOptions();
-        mLogpersistController.writeLogpersistOption(null, true);
-        mLogdSizeController.writeLogdSizeOption(null);
-        writeAnimationScaleOption(0, mWindowAnimationScale, null);
-        writeAnimationScaleOption(1, mTransitionAnimationScale, null);
-        writeAnimationScaleOption(2, mAnimatorDurationScale, null);
-        // Only poke the color space setting if we control it.
-        if (usingDevelopmentColorSpace()) {
-            writeSimulateColorSpace(-1);
-        }
-        writeOverlayDisplayDevicesOptions(null);
-        writeAppProcessLimitOptions(null);
-        mHaveDebugSettings = false;
-        updateAllOptions();
-        SystemPropPoker.getInstance().unblockPokes();
-        SystemPropPoker.getInstance().poke();
-    }
-
-    private void updateHdcpValues() {
-        ListPreference hdcpChecking = (ListPreference) findPreference(HDCP_CHECKING_KEY);
-        if (hdcpChecking != null) {
-            String currentValue = SystemProperties.get(HDCP_CHECKING_PROPERTY);
-            String[] values = getResources().getStringArray(R.array.hdcp_checking_values);
-            String[] summaries = getResources().getStringArray(R.array.hdcp_checking_summaries);
-            int index = 1; // Defaults to drm-only. Needs to match with R.array.hdcp_checking_values
-            for (int i = 0; i < values.length; i++) {
-                if (currentValue.equals(values[i])) {
-                    index = i;
-                    break;
-                }
-            }
-            hdcpChecking.setValue(values[index]);
-            hdcpChecking.setSummary(summaries[index]);
-            hdcpChecking.setOnPreferenceChangeListener(this);
-        }
-    }
-
-    private void updatePasswordSummary() {
-        mPassword.setEnabled(mBackupManager != null);
-        if (mBackupManager != null) {
-            try {
-                if (mBackupManager.hasBackupPassword()) {
-                    mPassword.setSummary(R.string.local_backup_password_summary_change);
-                } else {
-                    mPassword.setSummary(R.string.local_backup_password_summary_none);
-                }
-            } catch (RemoteException e) {
-                // Not much we can do here
-            }
-        }
-    }
-
-    private void writeBtHciSnoopLogOptions() {
-        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
-        SystemProperties.set(BLUETOOTH_BTSNOOP_ENABLE_PROPERTY,
-                Boolean.toString(mBtHciSnoopLog.isChecked()));
-    }
-
-    private void writeDebuggerOptions() {
-        try {
-            ActivityManager.getService().setDebugApp(
-                    mDebugApp, mWaitForDebugger.isChecked(), true);
-        } catch (RemoteException ex) {
-        }
-    }
-
-    private void writeMockLocation() {
-        AppOpsManager appOpsManager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
-
-        // Disable the app op of the previous mock location app if such.
-        List<PackageOps> packageOps = appOpsManager.getPackagesForOps(MOCK_LOCATION_APP_OPS);
-        if (packageOps != null) {
-            // Should be one but in case we are in a bad state due to use of command line tools.
-            for (PackageOps packageOp : packageOps) {
-                if (packageOp.getOps().get(0).getMode() != AppOpsManager.MODE_ERRORED) {
-                    String oldMockLocationApp = packageOp.getPackageName();
-                    try {
-                        ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(
-                                oldMockLocationApp, PackageManager.GET_DISABLED_COMPONENTS);
-                        appOpsManager.setMode(AppOpsManager.OP_MOCK_LOCATION, ai.uid,
-                                oldMockLocationApp, AppOpsManager.MODE_ERRORED);
-                    } catch (NameNotFoundException e) {
-                        /* ignore */
-                    }
-                }
-            }
-        }
-
-        // Enable the app op of the new mock location app if such.
-        if (!TextUtils.isEmpty(mMockLocationApp)) {
-            try {
-                ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(
-                        mMockLocationApp, PackageManager.GET_DISABLED_COMPONENTS);
-                appOpsManager.setMode(AppOpsManager.OP_MOCK_LOCATION, ai.uid,
-                        mMockLocationApp, AppOpsManager.MODE_ALLOWED);
-            } catch (NameNotFoundException e) {
-                /* ignore */
-            }
-        }
-    }
-
-    private static void resetDebuggerOptions() {
-        try {
-            ActivityManager.getService().setDebugApp(
-                    null, false, true);
-        } catch (RemoteException ex) {
-        }
-    }
-
-    private void updateDebuggerOptions() {
-        mDebugApp = Settings.Global.getString(
-                getActivity().getContentResolver(), Settings.Global.DEBUG_APP);
-        updateSwitchPreference(mWaitForDebugger, Settings.Global.getInt(
-                getActivity().getContentResolver(), Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0);
-        if (mDebugApp != null && mDebugApp.length() > 0) {
-            String label;
-            try {
-                ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(mDebugApp,
-                        PackageManager.GET_DISABLED_COMPONENTS);
-                CharSequence lab = getActivity().getPackageManager().getApplicationLabel(ai);
-                label = lab != null ? lab.toString() : mDebugApp;
-            } catch (PackageManager.NameNotFoundException e) {
-                label = mDebugApp;
-            }
-            mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_set, label));
-            mWaitForDebugger.setEnabled(true);
-            mHaveDebugSettings = true;
-        } else {
-            mDebugAppPref.setSummary(getResources().getString(R.string.debug_app_not_set));
-            mWaitForDebugger.setEnabled(false);
-        }
-    }
-
-    private void updateMockLocation() {
-        AppOpsManager appOpsManager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
-
-        List<PackageOps> packageOps = appOpsManager.getPackagesForOps(MOCK_LOCATION_APP_OPS);
-        if (packageOps != null) {
-            for (PackageOps packageOp : packageOps) {
-                if (packageOp.getOps().get(0).getMode() == AppOpsManager.MODE_ALLOWED) {
-                    mMockLocationApp = packageOps.get(0).getPackageName();
-                    break;
-                }
-            }
-        }
-
-        if (!TextUtils.isEmpty(mMockLocationApp)) {
-            String label = mMockLocationApp;
-            try {
-                ApplicationInfo ai = getActivity().getPackageManager().getApplicationInfo(
-                        mMockLocationApp, PackageManager.GET_DISABLED_COMPONENTS);
-                CharSequence appLabel = getPackageManager().getApplicationLabel(ai);
-                if (appLabel != null) {
-                    label = appLabel.toString();
-                }
-            } catch (PackageManager.NameNotFoundException e) {
-                /* ignore */
-            }
-
-            mMockLocationAppPref.setSummary(getString(R.string.mock_location_app_set, label));
-            mHaveDebugSettings = true;
-        } else {
-            mMockLocationAppPref.setSummary(getString(R.string.mock_location_app_not_set));
-        }
-    }
-
-    private void updateOtaDisableAutomaticUpdateOptions() {
-        // We use the "disabled status" in code, but show the opposite text
-        // "Automatic system updates" on screen. So a value 0 indicates the
-        // automatic update is enabled.
-        updateSwitchPreference(mOtaDisableAutomaticUpdate, Settings.Global.getInt(
-                getActivity().getContentResolver(),
-                Settings.Global.OTA_DISABLE_AUTOMATIC_UPDATE, 0) != 1);
-    }
-
-    private void writeOtaDisableAutomaticUpdateOptions() {
-        // We use the "disabled status" in code, but show the opposite text
-        // "Automatic system updates" on screen. So a value 0 indicates the
-        // automatic update is enabled.
-        Settings.Global.putInt(getActivity().getContentResolver(),
-                Settings.Global.OTA_DISABLE_AUTOMATIC_UPDATE,
-                mOtaDisableAutomaticUpdate.isChecked() ? 0 : 1);
-    }
-
-    private static boolean showEnableOemUnlockPreference(Context context) {
-        return context.getSystemService(Context.OEM_LOCK_SERVICE) != null;
-    }
-
-    /**
-     * Returns whether OEM unlock is allowed by the user and carrier.
-     *
-     * This does not take into account any restrictions imposed by the device policy.
-     */
-    private boolean isOemUnlockAllowedByUserAndCarrier() {
-        final UserHandle userHandle = UserHandle.of(UserHandle.myUserId());
-        return mOemLockManager.isOemUnlockAllowedByCarrier()
-                && !mUm.hasBaseUserRestriction(UserManager.DISALLOW_FACTORY_RESET, userHandle);
-    }
-
-    private boolean enableOemUnlockPreference() {
-        return !isBootloaderUnlocked() && isOemUnlockAllowedByUserAndCarrier();
-    }
-
-    private void updateOemUnlockOptions() {
-        if (mEnableOemUnlock != null) {
-            updateSwitchPreference(mEnableOemUnlock, mOemLockManager.isOemUnlockAllowed());
-            updateOemUnlockSettingDescription();
-            // Showing mEnableOemUnlock preference as device has persistent data block.
-            mEnableOemUnlock.setDisabledByAdmin(null);
-            mEnableOemUnlock.setEnabled(enableOemUnlockPreference());
-            if (mEnableOemUnlock.isEnabled()) {
-                // Check restriction, disable mEnableOemUnlock and apply policy transparency.
-                mEnableOemUnlock.checkRestrictionAndSetDisabled(UserManager.DISALLOW_FACTORY_RESET);
-            }
-        }
-    }
-
-    private void updateBugreportOptions() {
-        mBugReportController.enablePreference(true);
-        mBugReportInPowerController.updateBugreportOptions();
-    }
-
-    // Returns the current state of the system property that controls
-    // strictmode flashes.  One of:
-    //    0: not explicitly set one way or another
-    //    1: on
-    //    2: off
-    private static int currentStrictModeActiveIndex() {
-        if (TextUtils.isEmpty(SystemProperties.get(StrictMode.VISUAL_PROPERTY))) {
-            return 0;
-        }
-        boolean enabled = SystemProperties.getBoolean(StrictMode.VISUAL_PROPERTY, false);
-        return enabled ? 1 : 2;
-    }
-
-    private void writeStrictModeVisualOptions() {
-        try {
-            mWindowManager.setStrictModeVisualIndicatorPreference(mStrictMode.isChecked()
-                    ? "1" : "");
-        } catch (RemoteException e) {
-        }
-    }
-
-    private void updateStrictModeVisualOptions() {
-        updateSwitchPreference(mStrictMode, currentStrictModeActiveIndex() == 1);
-    }
-
-    private void writePointerLocationOptions() {
-        Settings.System.putInt(getActivity().getContentResolver(),
-                Settings.System.POINTER_LOCATION, mPointerLocation.isChecked() ? 1 : 0);
-    }
-
-    private void updatePointerLocationOptions() {
-        updateSwitchPreference(mPointerLocation,
-                Settings.System.getInt(getActivity().getContentResolver(),
-                        Settings.System.POINTER_LOCATION, 0) != 0);
-    }
-
-    private void writeShowTouchesOptions() {
-        Settings.System.putInt(getActivity().getContentResolver(),
-                Settings.System.SHOW_TOUCHES, mShowTouches.isChecked() ? 1 : 0);
-    }
-
-    private void updateShowTouchesOptions() {
-        updateSwitchPreference(mShowTouches,
-                Settings.System.getInt(getActivity().getContentResolver(),
-                        Settings.System.SHOW_TOUCHES, 0) != 0);
-    }
-
-    private void updateFlingerOptions() {
-        // magic communication with surface flinger.
-        try {
-            IBinder flinger = ServiceManager.getService("SurfaceFlinger");
-            if (flinger != null) {
-                Parcel data = Parcel.obtain();
-                Parcel reply = Parcel.obtain();
-                data.writeInterfaceToken("android.ui.ISurfaceComposer");
-                flinger.transact(1010, data, reply, 0);
-                @SuppressWarnings("unused")
-                int showCpu = reply.readInt();
-                @SuppressWarnings("unused")
-                int enableGL = reply.readInt();
-                int showUpdates = reply.readInt();
-                updateSwitchPreference(mShowScreenUpdates, showUpdates != 0);
-                @SuppressWarnings("unused")
-                int showBackground = reply.readInt();
-                int disableOverlays = reply.readInt();
-                updateSwitchPreference(mDisableOverlays, disableOverlays != 0);
-                reply.recycle();
-                data.recycle();
-            }
-        } catch (RemoteException ex) {
-        }
-    }
-
-    private void writeShowUpdatesOption() {
-        try {
-            IBinder flinger = ServiceManager.getService("SurfaceFlinger");
-            if (flinger != null) {
-                Parcel data = Parcel.obtain();
-                data.writeInterfaceToken("android.ui.ISurfaceComposer");
-                final int showUpdates = mShowScreenUpdates.isChecked() ? 1 : 0;
-                data.writeInt(showUpdates);
-                flinger.transact(1002, data, null, 0);
-                data.recycle();
-
-                updateFlingerOptions();
-            }
-        } catch (RemoteException ex) {
-        }
-    }
-
-    private void writeDisableOverlaysOption() {
-        try {
-            IBinder flinger = ServiceManager.getService("SurfaceFlinger");
-            if (flinger != null) {
-                Parcel data = Parcel.obtain();
-                data.writeInterfaceToken("android.ui.ISurfaceComposer");
-                final int disableOverlays = mDisableOverlays.isChecked() ? 1 : 0;
-                data.writeInt(disableOverlays);
-                flinger.transact(1008, data, null, 0);
-                data.recycle();
-
-                updateFlingerOptions();
-            }
-        } catch (RemoteException ex) {
-        }
-    }
-
-    private void updateHardwareUiOptions() {
-        updateSwitchPreference(mForceHardwareUi,
-                SystemProperties.getBoolean(HARDWARE_UI_PROPERTY, false));
-    }
-
-    private void writeHardwareUiOptions() {
-        SystemProperties.set(HARDWARE_UI_PROPERTY, mForceHardwareUi.isChecked() ? "true" : "false");
-        SystemPropPoker.getInstance().poke();
-    }
-
-    private void updateMsaaOptions() {
-        updateSwitchPreference(mForceMsaa, SystemProperties.getBoolean(MSAA_PROPERTY, false));
-    }
-
-    private void writeMsaaOptions() {
-        SystemProperties.set(MSAA_PROPERTY, mForceMsaa.isChecked() ? "true" : "false");
-        SystemPropPoker.getInstance().poke();
-    }
-
-    private void updateTrackFrameTimeOptions() {
-        String value = SystemProperties.get(ThreadedRenderer.PROFILE_PROPERTY);
-        if (value == null) {
-            value = "";
-        }
-
-        CharSequence[] values = mTrackFrameTime.getEntryValues();
-        for (int i = 0; i < values.length; i++) {
-            if (value.contentEquals(values[i])) {
-                mTrackFrameTime.setValueIndex(i);
-                mTrackFrameTime.setSummary(mTrackFrameTime.getEntries()[i]);
-                return;
-            }
-        }
-        mTrackFrameTime.setValueIndex(0);
-        mTrackFrameTime.setSummary(mTrackFrameTime.getEntries()[0]);
-    }
-
-    private void writeTrackFrameTimeOptions(Object newValue) {
-        SystemProperties.set(ThreadedRenderer.PROFILE_PROPERTY,
-                newValue == null ? "" : newValue.toString());
-        SystemPropPoker.getInstance().poke();
-        updateTrackFrameTimeOptions();
-    }
-
-    private void updateShowNonRectClipOptions() {
-        String value = SystemProperties.get(
-                ThreadedRenderer.DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY);
-        if (value == null) {
-            value = "hide";
-        }
-
-        CharSequence[] values = mShowNonRectClip.getEntryValues();
-        for (int i = 0; i < values.length; i++) {
-            if (value.contentEquals(values[i])) {
-                mShowNonRectClip.setValueIndex(i);
-                mShowNonRectClip.setSummary(mShowNonRectClip.getEntries()[i]);
-                return;
-            }
-        }
-        mShowNonRectClip.setValueIndex(0);
-        mShowNonRectClip.setSummary(mShowNonRectClip.getEntries()[0]);
-    }
-
-    private void writeShowNonRectClipOptions(Object newValue) {
-        SystemProperties.set(ThreadedRenderer.DEBUG_SHOW_NON_RECTANGULAR_CLIP_PROPERTY,
-                newValue == null ? "" : newValue.toString());
-        SystemPropPoker.getInstance().poke();
-        updateShowNonRectClipOptions();
-    }
-
-    private void updateShowHwScreenUpdatesOptions() {
-        updateSwitchPreference(mShowHwScreenUpdates,
-                SystemProperties.getBoolean(ThreadedRenderer.DEBUG_DIRTY_REGIONS_PROPERTY, false));
-    }
-
-    private void writeShowHwScreenUpdatesOptions() {
-        SystemProperties.set(ThreadedRenderer.DEBUG_DIRTY_REGIONS_PROPERTY,
-                mShowHwScreenUpdates.isChecked() ? "true" : null);
-        SystemPropPoker.getInstance().poke();
-    }
-
-    private void updateShowHwLayersUpdatesOptions() {
-        updateSwitchPreference(mShowHwLayersUpdates, SystemProperties.getBoolean(
-                ThreadedRenderer.DEBUG_SHOW_LAYERS_UPDATES_PROPERTY, false));
-    }
-
-    private void writeShowHwLayersUpdatesOptions() {
-        SystemProperties.set(ThreadedRenderer.DEBUG_SHOW_LAYERS_UPDATES_PROPERTY,
-                mShowHwLayersUpdates.isChecked() ? "true" : null);
-        SystemPropPoker.getInstance().poke();
-    }
-
-    private void updateDebugHwOverdrawOptions() {
-        String value = SystemProperties.get(ThreadedRenderer.DEBUG_OVERDRAW_PROPERTY);
-        if (value == null) {
-            value = "";
-        }
-
-        CharSequence[] values = mDebugHwOverdraw.getEntryValues();
-        for (int i = 0; i < values.length; i++) {
-            if (value.contentEquals(values[i])) {
-                mDebugHwOverdraw.setValueIndex(i);
-                mDebugHwOverdraw.setSummary(mDebugHwOverdraw.getEntries()[i]);
-                return;
-            }
-        }
-        mDebugHwOverdraw.setValueIndex(0);
-        mDebugHwOverdraw.setSummary(mDebugHwOverdraw.getEntries()[0]);
-    }
-
-    private void writeDebugHwOverdrawOptions(Object newValue) {
-        SystemProperties.set(ThreadedRenderer.DEBUG_OVERDRAW_PROPERTY,
-                newValue == null ? "" : newValue.toString());
-        SystemPropPoker.getInstance().poke();
-        updateDebugHwOverdrawOptions();
-    }
-
-    private void updateDebugHwRendererOptions() {
-        String value = SystemProperties.get(ThreadedRenderer.DEBUG_RENDERER_PROPERTY);
-        if (value == null) {
-            value = "";
-        }
-
-        CharSequence[] values = mDebugHwRenderer.getEntryValues();
-        for (int i = 0; i < values.length; i++) {
-            if (value.contentEquals(values[i])) {
-                mDebugHwRenderer.setValueIndex(i);
-                mDebugHwRenderer.setSummary(mDebugHwRenderer.getEntries()[i]);
-                return;
-            }
-        }
-        mDebugHwRenderer.setValueIndex(0);
-        mDebugHwRenderer.setSummary(mDebugHwRenderer.getEntries()[0]);
-    }
-
-    private void writeDebugHwRendererOptions(Object newValue) {
-        SystemProperties.set(ThreadedRenderer.DEBUG_RENDERER_PROPERTY,
-                newValue == null ? "" : newValue.toString());
-        SystemPropPoker.getInstance().poke();
-        updateDebugHwRendererOptions();
-    }
-
-    private void updateDebugLayoutOptions() {
-        updateSwitchPreference(mDebugLayout,
-                SystemProperties.getBoolean(View.DEBUG_LAYOUT_PROPERTY, false));
-    }
-
-    private void writeDebugLayoutOptions() {
-        SystemProperties.set(View.DEBUG_LAYOUT_PROPERTY,
-                mDebugLayout.isChecked() ? "true" : "false");
-        SystemPropPoker.getInstance().poke();
-    }
-
-    private void updateSimulateColorSpace() {
-        final ContentResolver cr = getContentResolver();
-        final boolean enabled = Settings.Secure.getInt(
-                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0) != 0;
-        if (enabled) {
-            final String mode = Integer.toString(Settings.Secure.getInt(
-                    cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER,
-                    AccessibilityManager.DALTONIZER_DISABLED));
-            mSimulateColorSpace.setValue(mode);
-            final int index = mSimulateColorSpace.findIndexOfValue(mode);
-            if (index < 0) {
-                // We're using a mode controlled by accessibility preferences.
-                mSimulateColorSpace.setSummary(getString(R.string.daltonizer_type_overridden,
-                        getString(R.string.accessibility_display_daltonizer_preference_title)));
-            } else {
-                mSimulateColorSpace.setSummary("%s");
-            }
-        } else {
-            mSimulateColorSpace.setValue(
-                    Integer.toString(AccessibilityManager.DALTONIZER_DISABLED));
-        }
-    }
-
-    /**
-     * @return <code>true</code> if the color space preference is currently
-     * controlled by development settings
-     */
-    private boolean usingDevelopmentColorSpace() {
-        final ContentResolver cr = getContentResolver();
-        final boolean enabled = Settings.Secure.getInt(
-                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0) != 0;
-        if (enabled) {
-            final String mode = Integer.toString(Settings.Secure.getInt(
-                    cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER,
-                    AccessibilityManager.DALTONIZER_DISABLED));
-            final int index = mSimulateColorSpace.findIndexOfValue(mode);
-            if (index >= 0) {
-                // We're using a mode controlled by developer preferences.
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private void writeSimulateColorSpace(Object value) {
-        final ContentResolver cr = getContentResolver();
-        final int newMode = Integer.parseInt(value.toString());
-        if (newMode < 0) {
-            Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0);
-        } else {
-            Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 1);
-            Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, newMode);
-        }
-    }
-
-    private void updateColorTemperature() {
-        updateSwitchPreference(mColorTemperaturePreference,
-                SystemProperties.getBoolean(COLOR_TEMPERATURE_PROPERTY, false));
-    }
-
-    private void writeColorTemperature() {
-        SystemProperties.set(COLOR_TEMPERATURE_PROPERTY,
-                mColorTemperaturePreference.isChecked() ? "1" : "0");
-        SystemPropPoker.getInstance().poke();
-        Toast.makeText(getActivity(), R.string.color_temperature_toast, Toast.LENGTH_LONG).show();
-    }
-
-    private void updateUSBAudioOptions() {
-        updateSwitchPreference(mUSBAudio, Settings.Secure.getInt(getContentResolver(),
-                Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED, 0) != 0);
-    }
-
-    private void writeUSBAudioOptions() {
-        Settings.Secure.putInt(getContentResolver(),
-                Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED,
-                mUSBAudio.isChecked() ? 1 : 0);
-    }
-
-    private void updateForceResizableOptions() {
-        updateSwitchPreference(mForceResizable, Settings.Global.getInt(getContentResolver(),
-                Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0);
-    }
-
-    private void writeForceResizableOptions() {
-        Settings.Global.putInt(getContentResolver(),
-                Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES,
-                mForceResizable.isChecked() ? 1 : 0);
-    }
-
-    private void updateEnableFreeformWindowsSupportOptions() {
-        updateSwitchPreference(mEnableFreeformSupport, Settings.Global.getInt(getContentResolver(),
-                Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0);
-    }
-
-    private void writeEnableFreeformWindowsSupportOptions() {
-        Settings.Global.putInt(getContentResolver(),
-                Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT,
-                mEnableFreeformSupport.isChecked() ? 1 : 0);
-    }
-
-    private void updateForceRtlOptions() {
-        updateSwitchPreference(mForceRtlLayout,
-                Settings.Global.getInt(getActivity().getContentResolver(),
-                        Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0);
-    }
-
-    private void writeForceRtlOptions() {
-        boolean value = mForceRtlLayout.isChecked();
-        Settings.Global.putInt(getActivity().getContentResolver(),
-                Settings.Global.DEVELOPMENT_FORCE_RTL, value ? 1 : 0);
-        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, value ? "1" : "0");
-        LocalePicker.updateLocales(getActivity().getResources().getConfiguration().getLocales());
-    }
-
-    private void updateWifiDisplayCertificationOptions() {
-        updateSwitchPreference(mWifiDisplayCertification, Settings.Global.getInt(
-                getActivity().getContentResolver(),
-                Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON, 0) != 0);
-    }
-
-    private void writeWifiDisplayCertificationOptions() {
-        Settings.Global.putInt(getActivity().getContentResolver(),
-                Settings.Global.WIFI_DISPLAY_CERTIFICATION_ON,
-                mWifiDisplayCertification.isChecked() ? 1 : 0);
-    }
-
-    private void updateWifiVerboseLoggingOptions() {
-        boolean enabled = mWifiManager.getVerboseLoggingLevel() > 0;
-        updateSwitchPreference(mWifiVerboseLogging, enabled);
-    }
-
-    private void writeWifiVerboseLoggingOptions() {
-        mWifiManager.enableVerboseLogging(mWifiVerboseLogging.isChecked() ? 1 : 0);
-    }
-
-    private void updateWifiAggressiveHandoverOptions() {
-        boolean enabled = mWifiManager.getAggressiveHandover() > 0;
-        updateSwitchPreference(mWifiAggressiveHandover, enabled);
-    }
-
-    private void writeWifiAggressiveHandoverOptions() {
-        mWifiManager.enableAggressiveHandover(mWifiAggressiveHandover.isChecked() ? 1 : 0);
-    }
-
-    private void updateWifiAllowScansWithTrafficOptions() {
-        boolean enabled = mWifiManager.getAllowScansWithTraffic() > 0;
-        updateSwitchPreference(mWifiAllowScansWithTraffic, enabled);
-    }
-
-    private void writeWifiAllowScansWithTrafficOptions() {
-        mWifiManager.setAllowScansWithTraffic(mWifiAllowScansWithTraffic.isChecked() ? 1 : 0);
-    }
-
-    private void updateBluetoothShowDevicesWithoutUserFriendlyNameOptions() {
-        updateSwitchPreference(mBluetoothShowDevicesWithoutNames,
-                SystemProperties.getBoolean(
-                        BLUETOOTH_SHOW_DEVICES_WITHOUT_NAMES_PROPERTY, false));
-    }
-
-    private void writeBluetoothShowDevicesWithoutUserFriendlyNameOptions() {
-        SystemProperties.set(BLUETOOTH_SHOW_DEVICES_WITHOUT_NAMES_PROPERTY,
-                mBluetoothShowDevicesWithoutNames.isChecked() ? "true" : "false");
-    }
-
-    private void updateBluetoothDisableAbsVolumeOptions() {
-        updateSwitchPreference(mBluetoothDisableAbsVolume,
-                SystemProperties.getBoolean(BLUETOOTH_DISABLE_ABSOLUTE_VOLUME_PROPERTY, false));
-    }
-
-    private void writeBluetoothDisableAbsVolumeOptions() {
-        SystemProperties.set(BLUETOOTH_DISABLE_ABSOLUTE_VOLUME_PROPERTY,
-                mBluetoothDisableAbsVolume.isChecked() ? "true" : "false");
-    }
-
-    private void updateBluetoothEnableInbandRingingOptions() {
-        if (mBluetoothEnableInbandRinging != null) {
-            updateSwitchPreference(mBluetoothEnableInbandRinging,
-                SystemProperties.getBoolean(BLUETOOTH_ENABLE_INBAND_RINGING_PROPERTY, true));
-        }
-    }
-
-    private void writeBluetoothEnableInbandRingingOptions() {
-        if (mBluetoothEnableInbandRinging != null) {
-            SystemProperties.set(BLUETOOTH_ENABLE_INBAND_RINGING_PROPERTY,
-                mBluetoothEnableInbandRinging.isChecked() ? "true" : "false");
-        }
-    }
-
-    private void updateMobileDataAlwaysOnOptions() {
-        updateSwitchPreference(mMobileDataAlwaysOn, Settings.Global.getInt(
-                getActivity().getContentResolver(),
-                Settings.Global.MOBILE_DATA_ALWAYS_ON, 1) != 0);
-    }
-
-    private void writeMobileDataAlwaysOnOptions() {
-        Settings.Global.putInt(getActivity().getContentResolver(),
-                Settings.Global.MOBILE_DATA_ALWAYS_ON,
-                mMobileDataAlwaysOn.isChecked() ? 1 : 0);
-    }
-
-    private void updateTetheringHardwareOffloadOptions() {
-        updateSwitchPreference(mTetheringHardwareOffload, Settings.Global.getInt(
-                getActivity().getContentResolver(),
-                Settings.Global.TETHER_OFFLOAD_DISABLED, 0) != 1);
-    }
-
-    private void writeTetheringHardwareOffloadOptions() {
-        Settings.Global.putInt(getActivity().getContentResolver(),
-                Settings.Global.TETHER_OFFLOAD_DISABLED,
-                mTetheringHardwareOffload.isChecked() ? 0 : 1);
-    }
-
-    private void updateUsbConfigurationValues() {
-        if (mUsbConfiguration != null) {
-            UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
-
-            String[] values = getResources().getStringArray(R.array.usb_configuration_values);
-            String[] titles = getResources().getStringArray(R.array.usb_configuration_titles);
-            int index = 0;
-            for (int i = 0; i < titles.length; i++) {
-                if (manager.isFunctionEnabled(values[i])) {
-                    index = i;
-                    break;
-                }
-            }
-            mUsbConfiguration.setValue(values[index]);
-            mUsbConfiguration.setSummary(titles[index]);
-            mUsbConfiguration.setOnPreferenceChangeListener(this);
-        }
-    }
-
-    private void writeUsbConfigurationOption(Object newValue) {
-        UsbManager manager = (UsbManager) getActivity().getSystemService(Context.USB_SERVICE);
-        String function = newValue.toString();
-        if (function.equals("none")) {
-            manager.setCurrentFunction(function, false);
-        } else {
-            manager.setCurrentFunction(function, true);
-        }
-    }
-
-    private void initBluetoothConfigurationValues() {
-        String[] values;
-        String[] summaries;
-        int index;
-
-        // Init the AVRCP Version - Default
-        values = getResources().getStringArray(R.array.bluetooth_avrcp_version_values);
-        summaries = getResources().getStringArray(R.array.bluetooth_avrcp_versions);
-        String value = SystemProperties.get(BLUETOOTH_AVRCP_VERSION_PROPERTY, values[0]);
-        index = mBluetoothSelectAvrcpVersion.findIndexOfValue(value);
-        mBluetoothSelectAvrcpVersion.setValue(values[index]);
-        mBluetoothSelectAvrcpVersion.setSummary(summaries[index]);
-
-        // Init the Codec Type - Default
-        values = getResources().getStringArray(R.array.bluetooth_a2dp_codec_values);
-        summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_summaries);
-        index = 0;
-        mBluetoothSelectA2dpCodec.setValue(values[index]);
-        mBluetoothSelectA2dpCodec.setSummary(summaries[index]);
-
-        // Init the Sample Rate - Default
-        values = getResources().getStringArray(R.array.bluetooth_a2dp_codec_sample_rate_values);
-        summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_sample_rate_summaries);
-        index = 0;
-        mBluetoothSelectA2dpSampleRate.setValue(values[index]);
-        mBluetoothSelectA2dpSampleRate.setSummary(summaries[index]);
-
-        // Init the Bits Per Sample - Default
-        values = getResources().getStringArray(R.array.bluetooth_a2dp_codec_bits_per_sample_values);
-        summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_bits_per_sample_summaries);
-        index = 0;
-        mBluetoothSelectA2dpBitsPerSample.setValue(values[index]);
-        mBluetoothSelectA2dpBitsPerSample.setSummary(summaries[index]);
-
-        // Init the Channel Mode - Default
-        values = getResources().getStringArray(R.array.bluetooth_a2dp_codec_channel_mode_values);
-        summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_channel_mode_summaries);
-        index = 0;
-        mBluetoothSelectA2dpChannelMode.setValue(values[index]);
-        mBluetoothSelectA2dpChannelMode.setSummary(summaries[index]);
-
-        // Init the LDAC Playback Quality - ABR
-        values = getResources().getStringArray(R.array.bluetooth_a2dp_codec_ldac_playback_quality_values);
-        summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_ldac_playback_quality_summaries);
-        index = 3;
-        mBluetoothSelectA2dpLdacPlaybackQuality.setValue(values[index]);
-        mBluetoothSelectA2dpLdacPlaybackQuality.setSummary(summaries[index]);
-    }
-
-    private void writeBluetoothAvrcpVersion(Object newValue) {
-        SystemProperties.set(BLUETOOTH_AVRCP_VERSION_PROPERTY, newValue.toString());
-        int index = mBluetoothSelectAvrcpVersion.findIndexOfValue(newValue.toString());
-        if (index >= 0) {
-            String[] titles = getResources().getStringArray(R.array.bluetooth_avrcp_versions);
-            mBluetoothSelectAvrcpVersion.setSummary(titles[index]);
-        }
-    }
-
-    private void updateBluetoothA2dpConfigurationValues() {
-        int index;
-        String[] summaries;
-        BluetoothCodecStatus codecStatus = null;
-        BluetoothCodecConfig codecConfig = null;
-        BluetoothCodecConfig[] codecsLocalCapabilities = null;
-        BluetoothCodecConfig[] codecsSelectableCapabilities = null;
-        String streaming;
-        Resources resources = null;
-
-        synchronized (mBluetoothA2dpLock) {
-            if (mBluetoothA2dp != null) {
-                codecStatus = mBluetoothA2dp.getCodecStatus();
-                if (codecStatus != null) {
-                    codecConfig = codecStatus.getCodecConfig();
-                    codecsLocalCapabilities = codecStatus.getCodecsLocalCapabilities();
-                    codecsSelectableCapabilities = codecStatus.getCodecsSelectableCapabilities();
-                }
-            }
-        }
-        if (codecConfig == null) {
-            return;
-        }
-
-        try {
-            resources = getResources();
-        } catch (IllegalStateException e) {
-            return;
-        }
-        if (resources == null) {
-            return;
-        }
-
-        // Update the Codec Type
-        index = -1;
-        switch (codecConfig.getCodecType()) {
-        case BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC:
-            index = 1;
-            break;
-        case BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC:
-            index = 2;
-            break;
-        case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX:
-            index = 3;
-            break;
-        case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD:
-            index = 4;
-            break;
-        case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC:
-            index = 5;
-            break;
-        case BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID:
-        default:
-            break;
-        }
-        if (index >= 0 && mBluetoothSelectA2dpCodec != null) {
-            summaries = resources.getStringArray(R.array.bluetooth_a2dp_codec_summaries);
-            streaming = resources.getString(R.string.bluetooth_select_a2dp_codec_streaming_label, summaries[index]);
-            mBluetoothSelectA2dpCodec.setSummary(streaming);
-        }
-
-        // Update the Sample Rate
-        index = -1;
-        switch (codecConfig.getSampleRate()) {
-        case BluetoothCodecConfig.SAMPLE_RATE_44100:
-            index = 1;
-            break;
-        case BluetoothCodecConfig.SAMPLE_RATE_48000:
-            index = 2;
-            break;
-        case BluetoothCodecConfig.SAMPLE_RATE_88200:
-            index = 3;
-            break;
-        case BluetoothCodecConfig.SAMPLE_RATE_96000:
-            index = 4;
-            break;
-        case BluetoothCodecConfig.SAMPLE_RATE_176400:
-        case BluetoothCodecConfig.SAMPLE_RATE_192000:
-        case BluetoothCodecConfig.SAMPLE_RATE_NONE:
-        default:
-            break;
-        }
-        if (index >= 0 && mBluetoothSelectA2dpSampleRate != null) {
-            summaries = resources.getStringArray(R.array.bluetooth_a2dp_codec_sample_rate_summaries);
-            streaming = resources.getString(R.string.bluetooth_select_a2dp_codec_streaming_label, summaries[index]);
-             mBluetoothSelectA2dpSampleRate.setSummary(streaming);
-        }
-
-        // Update the Bits Per Sample
-        index = -1;
-        switch (codecConfig.getBitsPerSample()) {
-        case BluetoothCodecConfig.BITS_PER_SAMPLE_16:
-            index = 1;
-            break;
-        case BluetoothCodecConfig.BITS_PER_SAMPLE_24:
-            index = 2;
-            break;
-        case BluetoothCodecConfig.BITS_PER_SAMPLE_32:
-            index = 3;
-            break;
-        case BluetoothCodecConfig.BITS_PER_SAMPLE_NONE:
-        default:
-            break;
-        }
-        if (index >= 0 && mBluetoothSelectA2dpBitsPerSample != null) {
-            summaries = resources.getStringArray(R.array.bluetooth_a2dp_codec_bits_per_sample_summaries);
-            streaming = resources.getString(R.string.bluetooth_select_a2dp_codec_streaming_label, summaries[index]);
-            mBluetoothSelectA2dpBitsPerSample.setSummary(streaming);
-        }
-
-        // Update the Channel Mode
-        index = -1;
-        switch (codecConfig.getChannelMode()) {
-        case BluetoothCodecConfig.CHANNEL_MODE_MONO:
-            index = 1;
-            break;
-        case BluetoothCodecConfig.CHANNEL_MODE_STEREO:
-            index = 2;
-            break;
-        case BluetoothCodecConfig.CHANNEL_MODE_NONE:
-        default:
-            break;
-        }
-        if (index >= 0 && mBluetoothSelectA2dpChannelMode != null) {
-            summaries = resources.getStringArray(R.array.bluetooth_a2dp_codec_channel_mode_summaries);
-            streaming = resources.getString(R.string.bluetooth_select_a2dp_codec_streaming_label, summaries[index]);
-             mBluetoothSelectA2dpChannelMode.setSummary(streaming);
-        }
-
-        // Update the LDAC Playback Quality
-        // The actual values are 0, 1, 2 - those are extracted
-        // as mod-10 remainders of a larger value.
-        // The reason is because within BluetoothCodecConfig we cannot use
-        // a codec-specific value of zero.
-        index = (int)codecConfig.getCodecSpecific1();
-        if (index > 0) {
-            index %= 10;
-        } else {
-            index = -1;
-        }
-        switch (index) {
-        case 0:
-        case 1:
-        case 2:
-        case 3:
-            break;
-        default:
-            index = -1;
-            break;
-        }
-        if (index >= 0 && mBluetoothSelectA2dpLdacPlaybackQuality != null) {
-            summaries = resources.getStringArray(R.array.bluetooth_a2dp_codec_ldac_playback_quality_summaries);
-            streaming = resources.getString(R.string.bluetooth_select_a2dp_codec_streaming_label, summaries[index]);
-            mBluetoothSelectA2dpLdacPlaybackQuality.setSummary(streaming);
-        }
-    }
-
-    private void writeBluetoothConfigurationOption(Preference preference,
-                                                   Object newValue) {
-        String[] summaries;
-        int index;
-        int codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID;
-        int codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT;
-        int sampleRateValue = BluetoothCodecConfig.SAMPLE_RATE_NONE;
-        int bitsPerSampleValue = BluetoothCodecConfig.BITS_PER_SAMPLE_NONE;
-        int channelModeValue = BluetoothCodecConfig.CHANNEL_MODE_NONE;
-        long codecSpecific1Value = 0;
-        long codecSpecific2Value = 0;
-        long codecSpecific3Value = 0;
-        long codecSpecific4Value = 0;
-
-        // Codec Type
-        String codecType = mBluetoothSelectA2dpCodec.getValue();
-        if (preference == mBluetoothSelectA2dpCodec) {
-            codecType = newValue.toString();
-            index = mBluetoothSelectA2dpCodec.findIndexOfValue(newValue.toString());
-            if (index >= 0) {
-                summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_summaries);
-                mBluetoothSelectA2dpCodec.setSummary(summaries[index]);
-            }
-        }
-        index = mBluetoothSelectA2dpCodec.findIndexOfValue(codecType);
-        switch (index) {
-        case 0:
-            // Reset the priority of the current codec to default
-            String oldValue = mBluetoothSelectA2dpCodec.getValue();
-            switch (mBluetoothSelectA2dpCodec.findIndexOfValue(oldValue)) {
-            case 0:
-                break;      // No current codec
-            case 1:
-                codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC;
-                break;
-            case 2:
-                codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC;
-                break;
-            case 3:
-                codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX;
-                break;
-            case 4:
-                codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD;
-                break;
-            case 5:
-                codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC;
-                break;
-            default:
-                break;
-            }
-            break;
-        case 1:
-            codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC;
-            codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
-            break;
-        case 2:
-            codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC;
-            codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
-            break;
-        case 3:
-            codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX;
-            codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
-            break;
-        case 4:
-            codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD;
-            codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
-            break;
-        case 5:
-            codecTypeValue = BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC;
-            codecPriorityValue = BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST;
-            break;
-        case 6:
-        synchronized (mBluetoothA2dpLock) {
-            if (mBluetoothA2dp != null) {
-                mBluetoothA2dp.enableOptionalCodecs();
-            }
-        }
-        return;
-        case 7:
-        synchronized (mBluetoothA2dpLock) {
-            if (mBluetoothA2dp != null) {
-                mBluetoothA2dp.disableOptionalCodecs();
-            }
-        }
-        return;
-        default:
-            break;
-        }
-
-        // Sample Rate
-        String sampleRate = mBluetoothSelectA2dpSampleRate.getValue();
-        if (preference == mBluetoothSelectA2dpSampleRate) {
-            sampleRate = newValue.toString();
-            index = mBluetoothSelectA2dpSampleRate.findIndexOfValue(newValue.toString());
-            if (index >= 0) {
-                summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_sample_rate_summaries);
-                mBluetoothSelectA2dpSampleRate.setSummary(summaries[index]);
-            }
-        }
-        index = mBluetoothSelectA2dpSampleRate.findIndexOfValue(sampleRate);
-        switch (index) {
-        case 0:
-            // Reset to default
-            break;
-        case 1:
-            sampleRateValue = BluetoothCodecConfig.SAMPLE_RATE_44100;
-            break;
-        case 2:
-            sampleRateValue = BluetoothCodecConfig.SAMPLE_RATE_48000;
-            break;
-        case 3:
-            sampleRateValue = BluetoothCodecConfig.SAMPLE_RATE_88200;
-            break;
-        case 4:
-            sampleRateValue = BluetoothCodecConfig.SAMPLE_RATE_96000;
-            break;
-        default:
-            break;
-        }
-
-        // Bits Per Sample
-        String bitsPerSample = mBluetoothSelectA2dpBitsPerSample.getValue();
-        if (preference == mBluetoothSelectA2dpBitsPerSample) {
-            bitsPerSample = newValue.toString();
-            index = mBluetoothSelectA2dpBitsPerSample.findIndexOfValue(newValue.toString());
-            if (index >= 0) {
-                summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_bits_per_sample_summaries);
-                mBluetoothSelectA2dpBitsPerSample.setSummary(summaries[index]);
-            }
-        }
-        index = mBluetoothSelectA2dpBitsPerSample.findIndexOfValue(bitsPerSample);
-        switch (index) {
-        case 0:
-            // Reset to default
-            break;
-        case 1:
-            bitsPerSampleValue = BluetoothCodecConfig.BITS_PER_SAMPLE_16;
-            break;
-        case 2:
-            bitsPerSampleValue = BluetoothCodecConfig.BITS_PER_SAMPLE_24;
-            break;
-        case 3:
-            bitsPerSampleValue = BluetoothCodecConfig.BITS_PER_SAMPLE_32;
-            break;
-        default:
-            break;
-        }
-
-        // Channel Mode
-        String channelMode = mBluetoothSelectA2dpChannelMode.getValue();
-        if (preference == mBluetoothSelectA2dpChannelMode) {
-            channelMode = newValue.toString();
-            index = mBluetoothSelectA2dpChannelMode.findIndexOfValue(newValue.toString());
-            if (index >= 0) {
-                summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_channel_mode_summaries);
-                mBluetoothSelectA2dpChannelMode.setSummary(summaries[index]);
-            }
-        }
-        index = mBluetoothSelectA2dpChannelMode.findIndexOfValue(channelMode);
-        switch (index) {
-        case 0:
-            // Reset to default
-            break;
-        case 1:
-            channelModeValue = BluetoothCodecConfig.CHANNEL_MODE_MONO;
-            break;
-        case 2:
-            channelModeValue = BluetoothCodecConfig.CHANNEL_MODE_STEREO;
-            break;
-        default:
-            break;
-        }
-
-        // LDAC Playback Quality
-        String ldacPlaybackQuality = mBluetoothSelectA2dpLdacPlaybackQuality.getValue();
-        if (preference == mBluetoothSelectA2dpLdacPlaybackQuality) {
-            ldacPlaybackQuality = newValue.toString();
-            index = mBluetoothSelectA2dpLdacPlaybackQuality.findIndexOfValue(newValue.toString());
-            if (index >= 0) {
-                summaries = getResources().getStringArray(R.array.bluetooth_a2dp_codec_ldac_playback_quality_summaries);
-                mBluetoothSelectA2dpLdacPlaybackQuality.setSummary(summaries[index]);
-            }
-        }
-        index = mBluetoothSelectA2dpLdacPlaybackQuality.findIndexOfValue(ldacPlaybackQuality);
-        switch (index) {
-        case 0:
-        case 1:
-        case 2:
-        case 3:
-            codecSpecific1Value = 1000 + index;
-            break;
-        default:
-            break;
-        }
-
-        BluetoothCodecConfig codecConfig =
-            new BluetoothCodecConfig(codecTypeValue, codecPriorityValue,
-                                     sampleRateValue, bitsPerSampleValue,
-                                     channelModeValue, codecSpecific1Value,
-                                     codecSpecific2Value, codecSpecific3Value,
-                                     codecSpecific4Value);
-
-        synchronized (mBluetoothA2dpLock) {
-            if (mBluetoothA2dp != null) {
-                mBluetoothA2dp.setCodecConfigPreference(codecConfig);
-            }
-        }
-    }
-
-    private void writeImmediatelyDestroyActivitiesOptions() {
-        try {
-            ActivityManager.getService().setAlwaysFinish(
-                    mImmediatelyDestroyActivities.isChecked());
-        } catch (RemoteException ex) {
-        }
-    }
-
-    private void updateImmediatelyDestroyActivitiesOptions() {
-        updateSwitchPreference(mImmediatelyDestroyActivities, Settings.Global.getInt(
-                getActivity().getContentResolver(), Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0)
-                != 0);
-    }
-
-    private void updateAnimationScaleValue(int which, ListPreference pref) {
-        try {
-            float scale = mWindowManager.getAnimationScale(which);
-            if (scale != 1) {
-                mHaveDebugSettings = true;
-            }
-            CharSequence[] values = pref.getEntryValues();
-            for (int i = 0; i < values.length; i++) {
-                float val = Float.parseFloat(values[i].toString());
-                if (scale <= val) {
-                    pref.setValueIndex(i);
-                    pref.setSummary(pref.getEntries()[i]);
-                    return;
-                }
-            }
-            pref.setValueIndex(values.length - 1);
-            pref.setSummary(pref.getEntries()[0]);
-        } catch (RemoteException e) {
-        }
-    }
-
-    private void updateAnimationScaleOptions() {
-        updateAnimationScaleValue(0, mWindowAnimationScale);
-        updateAnimationScaleValue(1, mTransitionAnimationScale);
-        updateAnimationScaleValue(2, mAnimatorDurationScale);
-    }
-
-    private void writeAnimationScaleOption(int which, ListPreference pref, Object newValue) {
-        try {
-            float scale = newValue != null ? Float.parseFloat(newValue.toString()) : 1;
-            mWindowManager.setAnimationScale(which, scale);
-            updateAnimationScaleValue(which, pref);
-        } catch (RemoteException e) {
-        }
-    }
-
-    private void updateOverlayDisplayDevicesOptions() {
-        String value = Settings.Global.getString(getActivity().getContentResolver(),
-                Settings.Global.OVERLAY_DISPLAY_DEVICES);
-        if (value == null) {
-            value = "";
-        }
-
-        CharSequence[] values = mOverlayDisplayDevices.getEntryValues();
-        for (int i = 0; i < values.length; i++) {
-            if (value.contentEquals(values[i])) {
-                mOverlayDisplayDevices.setValueIndex(i);
-                mOverlayDisplayDevices.setSummary(mOverlayDisplayDevices.getEntries()[i]);
-                return;
-            }
-        }
-        mOverlayDisplayDevices.setValueIndex(0);
-        mOverlayDisplayDevices.setSummary(mOverlayDisplayDevices.getEntries()[0]);
-    }
-
-    private void writeOverlayDisplayDevicesOptions(Object newValue) {
-        Settings.Global.putString(getActivity().getContentResolver(),
-                Settings.Global.OVERLAY_DISPLAY_DEVICES, (String) newValue);
-        updateOverlayDisplayDevicesOptions();
-    }
-
-    private void updateAppProcessLimitOptions() {
-        try {
-            int limit = ActivityManager.getService().getProcessLimit();
-            CharSequence[] values = mAppProcessLimit.getEntryValues();
-            for (int i = 0; i < values.length; i++) {
-                int val = Integer.parseInt(values[i].toString());
-                if (val >= limit) {
-                    if (i != 0) {
-                        mHaveDebugSettings = true;
-                    }
-                    mAppProcessLimit.setValueIndex(i);
-                    mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[i]);
-                    return;
-                }
-            }
-            mAppProcessLimit.setValueIndex(0);
-            mAppProcessLimit.setSummary(mAppProcessLimit.getEntries()[0]);
-        } catch (RemoteException e) {
-        }
-    }
-
-    private void writeAppProcessLimitOptions(Object newValue) {
-        try {
-            int limit = newValue != null ? Integer.parseInt(newValue.toString()) : -1;
-            ActivityManager.getService().setProcessLimit(limit);
-            updateAppProcessLimitOptions();
-        } catch (RemoteException e) {
-        }
-    }
-
-    private void writeShowAllANRsOptions() {
-        Settings.Secure.putInt(getActivity().getContentResolver(),
-                Settings.Secure.ANR_SHOW_BACKGROUND,
-                mShowAllANRs.isChecked() ? 1 : 0);
-    }
-
-    private void updateShowAllANRsOptions() {
-        updateSwitchPreference(mShowAllANRs, Settings.Secure.getInt(
-                getActivity().getContentResolver(), Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0);
-    }
-
-    private void writeShowNotificationChannelWarningsOptions() {
-        Settings.Global.putInt(getActivity().getContentResolver(),
-                Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS,
-                mShowNotificationChannelWarnings.isChecked() ? 1 : 0);
-    }
-
-    private void updateShowNotificationChannelWarningsOptions() {
-        final int defaultWarningEnabled = Build.IS_DEBUGGABLE ? 1 : 0;
-        updateSwitchPreference(mShowNotificationChannelWarnings, Settings.Global.getInt(
-                getActivity().getContentResolver(),
-                Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS, defaultWarningEnabled) != 0);
-    }
-
-    private void confirmEnableOemUnlock() {
-        DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                if (which == DialogInterface.BUTTON_POSITIVE) {
-                    mOemLockManager.setOemUnlockAllowedByUser(true);
-                }
-            }
-        };
-
-        DialogInterface.OnDismissListener onDismissListener =
-                new DialogInterface.OnDismissListener() {
-                    @Override
-                    public void onDismiss(DialogInterface dialog) {
-                        if (getActivity() == null) {
-                            return;
-                        }
-                        updateAllOptions();
-                    }
-                };
-
-        new AlertDialog.Builder(getActivity())
-                .setTitle(R.string.confirm_enable_oem_unlock_title)
-                .setMessage(R.string.confirm_enable_oem_unlock_text)
-                .setPositiveButton(R.string.enable_text, onClickListener)
-                .setNegativeButton(android.R.string.cancel, null)
-                .setOnDismissListener(onDismissListener)
-                .create()
-                .show();
-    }
-
-    @Override
-    public void onSwitchChanged(Switch switchView, boolean isChecked) {
-        if (switchView != mSwitchBar.getSwitch()) {
-            return;
-        }
-        final boolean developmentEnabledState =
-                DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(getContext());
-        if (isChecked != developmentEnabledState) {
-            if (isChecked) {
-                mDialogClicked = false;
-                if (mEnableDialog != null) dismissDialogs();
-                mEnableDialog = new AlertDialog.Builder(getActivity()).setMessage(
-                        getActivity().getResources().getString(
-                                R.string.dev_settings_warning_message))
-                        .setTitle(R.string.dev_settings_warning_title)
-                        .setPositiveButton(android.R.string.yes, this)
-                        .setNegativeButton(android.R.string.no, this)
-                        .show();
-                mEnableDialog.setOnDismissListener(this);
-            } else {
-                resetDangerousOptions();
-                DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(getContext(), false);
-                setPrefsEnabledState(false);
-            }
-        }
-    }
-
-    @Override
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (requestCode == RESULT_DEBUG_APP) {
-            if (resultCode == Activity.RESULT_OK) {
-                mDebugApp = data.getAction();
-                writeDebuggerOptions();
-                updateDebuggerOptions();
-            }
-        } else if (requestCode == RESULT_MOCK_LOCATION_APP) {
-            if (resultCode == Activity.RESULT_OK) {
-                mMockLocationApp = data.getAction();
-                writeMockLocation();
-                updateMockLocation();
-            }
-        } else if (requestCode == REQUEST_CODE_ENABLE_OEM_UNLOCK) {
-            if (resultCode == Activity.RESULT_OK) {
-                if (mEnableOemUnlock.isChecked()) {
-                    confirmEnableOemUnlock();
-                } else {
-                    mOemLockManager.setOemUnlockAllowedByUser(false);
-                }
-            }
-        } else {
-            super.onActivityResult(requestCode, resultCode, data);
-        }
-    }
-
-    @Override
-    public boolean onPreferenceTreeClick(Preference preference) {
-        if (Utils.isMonkeyRunning()) {
-            return false;
-        }
-
-        if (mBugReportInPowerController.handlePreferenceTreeClick(preference)) {
-            return true;
-        }
-
-        if (mConnectivityMonitorController.handlePreferenceTreeClick(preference)) {
-            return true;
-        }
-
-        if (mWebViewAppPrefController.handlePreferenceTreeClick(preference)) {
-            return true;
-        }
-
-        if (mVerifyAppsOverUsbController.handlePreferenceTreeClick(preference)) {
-            return true;
-        }
-
-        if (mEnableAdbController.handlePreferenceTreeClick(preference)) {
-            return true;
-        }
-
-        if (mCameraLaserSensorController.handlePreferenceTreeClick(preference)) {
-            return true;
-        }
-
-        if (preference == mClearAdbKeys) {
-            if (mAdbKeysDialog != null) dismissDialogs();
-            mAdbKeysDialog = new AlertDialog.Builder(getActivity())
-                    .setMessage(R.string.adb_keys_warning_message)
-                    .setPositiveButton(android.R.string.ok, this)
-                    .setNegativeButton(android.R.string.cancel, null)
-                    .show();
-        } else if (preference == mEnableTerminal) {
-            final PackageManager pm = getActivity().getPackageManager();
-            pm.setApplicationEnabledSetting(TERMINAL_APP_PACKAGE,
-                    mEnableTerminal.isChecked() ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
-                            : PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, 0);
-        } else if (preference == mKeepScreenOn) {
-            Settings.Global.putInt(getActivity().getContentResolver(),
-                    Settings.Global.STAY_ON_WHILE_PLUGGED_IN,
-                    mKeepScreenOn.isChecked() ?
-                            (BatteryManager.BATTERY_PLUGGED_AC | BatteryManager.BATTERY_PLUGGED_USB
-                                    | BatteryManager.BATTERY_PLUGGED_WIRELESS) : 0);
-        } else if (preference == mBtHciSnoopLog) {
-            writeBtHciSnoopLogOptions();
-        } else if (preference == mEnableOemUnlock && mEnableOemUnlock.isEnabled()) {
-            if (mEnableOemUnlock.isChecked()) {
-                if (!showKeyguardConfirmation(getResources(), REQUEST_CODE_ENABLE_OEM_UNLOCK)) {
-                    confirmEnableOemUnlock();
-                }
-            } else {
-                mOemLockManager.setOemUnlockAllowedByUser(false);
-            }
-        } else if (preference == mMockLocationAppPref) {
-            Intent intent = new Intent(getActivity(), AppPicker.class);
-            intent.putExtra(AppPicker.EXTRA_REQUESTIING_PERMISSION,
-                    Manifest.permission.ACCESS_MOCK_LOCATION);
-            startActivityForResult(intent, RESULT_MOCK_LOCATION_APP);
-        } else if (preference == mDebugViewAttributes) {
-            Settings.Global.putInt(getActivity().getContentResolver(),
-                    Settings.Global.DEBUG_VIEW_ATTRIBUTES,
-                    mDebugViewAttributes.isChecked() ? 1 : 0);
-        } else if (preference == mForceAllowOnExternal) {
-            Settings.Global.putInt(getActivity().getContentResolver(),
-                    Settings.Global.FORCE_ALLOW_ON_EXTERNAL,
-                    mForceAllowOnExternal.isChecked() ? 1 : 0);
-        } else if (preference == mDebugAppPref) {
-            Intent intent = new Intent(getActivity(), AppPicker.class);
-            intent.putExtra(AppPicker.EXTRA_DEBUGGABLE, true);
-            startActivityForResult(intent, RESULT_DEBUG_APP);
-        } else if (preference == mWaitForDebugger) {
-            writeDebuggerOptions();
-        } else if (preference == mOtaDisableAutomaticUpdate) {
-            writeOtaDisableAutomaticUpdateOptions();
-        } else if (preference == mStrictMode) {
-            writeStrictModeVisualOptions();
-        } else if (preference == mPointerLocation) {
-            writePointerLocationOptions();
-        } else if (preference == mShowTouches) {
-            writeShowTouchesOptions();
-        } else if (preference == mShowScreenUpdates) {
-            writeShowUpdatesOption();
-        } else if (preference == mDisableOverlays) {
-            writeDisableOverlaysOption();
-        } else if (preference == mImmediatelyDestroyActivities) {
-            writeImmediatelyDestroyActivitiesOptions();
-        } else if (preference == mShowAllANRs) {
-            writeShowAllANRsOptions();
-        } else if (preference == mShowNotificationChannelWarnings) {
-            writeShowNotificationChannelWarningsOptions();
-        } else if (preference == mForceHardwareUi) {
-            writeHardwareUiOptions();
-        } else if (preference == mForceMsaa) {
-            writeMsaaOptions();
-        } else if (preference == mShowHwScreenUpdates) {
-            writeShowHwScreenUpdatesOptions();
-        } else if (preference == mShowHwLayersUpdates) {
-            writeShowHwLayersUpdatesOptions();
-        } else if (preference == mDebugLayout) {
-            writeDebugLayoutOptions();
-        } else if (preference == mForceRtlLayout) {
-            writeForceRtlOptions();
-        } else if (preference == mWifiDisplayCertification) {
-            writeWifiDisplayCertificationOptions();
-        } else if (preference == mWifiVerboseLogging) {
-            writeWifiVerboseLoggingOptions();
-        } else if (preference == mWifiAggressiveHandover) {
-            writeWifiAggressiveHandoverOptions();
-        } else if (preference == mWifiAllowScansWithTraffic) {
-            writeWifiAllowScansWithTrafficOptions();
-        } else if (preference == mMobileDataAlwaysOn) {
-            writeMobileDataAlwaysOnOptions();
-        } else if (preference == mTetheringHardwareOffload) {
-            writeTetheringHardwareOffloadOptions();
-        } else if (preference == mColorTemperaturePreference) {
-            writeColorTemperature();
-        } else if (preference == mUSBAudio) {
-            writeUSBAudioOptions();
-        } else if (preference == mForceResizable) {
-            writeForceResizableOptions();
-        } else if (preference == mEnableFreeformSupport){
-            writeEnableFreeformWindowsSupportOptions();
-        } else if (preference == mBluetoothShowDevicesWithoutNames) {
-            writeBluetoothShowDevicesWithoutUserFriendlyNameOptions();
-        } else if (preference == mBluetoothDisableAbsVolume) {
-            writeBluetoothDisableAbsVolumeOptions();
-        } else if (preference == mBluetoothEnableInbandRinging) {
-            writeBluetoothEnableInbandRingingOptions();
-        } else if (SHORTCUT_MANAGER_RESET_KEY.equals(preference.getKey())) {
-            resetShortcutManagerThrottling();
-        } else {
-            return super.onPreferenceTreeClick(preference);
-        }
-
-        return false;
-    }
-
-    private boolean showKeyguardConfirmation(Resources resources, int requestCode) {
-        return new ChooseLockSettingsHelper(getActivity(), this).launchConfirmationActivity(
-                requestCode, resources.getString(R.string.oem_unlock_enable));
-    }
-
-    @Override
-    public boolean onPreferenceChange(Preference preference, Object newValue) {
-        if (HDCP_CHECKING_KEY.equals(preference.getKey())) {
-            SystemProperties.set(HDCP_CHECKING_PROPERTY, newValue.toString());
-            updateHdcpValues();
-            SystemPropPoker.getInstance().poke();
-            return true;
-        } else if (preference == mBluetoothSelectAvrcpVersion) {
-           writeBluetoothAvrcpVersion(newValue);
-           return true;
-        } else if ((preference == mBluetoothSelectA2dpCodec) ||
-                   (preference == mBluetoothSelectA2dpSampleRate) ||
-                   (preference == mBluetoothSelectA2dpBitsPerSample) ||
-                   (preference == mBluetoothSelectA2dpChannelMode) ||
-                   (preference == mBluetoothSelectA2dpLdacPlaybackQuality)) {
-            writeBluetoothConfigurationOption(preference, newValue);
-            return true;
-        } else if (preference == mUsbConfiguration) {
-            writeUsbConfigurationOption(newValue);
-            return true;
-        } else if (preference == mWindowAnimationScale) {
-            writeAnimationScaleOption(0, mWindowAnimationScale, newValue);
-            return true;
-        } else if (preference == mTransitionAnimationScale) {
-            writeAnimationScaleOption(1, mTransitionAnimationScale, newValue);
-            return true;
-        } else if (preference == mAnimatorDurationScale) {
-            writeAnimationScaleOption(2, mAnimatorDurationScale, newValue);
-            return true;
-        } else if (preference == mOverlayDisplayDevices) {
-            writeOverlayDisplayDevicesOptions(newValue);
-            return true;
-        } else if (preference == mTrackFrameTime) {
-            writeTrackFrameTimeOptions(newValue);
-            return true;
-        } else if (preference == mDebugHwOverdraw) {
-            writeDebugHwOverdrawOptions(newValue);
-            return true;
-        } else if (preference == mDebugHwRenderer) {
-            writeDebugHwRendererOptions(newValue);
-            return true;
-        } else if (preference == mShowNonRectClip) {
-            writeShowNonRectClipOptions(newValue);
-            return true;
-        } else if (preference == mAppProcessLimit) {
-            writeAppProcessLimitOptions(newValue);
-            return true;
-        } else if (preference == mSimulateColorSpace) {
-            writeSimulateColorSpace(newValue);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Iterates through preference controllers that show confirmation dialogs and returns the
-     * preference key for the first currently showing dialog. Ideally there should only ever be one.
-     * @return Preference key, or null if no dialog is showing
-     */
-    private String getKeyForShowingDialog() {
-        // TODO: iterate through a fragment-wide list of PreferenceControllers and just pick out the
-        // ConfirmationDialogController objects
-        final List<ConfirmationDialogController> dialogControllers = new ArrayList<>(2);
-        dialogControllers.add(mEnableAdbController);
-        dialogControllers.add(mLogpersistController);
-        for (ConfirmationDialogController dialogController : dialogControllers) {
-            if (dialogController.isConfirmationDialogShowing()) {
-                return dialogController.getPreferenceKey();
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Re-show the dialog we lost previously
-     * @param preferenceKey Key for the preference the dialog is for
-     */
-    private void recreateDialogForKey(String preferenceKey) {
-        // TODO: iterate through a fragment-wide list of PreferenceControllers and just pick out the
-        // ConfirmationDialogController objects
-        final List<ConfirmationDialogController> dialogControllers = new ArrayList<>(2);
-        dialogControllers.add(mEnableAdbController);
-        dialogControllers.add(mLogpersistController);
-        for (ConfirmationDialogController dialogController : dialogControllers) {
-            if (TextUtils.equals(preferenceKey, dialogController.getPreferenceKey())) {
-                dialogController.showConfirmationDialog(findPreference(preferenceKey));
-            }
-        }
-    }
-
-    private void dismissDialogs() {
-        mEnableAdbController.dismissConfirmationDialog();
-        if (mAdbKeysDialog != null) {
-            mAdbKeysDialog.dismiss();
-            mAdbKeysDialog = null;
-        }
-        if (mEnableDialog != null) {
-            mEnableDialog.dismiss();
-            mEnableDialog = null;
-        }
-        mLogpersistController.dismissConfirmationDialog();
-    }
-
-    public void onClick(DialogInterface dialog, int which) {
-        if (dialog == mAdbKeysDialog) {
-            if (which == DialogInterface.BUTTON_POSITIVE) {
-                try {
-                    IBinder b = ServiceManager.getService(Context.USB_SERVICE);
-                    IUsbManager service = IUsbManager.Stub.asInterface(b);
-                    service.clearUsbDebuggingKeys();
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Unable to clear adb keys", e);
-                }
-            }
-        } else if (dialog == mEnableDialog) {
-            if (which == DialogInterface.BUTTON_POSITIVE) {
-                mDialogClicked = true;
-                DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(getContext(), true);
-                setPrefsEnabledState(true);
-            } else {
-                // Reset the toggle
-                mSwitchBar.setChecked(false);
-            }
-        }
-    }
-
-    public void onDismiss(DialogInterface dialog) {
-        // Assuming that onClick gets called first
-        if (dialog == mEnableDialog) {
-            if (!mDialogClicked) {
-                mSwitchBar.setChecked(false);
-            }
-            mEnableDialog = null;
-        }
-    }
-
-    @Override
-    public void onDestroy() {
-        dismissDialogs();
-        super.onDestroy();
-    }
-
-    private BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            updateUsbConfigurationValues();
-        }
-    };
-
-    private BroadcastReceiver mBluetoothA2dpReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            Log.d(TAG, "mBluetoothA2dpReceiver.onReceive intent=" + intent);
-            String action = intent.getAction();
-
-            if (BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED.equals(action)) {
-                BluetoothCodecStatus codecStatus =
-                    (BluetoothCodecStatus)intent.getParcelableExtra(BluetoothCodecStatus.EXTRA_CODEC_STATUS);
-                Log.d(TAG, "Received BluetoothCodecStatus=" + codecStatus);
-                updateBluetoothA2dpConfigurationValues();
-            }
-        }
-    };
-
-    private BluetoothProfile.ServiceListener mBluetoothA2dpServiceListener =
-        new BluetoothProfile.ServiceListener() {
-            public void onServiceConnected(int profile,
-                                           BluetoothProfile proxy) {
-                synchronized (mBluetoothA2dpLock) {
-                    mBluetoothA2dp = (BluetoothA2dp) proxy;
-                }
-                updateBluetoothA2dpConfigurationValues();
-            }
-
-            public void onServiceDisconnected(int profile) {
-                synchronized (mBluetoothA2dpLock) {
-                    mBluetoothA2dp = null;
-                }
-                updateBluetoothA2dpConfigurationValues();
-            }
-        };
-
-    private static boolean isPackageInstalled(Context context, String packageName) {
-        try {
-            return context.getPackageManager().getPackageInfo(packageName, 0) != null;
-        } catch (NameNotFoundException e) {
-            return false;
-        }
-    }
-
-
-    /**
-     * For Search.
-     */
-    public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider() {
-
-                @Override
-                protected boolean isPageSearchEnabled(Context context) {
-                    return DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(context);
-                }
-
-                @Override
-                public List<SearchIndexableResource> getXmlResourcesToIndex(
-                        Context context, boolean enabled) {
-
-                    final SearchIndexableResource sir = new SearchIndexableResource(context);
-                    sir.xmlResId = R.xml.development_settings;
-                    return Arrays.asList(sir);
-                }
-
-                @Override
-                public List<String> getNonIndexableKeys(Context context) {
-                    final List<String> keys = super.getNonIndexableKeys(context);
-
-                    if (!showEnableOemUnlockPreference(context)) {
-                        keys.add(ENABLE_OEM_UNLOCK);
-                    }
-                    return keys;
-                }
-            };
-
-    private void resetShortcutManagerThrottling() {
-        final IShortcutService service = IShortcutService.Stub.asInterface(
-                ServiceManager.getService(Context.SHORTCUT_SERVICE));
-        if (service != null) {
-            try {
-                service.resetThrottling();
-                Toast.makeText(getActivity(), R.string.reset_shortcut_manager_throttling_complete,
-                        Toast.LENGTH_SHORT).show();
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to reset rate limiting", e);
-            }
-        }
-    }
-
-    private void updateOemUnlockSettingDescription() {
-        if (mEnableOemUnlock != null) {
-            int oemUnlockSummary = R.string.oem_unlock_enable_summary;
-            if (isBootloaderUnlocked()) {
-                oemUnlockSummary = R.string.oem_unlock_enable_disabled_summary_bootloader_unlocked;
-            } else if (isSimLockedDevice()) {
-                oemUnlockSummary = R.string.oem_unlock_enable_disabled_summary_sim_locked_device;
-            } else if (!isOemUnlockAllowedByUserAndCarrier()) {
-                // If the device isn't SIM-locked but OEM unlock is disallowed by some party, this
-                // means either some other carrier restriction is in place or the device hasn't been
-                // able to confirm which restrictions (SIM-lock or otherwise) apply.
-                oemUnlockSummary =
-                        R.string.oem_unlock_enable_disabled_summary_connectivity_or_locked;
-            }
-            mEnableOemUnlock.setSummary(getString(oemUnlockSummary));
-        }
-    }
-
-    /** Returns {@code true} if the device is SIM-locked. Otherwise, returns {@code false}. */
-    private boolean isSimLockedDevice() {
-        int phoneCount = mTelephonyManager.getPhoneCount();
-        for (int i = 0; i < phoneCount; i++) {
-            if (mTelephonyManager.getAllowedCarriers(i).size() > 0) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns {@code true} if the bootloader has been unlocked. Otherwise, returns {code false}.
-     */
-    private boolean isBootloaderUnlocked() {
-        return mOemLockManager.isDeviceOemUnlocked();
-    }
-
-
-}
diff --git a/src/com/android/settings/development/DevelopmentSwitchBarController.java b/src/com/android/settings/development/DevelopmentSwitchBarController.java
index ae875b3..79a8310 100644
--- a/src/com/android/settings/development/DevelopmentSwitchBarController.java
+++ b/src/com/android/settings/development/DevelopmentSwitchBarController.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.development;
 
+import android.support.annotation.NonNull;
+
 import com.android.settings.Utils;
 import com.android.settings.widget.SwitchBar;
 import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -28,33 +30,13 @@
 
     private final SwitchBar mSwitchBar;
     private final boolean mIsAvailable;
-    private final DevelopmentSettings mSettings;
-    private final DevelopmentSettingsDashboardFragment mNewSettings;
+    private final DevelopmentSettingsDashboardFragment mSettings;
 
-    /**
-     * @deprecated in favor of the other constructor.
-     */
-    @Deprecated
-    public DevelopmentSwitchBarController(DevelopmentSettings settings, SwitchBar switchBar,
-            boolean isAvailable, Lifecycle lifecycle) {
-        mSwitchBar = switchBar;
-        mIsAvailable = isAvailable && !Utils.isMonkeyRunning();
-        mSettings = settings;
-        mNewSettings = null;
-
-        if (mIsAvailable) {
-            lifecycle.addObserver(this);
-        } else {
-            mSwitchBar.setEnabled(false);
-        }
-    }
-
-    public DevelopmentSwitchBarController(DevelopmentSettingsDashboardFragment settings,
+    public DevelopmentSwitchBarController(@NonNull DevelopmentSettingsDashboardFragment settings,
             SwitchBar switchBar, boolean isAvailable, Lifecycle lifecycle) {
         mSwitchBar = switchBar;
         mIsAvailable = isAvailable && !Utils.isMonkeyRunning();
-        mSettings = null;
-        mNewSettings = settings;
+        mSettings = settings;
 
         if (mIsAvailable) {
             lifecycle.addObserver(this);
@@ -65,24 +47,14 @@
 
     @Override
     public void onStart() {
-        if (mSettings != null) {
-            mSwitchBar.addOnSwitchChangeListener(mSettings);
-        }
-        if (mNewSettings != null) {
-            final boolean developmentEnabledState = DevelopmentSettingsEnabler
-                    .isDevelopmentSettingsEnabled(mNewSettings.getContext());
-            mSwitchBar.setChecked(developmentEnabledState);
-            mSwitchBar.addOnSwitchChangeListener(mNewSettings);
-        }
+        final boolean developmentEnabledState = DevelopmentSettingsEnabler
+                .isDevelopmentSettingsEnabled(mSettings.getContext());
+        mSwitchBar.setChecked(developmentEnabledState);
+        mSwitchBar.addOnSwitchChangeListener(mSettings);
     }
 
     @Override
     public void onStop() {
-        if (mSettings != null) {
-            mSwitchBar.removeOnSwitchChangeListener(mSettings);
-        }
-        if (mNewSettings != null) {
-            mSwitchBar.removeOnSwitchChangeListener(mNewSettings);
-        }
+        mSwitchBar.removeOnSwitchChangeListener(mSettings);
     }
 }
diff --git a/src/com/android/settings/development/EnableAdbPreferenceController.java b/src/com/android/settings/development/EnableAdbPreferenceController.java
deleted file mode 100644
index a866353..0000000
--- a/src/com/android/settings/development/EnableAdbPreferenceController.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.development;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.support.annotation.Nullable;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.TwoStatePreference;
-
-import com.android.settings.R;
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.development.AbstractEnableAdbPreferenceController;
-
-/**
- * @deprecated in favor of {@link AdbPreferenceController}
- */
-@Deprecated
-public class EnableAdbPreferenceController extends AbstractEnableAdbPreferenceController
-        implements PreferenceControllerMixin {
-
-    private Dialog mAdbDialog;
-    private boolean mDialogClicked;
-
-    public EnableAdbPreferenceController(Context context) {
-        super(context);
-    }
-
-    @Override
-    public void showConfirmationDialog(@Nullable Preference preference) {
-        if (preference == null) {
-            return;
-        }
-        final TwoStatePreference twoStatePreference = (TwoStatePreference) preference;
-        mDialogClicked = false;
-        dismissConfirmationDialog();
-        mAdbDialog = new AlertDialog.Builder(mContext).setMessage(
-                mContext.getString(R.string.adb_warning_message))
-                .setTitle(R.string.adb_warning_title)
-                .setPositiveButton(android.R.string.yes, (dialog, which) -> {
-                    mDialogClicked = true;
-                    writeAdbSetting(true);
-                    twoStatePreference.setChecked(true);
-                })
-                .setNegativeButton(android.R.string.no,
-                        (dialog, which) -> twoStatePreference.setChecked(false))
-                .show();
-        mAdbDialog.setOnDismissListener(dialog -> {
-            // Assuming that onClick gets called first
-            if (!mDialogClicked) {
-                twoStatePreference.setChecked(false);
-            }
-            mAdbDialog = null;
-        });
-    }
-
-    @Override
-    public void dismissConfirmationDialog() {
-        if (mAdbDialog != null) {
-            mAdbDialog.dismiss();
-            mAdbDialog = null;
-        }
-    }
-
-    @Override
-    public boolean isConfirmationDialogShowing() {
-        return mAdbDialog != null;
-    }
-}
diff --git a/src/com/android/settings/development/LogdSizePreferenceController.java b/src/com/android/settings/development/LogdSizePreferenceController.java
deleted file mode 100644
index 8ee3405..0000000
--- a/src/com/android/settings/development/LogdSizePreferenceController.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.development;
-
-import android.content.Context;
-
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.development.AbstractLogdSizePreferenceController;
-
-/**
- * deprecated in favor of {@link LogdSizePreferenceControllerV2}
- */
-@Deprecated
-public class LogdSizePreferenceController extends AbstractLogdSizePreferenceController
-        implements PreferenceControllerMixin {
-
-    public LogdSizePreferenceController(Context context) {
-        super(context);
-    }
-}
diff --git a/src/com/android/settings/development/LogpersistPreferenceController.java b/src/com/android/settings/development/LogpersistPreferenceController.java
deleted file mode 100644
index 26ab878..0000000
--- a/src/com/android/settings/development/LogpersistPreferenceController.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.development;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.support.annotation.Nullable;
-import android.support.v7.preference.Preference;
-
-import com.android.settings.R;
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.development.AbstractLogpersistPreferenceController;
-
-/**
- * depreacted in favor of {@link LogdSizePreferenceControllerV2}
- */
-@Deprecated
-public class LogpersistPreferenceController extends AbstractLogpersistPreferenceController
-        implements PreferenceControllerMixin {
-
-    private Dialog mLogpersistClearDialog;
-
-    LogpersistPreferenceController(Context context, Lifecycle lifecycle) {
-        super(context, lifecycle);
-    }
-
-    @Override
-    public void showConfirmationDialog(@Nullable Preference preference) {
-        if (preference == null) {
-            return;
-        }
-        if (mLogpersistClearDialog != null) dismissConfirmationDialog();
-        mLogpersistClearDialog = new AlertDialog.Builder(mContext)
-                .setMessage(R.string.dev_logpersist_clear_warning_message)
-                .setTitle(R.string.dev_logpersist_clear_warning_title)
-                .setPositiveButton(android.R.string.yes, (dialog, which) -> setLogpersistOff(true))
-                .setNegativeButton(android.R.string.no, (dialog, which) -> updateLogpersistValues())
-                .show();
-        mLogpersistClearDialog.setOnDismissListener(dialog -> mLogpersistClearDialog = null);
-    }
-
-    @Override
-    public void dismissConfirmationDialog() {
-        if (mLogpersistClearDialog != null) {
-            mLogpersistClearDialog.dismiss();
-            mLogpersistClearDialog = null;
-        }
-    }
-
-    @Override
-    public boolean isConfirmationDialogShowing() {
-        return mLogpersistClearDialog != null;
-    }
-}
diff --git a/src/com/android/settings/development/VerifyAppsOverUsbPreferenceController.java b/src/com/android/settings/development/VerifyAppsOverUsbPreferenceController.java
deleted file mode 100644
index 4fd7fbc..0000000
--- a/src/com/android/settings/development/VerifyAppsOverUsbPreferenceController.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.settings.development;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.support.annotation.VisibleForTesting;
-import android.support.v7.preference.Preference;
-import android.support.v7.preference.PreferenceScreen;
-
-import com.android.settings.core.PreferenceControllerMixin;
-import com.android.settingslib.RestrictedLockUtils;
-import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-import com.android.settingslib.RestrictedSwitchPreference;
-import com.android.settingslib.core.AbstractPreferenceController;
-
-import java.util.List;
-
-/**
- * Controller to manage the state of "Verify apps over USB" toggle.
- *
- * deprecated in favor of {@link VerifyAppsOverUsbPreferenceControllerV2}
- */
-@Deprecated
-public class VerifyAppsOverUsbPreferenceController extends AbstractPreferenceController implements
-        PreferenceControllerMixin {
-    private static final String VERIFY_APPS_OVER_USB_KEY = "verify_apps_over_usb";
-    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
-
-    private RestrictedSwitchPreference mPreference;
-
-    /**
-     * Class for indirection of RestrictedLockUtils for testing purposes. It would be nice to mock
-     * the appropriate methods in UserManager instead but they aren't accessible.
-     */
-    @VisibleForTesting
-    class RestrictedLockUtilsDelegate {
-        public EnforcedAdmin checkIfRestrictionEnforced(
-                Context context, String userRestriction, int userId) {
-            return RestrictedLockUtils.checkIfRestrictionEnforced(context, userRestriction, userId);
-        }
-    }
-    // NB: This field is accessed using reflection in the test, please keep name in sync.
-    private final RestrictedLockUtilsDelegate mRestrictedLockUtils =
-            new RestrictedLockUtilsDelegate();
-
-    VerifyAppsOverUsbPreferenceController(Context context) {
-        super(context);
-    }
-
-    @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        if (isAvailable()) {
-            mPreference = (RestrictedSwitchPreference)
-                    screen.findPreference(VERIFY_APPS_OVER_USB_KEY);
-        }
-    }
-
-    @Override
-    public boolean isAvailable() {
-        return Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.PACKAGE_VERIFIER_SETTING_VISIBLE, 1) > 0;
-    }
-
-    @Override
-    public String getPreferenceKey() {
-        return VERIFY_APPS_OVER_USB_KEY;
-    }
-
-    /** Saves the settings value when it is toggled. */
-    @Override
-    public boolean handlePreferenceTreeClick(Preference preference) {
-        if (VERIFY_APPS_OVER_USB_KEY.equals(preference.getKey())) {
-            Settings.Global.putInt(mContext.getContentResolver(),
-                    Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, mPreference.isChecked() ? 1 : 0);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Checks whether the toggle should be enabled depending on whether verify apps over USB is
-     * possible currently. If ADB is disabled or if package verifier does not exist, the toggle
-     * should be disabled.
-     */
-    private boolean shouldBeEnabled() {
-        final ContentResolver cr = mContext.getContentResolver();
-        if (Settings.Global.getInt(cr, Settings.Global.ADB_ENABLED, 0) == 0) {
-            return false;
-        }
-        if (Settings.Global.getInt(cr, Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 0) {
-            return false;
-        } else {
-            final PackageManager pm = mContext.getPackageManager();
-            final Intent verification = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
-            verification.setType(PACKAGE_MIME_TYPE);
-            verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-            final List<ResolveInfo> receivers = pm.queryBroadcastReceivers(verification, 0);
-            if (receivers.size() == 0) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Updates position, enabled status and maybe admin message.
-     */
-    public void updatePreference() {
-        if (!isAvailable()) {
-            return;
-        }
-
-        if (!shouldBeEnabled()) {
-            mPreference.setChecked(false);
-            mPreference.setDisabledByAdmin(null);
-            mPreference.setEnabled(false);
-            return;
-        }
-
-        final EnforcedAdmin enforcingAdmin = mRestrictedLockUtils.checkIfRestrictionEnforced(
-                        mContext, UserManager.ENSURE_VERIFY_APPS, UserHandle.myUserId());
-        if (enforcingAdmin != null) {
-            mPreference.setChecked(true);
-            mPreference.setDisabledByAdmin(enforcingAdmin);
-            return;
-        }
-
-        mPreference.setEnabled(true);
-        final boolean checked = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) != 0;
-        mPreference.setChecked(checked);
-    }
-}
