Split BluetoothSettings into two pages
This cl splits the BluetoothSettings into paired device page and pairing page, including small changes about: 1. Refactor the pages so they could get as much as static preference from xml file rather than dynamically add/remove them everytime. 2. Remove creating method in BluetoothDeviceNamePreferenceController and add it in xml file 3. Create BluetoothPairingDetail page, basically move the logic from BluetoothSettings. 4. Make pairing preference clickable and jump to BluetoothPairingDetail 5. Add and update bunch of tests Bug: 35877041 Test: RunSettingsRoboTests Change-Id: Ief9e9690c612f7b46c58e866e5cecc511af642c8
This commit is contained in:
@@ -19,7 +19,6 @@ package com.android.settings.bluetooth;
|
||||
import android.app.Activity;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -29,10 +28,8 @@ import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceCategory;
|
||||
import android.support.v7.preference.PreferenceGroup;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.text.BidiFormatter;
|
||||
import android.text.Spannable;
|
||||
import android.text.style.TextAppearanceSpan;
|
||||
import android.util.Log;
|
||||
@@ -74,11 +71,9 @@ import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
|
||||
* connection management.
|
||||
*
|
||||
*/
|
||||
// TODO: Refactor this fragment
|
||||
public class BluetoothSettings extends DeviceListPreferenceFragment implements Indexable {
|
||||
private static final String TAG = "BluetoothSettings";
|
||||
|
||||
private static final int MENU_ID_SCAN = Menu.FIRST;
|
||||
private static final int MENU_ID_SHOW_RECEIVED = Menu.FIRST + 1;
|
||||
|
||||
/* Private intent to show the list of received files */
|
||||
@@ -87,47 +82,32 @@ public class BluetoothSettings extends DeviceListPreferenceFragment implements I
|
||||
private static final String BTOPP_PACKAGE =
|
||||
"com.android.bluetooth";
|
||||
|
||||
private static final String KEY_PAIRED_DEVICES = "paired_devices";
|
||||
private static final int PAIRED_DEVICE_ORDER = 1;
|
||||
private static final int PAIRING_PREF_ORDER = 2;
|
||||
|
||||
private static View mSettingsDialogView = null;
|
||||
@VisibleForTesting
|
||||
static final String KEY_PAIRED_DEVICES = "paired_devices";
|
||||
@VisibleForTesting
|
||||
static final String KEY_FOOTER_PREF = "footer_preference";
|
||||
|
||||
private BluetoothEnabler mBluetoothEnabler;
|
||||
|
||||
private PreferenceGroup mPairedDevicesCategory;
|
||||
private PreferenceGroup mAvailableDevicesCategory;
|
||||
private Preference mDeviceNamePreference;
|
||||
@VisibleForTesting
|
||||
PreferenceGroup mPairedDevicesCategory;
|
||||
@VisibleForTesting
|
||||
FooterPreference mFooterPreference;
|
||||
private Preference mPairingPreference;
|
||||
private boolean mAvailableDevicesCategoryIsPresent;
|
||||
|
||||
private boolean mInitialScanStarted;
|
||||
private boolean mInitiateDiscoverable;
|
||||
private BluetoothEnabler mBluetoothEnabler;
|
||||
|
||||
private SwitchBar mSwitchBar;
|
||||
|
||||
private final IntentFilter mIntentFilter;
|
||||
private BluetoothDeviceNamePreferenceController mDeviceNamePrefController;
|
||||
private BluetoothPairingPreferenceController mPairingPrefController;
|
||||
@VisibleForTesting
|
||||
BluetoothPairingPreferenceController mPairingPrefController;
|
||||
|
||||
// For Search
|
||||
@VisibleForTesting
|
||||
static final String DATA_KEY_REFERENCE = "main_toggle_bluetooth";
|
||||
|
||||
// accessed from inner class (not private to avoid thunks)
|
||||
FooterPreference mMyDevicePreference;
|
||||
|
||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
final String action = intent.getAction();
|
||||
final int state =
|
||||
intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
|
||||
|
||||
if (state == BluetoothAdapter.STATE_ON) {
|
||||
mInitiateDiscoverable = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public BluetoothSettings() {
|
||||
super(DISALLOW_CONFIG_BLUETOOTH);
|
||||
mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
|
||||
@@ -141,15 +121,13 @@ public class BluetoothSettings extends DeviceListPreferenceFragment implements I
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
mInitialScanStarted = false;
|
||||
mInitiateDiscoverable = true;
|
||||
|
||||
final SettingsActivity activity = (SettingsActivity) getActivity();
|
||||
mSwitchBar = activity.getSwitchBar();
|
||||
|
||||
mBluetoothEnabler = new BluetoothEnabler(activity, new SwitchBarController(mSwitchBar),
|
||||
mMetricsFeatureProvider, Utils.getLocalBtManager(activity),
|
||||
MetricsEvent.ACTION_BLUETOOTH_TOGGLE);
|
||||
mMetricsFeatureProvider, Utils.getLocalBtManager(activity),
|
||||
MetricsEvent.ACTION_BLUETOOTH_TOGGLE);
|
||||
mBluetoothEnabler.setupSwitchController();
|
||||
}
|
||||
|
||||
@@ -161,28 +139,11 @@ public class BluetoothSettings extends DeviceListPreferenceFragment implements I
|
||||
}
|
||||
|
||||
@Override
|
||||
void addPreferencesForActivity() {
|
||||
final Context prefContext = getPrefContext();
|
||||
|
||||
mDeviceNamePreference = mDeviceNamePrefController.createBluetoothDeviceNamePreference(
|
||||
getPreferenceScreen(), 1 /* order */);
|
||||
|
||||
mPairedDevicesCategory = new PreferenceCategory(prefContext);
|
||||
mPairedDevicesCategory.setKey(KEY_PAIRED_DEVICES);
|
||||
mPairedDevicesCategory.setOrder(2);
|
||||
getPreferenceScreen().addPreference(mPairedDevicesCategory);
|
||||
|
||||
mAvailableDevicesCategory = new BluetoothProgressCategory(prefContext);
|
||||
mAvailableDevicesCategory.setSelectable(false);
|
||||
mAvailableDevicesCategory.setOrder(3);
|
||||
getPreferenceScreen().addPreference(mAvailableDevicesCategory);
|
||||
|
||||
mMyDevicePreference = mFooterPreferenceMixin.createFooterPreference();
|
||||
mMyDevicePreference.setSelectable(false);
|
||||
|
||||
mPairingPreference = mPairingPrefController.createBluetoothPairingPreference();
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
void initPreferencesFromPreferenceScreen() {
|
||||
mPairingPreference = mPairingPrefController.createBluetoothPairingPreference(
|
||||
PAIRING_PREF_ORDER);
|
||||
mFooterPreference = (FooterPreference) findPreference(KEY_FOOTER_PREF);
|
||||
mPairedDevicesCategory = (PreferenceGroup) findPreference(KEY_PAIRED_DEVICES);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -193,19 +154,14 @@ public class BluetoothSettings extends DeviceListPreferenceFragment implements I
|
||||
mBluetoothEnabler.resume(getActivity());
|
||||
}
|
||||
super.onStart();
|
||||
|
||||
mInitiateDiscoverable = true;
|
||||
|
||||
if (isUiRestricted()) {
|
||||
setDeviceListGroup(getPreferenceScreen());
|
||||
getPreferenceScreen().removeAll();
|
||||
if (!isUiRestrictedByOnlyAdmin()) {
|
||||
getEmptyTextView().setText(R.string.bluetooth_empty_list_user_restricted);
|
||||
}
|
||||
removeAllDevices();
|
||||
return;
|
||||
}
|
||||
|
||||
getActivity().registerReceiver(mReceiver, mIntentFilter);
|
||||
if (mLocalAdapter != null) {
|
||||
updateContent(mLocalAdapter.getBluetoothState());
|
||||
}
|
||||
@@ -224,8 +180,6 @@ public class BluetoothSettings extends DeviceListPreferenceFragment implements I
|
||||
if (isUiRestricted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
getActivity().unregisterReceiver(mReceiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -234,13 +188,6 @@ public class BluetoothSettings extends DeviceListPreferenceFragment implements I
|
||||
// If the user is not allowed to configure bluetooth, do not show the menu.
|
||||
if (isUiRestricted()) return;
|
||||
|
||||
boolean bluetoothIsEnabled = mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON;
|
||||
boolean isDiscovering = mLocalAdapter.isDiscovering();
|
||||
int textId = isDiscovering ? R.string.bluetooth_searching_for_devices :
|
||||
R.string.bluetooth_search_for_devices;
|
||||
menu.add(Menu.NONE, MENU_ID_SCAN, 0, textId)
|
||||
.setEnabled(bluetoothIsEnabled && !isDiscovering)
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
|
||||
menu.add(Menu.NONE, MENU_ID_SHOW_RECEIVED, 0, R.string.bluetooth_show_received_files)
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
@@ -249,14 +196,6 @@ public class BluetoothSettings extends DeviceListPreferenceFragment implements I
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case MENU_ID_SCAN:
|
||||
if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON) {
|
||||
mMetricsFeatureProvider.action(getActivity(),
|
||||
MetricsEvent.ACTION_BLUETOOTH_SCAN);
|
||||
startScanning();
|
||||
}
|
||||
return true;
|
||||
|
||||
case MENU_ID_SHOW_RECEIVED:
|
||||
mMetricsFeatureProvider.action(getActivity(),
|
||||
MetricsEvent.ACTION_BLUETOOTH_FILES);
|
||||
@@ -268,104 +207,37 @@ public class BluetoothSettings extends DeviceListPreferenceFragment implements I
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void startScanning() {
|
||||
if (isUiRestricted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mAvailableDevicesCategoryIsPresent) {
|
||||
getPreferenceScreen().addPreference(mAvailableDevicesCategory);
|
||||
mAvailableDevicesCategoryIsPresent = true;
|
||||
}
|
||||
|
||||
if (mAvailableDevicesCategory != null) {
|
||||
setDeviceListGroup(mAvailableDevicesCategory);
|
||||
removeAllDevices();
|
||||
}
|
||||
|
||||
mLocalManager.getCachedDeviceManager().clearNonBondedDevices();
|
||||
mAvailableDevicesCategory.removeAll();
|
||||
mInitialScanStarted = true;
|
||||
mLocalAdapter.startScanning(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
void onDevicePreferenceClick(BluetoothDevicePreference btPreference) {
|
||||
mLocalAdapter.stopScanning();
|
||||
super.onDevicePreferenceClick(btPreference);
|
||||
}
|
||||
|
||||
private void addDeviceCategory(PreferenceGroup preferenceGroup, int titleId,
|
||||
BluetoothDeviceFilter.Filter filter, boolean addCachedDevices) {
|
||||
cacheRemoveAllPrefs(preferenceGroup);
|
||||
preferenceGroup.setTitle(titleId);
|
||||
setFilter(filter);
|
||||
setDeviceListGroup(preferenceGroup);
|
||||
if (addCachedDevices) {
|
||||
addCachedDevices();
|
||||
}
|
||||
preferenceGroup.setEnabled(true);
|
||||
removeCachedPrefs(preferenceGroup);
|
||||
public String getDeviceListKey() {
|
||||
return KEY_PAIRED_DEVICES;
|
||||
}
|
||||
|
||||
private void updateContent(int bluetoothState) {
|
||||
final PreferenceScreen preferenceScreen = getPreferenceScreen();
|
||||
int messageId = 0;
|
||||
|
||||
switch (bluetoothState) {
|
||||
case BluetoothAdapter.STATE_ON:
|
||||
displayEmptyMessage(false);
|
||||
mDevicePreferenceMap.clear();
|
||||
|
||||
if (isUiRestricted()) {
|
||||
messageId = R.string.bluetooth_empty_list_user_restricted;
|
||||
break;
|
||||
}
|
||||
getPreferenceScreen().removeAll();
|
||||
getPreferenceScreen().addPreference(mDeviceNamePreference);
|
||||
getPreferenceScreen().addPreference(mPairedDevicesCategory);
|
||||
getPreferenceScreen().addPreference(mAvailableDevicesCategory);
|
||||
getPreferenceScreen().addPreference(mMyDevicePreference);
|
||||
|
||||
// Paired devices category
|
||||
addDeviceCategory(mPairedDevicesCategory,
|
||||
R.string.bluetooth_preference_paired_devices,
|
||||
BluetoothDeviceFilter.BONDED_DEVICE_FILTER, true);
|
||||
mPairedDevicesCategory.addPreference(mPairingPreference);
|
||||
int numberOfPairedDevices = mPairedDevicesCategory.getPreferenceCount();
|
||||
updateFooterPreference(mFooterPreference);
|
||||
|
||||
if (isUiRestricted() || numberOfPairedDevices <= 0) {
|
||||
if (preferenceScreen.findPreference(KEY_PAIRED_DEVICES) != null) {
|
||||
preferenceScreen.removePreference(mPairedDevicesCategory);
|
||||
}
|
||||
} else {
|
||||
if (preferenceScreen.findPreference(KEY_PAIRED_DEVICES) == null) {
|
||||
preferenceScreen.addPreference(mPairedDevicesCategory);
|
||||
}
|
||||
}
|
||||
|
||||
// Available devices category
|
||||
addDeviceCategory(mAvailableDevicesCategory,
|
||||
R.string.bluetooth_preference_found_devices,
|
||||
BluetoothDeviceFilter.UNBONDED_DEVICE_FILTER, mInitialScanStarted);
|
||||
|
||||
if (!mInitialScanStarted) {
|
||||
startScanning();
|
||||
}
|
||||
|
||||
updateMyDevicePreference(mMyDevicePreference);
|
||||
getActivity().invalidateOptionsMenu();
|
||||
|
||||
// mLocalAdapter.setScanMode is internally synchronized so it is okay for multiple
|
||||
// threads to execute.
|
||||
if (mInitiateDiscoverable) {
|
||||
// Make the device visible to other devices.
|
||||
mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
|
||||
mInitiateDiscoverable = false;
|
||||
}
|
||||
mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
|
||||
return; // not break
|
||||
|
||||
case BluetoothAdapter.STATE_TURNING_OFF:
|
||||
messageId = R.string.bluetooth_turning_off;
|
||||
mLocalAdapter.stopScanning();
|
||||
break;
|
||||
|
||||
case BluetoothAdapter.STATE_OFF:
|
||||
@@ -377,12 +249,10 @@ public class BluetoothSettings extends DeviceListPreferenceFragment implements I
|
||||
|
||||
case BluetoothAdapter.STATE_TURNING_ON:
|
||||
messageId = R.string.bluetooth_turning_on;
|
||||
mInitialScanStarted = false;
|
||||
break;
|
||||
}
|
||||
|
||||
setDeviceListGroup(preferenceScreen);
|
||||
removeAllDevices();
|
||||
displayEmptyMessage(true);
|
||||
if (messageId != 0) {
|
||||
getEmptyTextView().setText(messageId);
|
||||
}
|
||||
@@ -421,18 +291,21 @@ public class BluetoothSettings extends DeviceListPreferenceFragment implements I
|
||||
}
|
||||
});
|
||||
}
|
||||
getPreferenceScreen().removeAll();
|
||||
setTextSpan(emptyView.getText(), briefText);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void displayEmptyMessage(boolean display) {
|
||||
final Activity activity = getActivity();
|
||||
activity.findViewById(android.R.id.list_container).setVisibility(
|
||||
display ? View.INVISIBLE : View.VISIBLE);
|
||||
activity.findViewById(android.R.id.empty).setVisibility(
|
||||
display ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBluetoothStateChanged(int bluetoothState) {
|
||||
super.onBluetoothStateChanged(bluetoothState);
|
||||
// If BT is turned off/on staying in the same BT Settings screen
|
||||
// discoverability to be set again
|
||||
if (BluetoothAdapter.STATE_ON == bluetoothState) {
|
||||
mInitiateDiscoverable = true;
|
||||
}
|
||||
updateContent(bluetoothState);
|
||||
}
|
||||
|
||||
@@ -440,15 +313,14 @@ public class BluetoothSettings extends DeviceListPreferenceFragment implements I
|
||||
public void onScanningStateChanged(boolean started) {
|
||||
super.onScanningStateChanged(started);
|
||||
// Update options' enabled state
|
||||
if (getActivity() != null) {
|
||||
getActivity().invalidateOptionsMenu();
|
||||
final Activity activity = getActivity();
|
||||
if (activity != null) {
|
||||
activity.invalidateOptionsMenu();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
|
||||
setDeviceListGroup(getPreferenceScreen());
|
||||
removeAllDevices();
|
||||
updateContent(mLocalAdapter.getBluetoothState());
|
||||
}
|
||||
|
||||
@@ -457,20 +329,11 @@ public class BluetoothSettings extends DeviceListPreferenceFragment implements I
|
||||
if (text instanceof Spannable) {
|
||||
Spannable boldSpan = (Spannable) text;
|
||||
boldSpan.setSpan(
|
||||
new TextAppearanceSpan(getActivity(), android.R.style.TextAppearance_Medium), 0,
|
||||
briefText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
new TextAppearanceSpan(getActivity(), android.R.style.TextAppearance_Medium), 0,
|
||||
briefText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void updateMyDevicePreference(Preference myDevicePreference) {
|
||||
final BidiFormatter bidiFormatter = BidiFormatter.getInstance();
|
||||
|
||||
myDevicePreference.setTitle(getString(
|
||||
R.string.bluetooth_footer_mac_message,
|
||||
bidiFormatter.unicodeWrap(mLocalAdapter.getAddress())));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setLocalBluetoothAdapter(LocalBluetoothAdapter localAdapter) {
|
||||
mLocalAdapter = localAdapter;
|
||||
@@ -504,6 +367,7 @@ public class BluetoothSettings extends DeviceListPreferenceFragment implements I
|
||||
*/
|
||||
@Override
|
||||
void initDevicePreference(BluetoothDevicePreference preference) {
|
||||
preference.setOrder(PAIRED_DEVICE_ORDER);
|
||||
CachedBluetoothDevice cachedDevice = preference.getCachedDevice();
|
||||
if (cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
|
||||
// Only paired device have an associated advanced settings screen
|
||||
@@ -531,7 +395,8 @@ public class BluetoothSettings extends DeviceListPreferenceFragment implements I
|
||||
List<PreferenceController> controllers = new ArrayList<>();
|
||||
mDeviceNamePrefController = new BluetoothDeviceNamePreferenceController(context,
|
||||
this, getLifecycle());
|
||||
mPairingPrefController = new BluetoothPairingPreferenceController(context, this);
|
||||
mPairingPrefController = new BluetoothPairingPreferenceController(context, this,
|
||||
(SettingsActivity) getActivity());
|
||||
controllers.add(mDeviceNamePrefController);
|
||||
controllers.add(mPairingPrefController);
|
||||
|
||||
|
Reference in New Issue
Block a user