Sound + Output Switcher on Sound Setting

1. Show "play media to" item when Previously Connected device is available
2. Click "Play media to" to launch output slice
3. Update test case

Bug: 126475101
Test: make -j50 RunSettingsRoboTests
Change-Id: Id8afd1a2407acb78c11e81d2420ae8c16130a321
This commit is contained in:
timhypeng
2019-03-04 16:32:47 +08:00
committed by tim peng
parent 94240c5a52
commit abdf739071
8 changed files with 350 additions and 522 deletions

View File

@@ -32,7 +32,6 @@ import android.media.MediaRouter;
import android.media.MediaRouter.Callback;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.FeatureFlagUtils;
import android.util.Log;
@@ -40,7 +39,6 @@ import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.bluetooth.Utils;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.FeatureFlags;
@@ -63,15 +61,11 @@ import java.util.concurrent.FutureTask;
/**
* Abstract class for audio switcher controller to notify subclass
* updating the current status of switcher entry. Subclasses must overwrite
* {@link #setActiveBluetoothDevice(BluetoothDevice)} to set the
* active device for corresponding profile.
*/
public abstract class AudioSwitchPreferenceController extends BasePreferenceController
implements Preference.OnPreferenceChangeListener, BluetoothCallback,
LifecycleObserver, OnStart, OnStop {
implements BluetoothCallback, LifecycleObserver, OnStart, OnStop {
private static final String TAG = "AudioSwitchPrefCtrl";
private static final int INVALID_INDEX = -1;
protected final List<BluetoothDevice> mConnectedDevices;
protected final AudioManager mAudioManager;
@@ -128,35 +122,6 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final String address = (String) newValue;
if (!(preference instanceof ListPreference)) {
return false;
}
final ListPreference listPreference = (ListPreference) preference;
if (TextUtils.equals(address, mContext.getText(R.string.media_output_default_summary))) {
// Switch to default device which address is device name
mSelectedIndex = getDefaultDeviceIndex();
setActiveBluetoothDevice(null);
listPreference.setSummary(mContext.getText(R.string.media_output_default_summary));
} else {
// Switch to BT device which address is hardware address
final int connectedDeviceIndex = getConnectedDeviceIndex(address);
if (connectedDeviceIndex == INVALID_INDEX) {
return false;
}
final BluetoothDevice btDevice = mConnectedDevices.get(connectedDeviceIndex);
mSelectedIndex = connectedDeviceIndex;
setActiveBluetoothDevice(btDevice);
listPreference.setSummary(btDevice.getAliasName());
}
return true;
}
public abstract void setActiveBluetoothDevice(BluetoothDevice device);
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
@@ -184,6 +149,12 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont
unregister();
}
@Override
public void onBluetoothStateChanged(int bluetoothState) {
// To handle the case that Bluetooth on and no connected devices
updateState(mPreference);
}
@Override
public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {
updateState(mPreference);
@@ -236,21 +207,15 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont
}
/**
* get A2dp connected device
* get A2dp devices on all states
* (STATE_DISCONNECTED, STATE_CONNECTING, STATE_CONNECTED, STATE_DISCONNECTING)
*/
protected List<BluetoothDevice> getConnectedA2dpDevices() {
final List<BluetoothDevice> connectedDevices = new ArrayList<>();
protected List<BluetoothDevice> getConnectableA2dpDevices() {
final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
if (a2dpProfile == null) {
return connectedDevices;
return new ArrayList<>();
}
final List<BluetoothDevice> devices = a2dpProfile.getConnectedDevices();
for (BluetoothDevice device : devices) {
if (device.isConnected()) {
connectedDevices.add(device);
}
}
return connectedDevices;
return a2dpProfile.getConnectableDevices();
}
/**
@@ -276,6 +241,31 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont
return connectedDevices;
}
/**
* get hearing aid profile devices on all states
* (STATE_DISCONNECTED, STATE_CONNECTING, STATE_CONNECTED, STATE_DISCONNECTING)
* exclude other devices with same hiSyncId.
*/
protected List<BluetoothDevice> getConnectableHearingAidDevices() {
final List<BluetoothDevice> connectedDevices = new ArrayList<>();
final HearingAidProfile hapProfile = mProfileManager.getHearingAidProfile();
if (hapProfile == null) {
return connectedDevices;
}
final List<Long> devicesHiSyncIds = new ArrayList<>();
final List<BluetoothDevice> devices = hapProfile.getConnectableDevices();
for (BluetoothDevice device : devices) {
final long hiSyncId = hapProfile.getHiSyncId(device);
// device with same hiSyncId should not be shown in the UI.
// So do not add it into connectedDevices.
if (!devicesHiSyncIds.contains(hiSyncId)) {
devicesHiSyncIds.add(hiSyncId);
connectedDevices.add(device);
}
}
return connectedDevices;
}
/**
* Find active hearing aid device
*/
@@ -306,52 +296,6 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont
*/
public abstract BluetoothDevice findActiveDevice();
int getDefaultDeviceIndex() {
// Default device is after all connected devices.
return mConnectedDevices.size();
}
void setupPreferenceEntries(CharSequence[] mediaOutputs, CharSequence[] mediaValues,
BluetoothDevice activeDevice) {
// default to current device
mSelectedIndex = getDefaultDeviceIndex();
// default device is after all connected devices.
mediaOutputs[mSelectedIndex] = mContext.getText(R.string.media_output_default_summary);
// use default device name as address
mediaValues[mSelectedIndex] = mContext.getText(R.string.media_output_default_summary);
for (int i = 0, size = mConnectedDevices.size(); i < size; i++) {
final BluetoothDevice btDevice = mConnectedDevices.get(i);
mediaOutputs[i] = btDevice.getAliasName();
mediaValues[i] = btDevice.getAddress();
if (btDevice.equals(activeDevice)) {
// select the active connected device.
mSelectedIndex = i;
}
}
}
void setPreference(CharSequence[] mediaOutputs, CharSequence[] mediaValues,
Preference preference) {
final ListPreference listPreference = (ListPreference) preference;
listPreference.setEntries(mediaOutputs);
listPreference.setEntryValues(mediaValues);
listPreference.setValueIndex(mSelectedIndex);
listPreference.setSummary(mediaOutputs[mSelectedIndex]);
mAudioSwitchPreferenceCallback.onPreferenceDataChanged(listPreference);
}
private int getConnectedDeviceIndex(String hardwareAddress) {
if (mConnectedDevices != null) {
for (int i = 0, size = mConnectedDevices.size(); i < size; i++) {
final BluetoothDevice btDevice = mConnectedDevices.get(i);
if (TextUtils.equals(btDevice.getAddress(), hardwareAddress)) {
return i;
}
}
}
return INVALID_INDEX;
}
private void register() {
mLocalBluetoothManager.getEventManager().registerCallback(this);
mAudioManager.registerAudioDeviceCallback(mAudioManagerAudioDeviceCallback, mHandler);