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:
@@ -41,7 +41,7 @@
|
|||||||
settings:controller="com.android.settings.notification.MediaVolumePreferenceController"/>
|
settings:controller="com.android.settings.notification.MediaVolumePreferenceController"/>
|
||||||
|
|
||||||
<!-- Media output switcher -->
|
<!-- Media output switcher -->
|
||||||
<ListPreference
|
<Preference
|
||||||
android:key="media_output"
|
android:key="media_output"
|
||||||
android:title="@string/media_output_title"
|
android:title="@string/media_output_title"
|
||||||
android:dialogTitle="@string/media_output_title"
|
android:dialogTitle="@string/media_output_title"
|
||||||
|
@@ -38,7 +38,6 @@ import com.android.settings.core.OnActivityResultListener;
|
|||||||
import com.android.settings.dashboard.DashboardFragment;
|
import com.android.settings.dashboard.DashboardFragment;
|
||||||
import com.android.settings.search.BaseSearchIndexProvider;
|
import com.android.settings.search.BaseSearchIndexProvider;
|
||||||
import com.android.settings.sound.HandsFreeProfileOutputPreferenceController;
|
import com.android.settings.sound.HandsFreeProfileOutputPreferenceController;
|
||||||
import com.android.settings.sound.MediaOutputPreferenceController;
|
|
||||||
import com.android.settings.widget.PreferenceCategoryController;
|
import com.android.settings.widget.PreferenceCategoryController;
|
||||||
import com.android.settings.widget.UpdatableListPreferenceDialogFragment;
|
import com.android.settings.widget.UpdatableListPreferenceDialogFragment;
|
||||||
import com.android.settingslib.core.AbstractPreferenceController;
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
@@ -77,7 +76,6 @@ public class SoundSettings extends DashboardFragment implements OnActivityResult
|
|||||||
|
|
||||||
private RingtonePreference mRequestPreference;
|
private RingtonePreference mRequestPreference;
|
||||||
private UpdatableListPreferenceDialogFragment mDialogFragment;
|
private UpdatableListPreferenceDialogFragment mDialogFragment;
|
||||||
private String mMediaOutputControllerKey;
|
|
||||||
private String mHfpOutputControllerKey;
|
private String mHfpOutputControllerKey;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -132,8 +130,6 @@ public class SoundSettings extends DashboardFragment implements OnActivityResult
|
|||||||
final int metricsCategory;
|
final int metricsCategory;
|
||||||
if (mHfpOutputControllerKey.equals(preference.getKey())) {
|
if (mHfpOutputControllerKey.equals(preference.getKey())) {
|
||||||
metricsCategory = SettingsEnums.DIALOG_SWITCH_HFP_DEVICES;
|
metricsCategory = SettingsEnums.DIALOG_SWITCH_HFP_DEVICES;
|
||||||
} else if (mMediaOutputControllerKey.equals(preference.getKey())) {
|
|
||||||
metricsCategory = SettingsEnums.DIALOG_SWITCH_A2DP_DEVICES;
|
|
||||||
} else {
|
} else {
|
||||||
metricsCategory = Instrumentable.METRICS_CATEGORY_UNKNOWN;
|
metricsCategory = Instrumentable.METRICS_CATEGORY_UNKNOWN;
|
||||||
}
|
}
|
||||||
@@ -186,9 +182,6 @@ public class SoundSettings extends DashboardFragment implements OnActivityResult
|
|||||||
volumeControllers.add(use(CallVolumePreferenceController.class));
|
volumeControllers.add(use(CallVolumePreferenceController.class));
|
||||||
volumeControllers.add(use(RemoteVolumePreferenceController.class));
|
volumeControllers.add(use(RemoteVolumePreferenceController.class));
|
||||||
|
|
||||||
use(MediaOutputPreferenceController.class).setCallback(listPreference ->
|
|
||||||
onPreferenceDataChanged(listPreference));
|
|
||||||
mMediaOutputControllerKey = use(MediaOutputPreferenceController.class).getPreferenceKey();
|
|
||||||
use(HandsFreeProfileOutputPreferenceController.class).setCallback(listPreference ->
|
use(HandsFreeProfileOutputPreferenceController.class).setCallback(listPreference ->
|
||||||
onPreferenceDataChanged(listPreference));
|
onPreferenceDataChanged(listPreference));
|
||||||
mHfpOutputControllerKey =
|
mHfpOutputControllerKey =
|
||||||
|
@@ -32,7 +32,6 @@ import android.media.MediaRouter;
|
|||||||
import android.media.MediaRouter.Callback;
|
import android.media.MediaRouter.Callback;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.FeatureFlagUtils;
|
import android.util.FeatureFlagUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@@ -40,7 +39,6 @@ import androidx.preference.ListPreference;
|
|||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
import androidx.preference.PreferenceScreen;
|
import androidx.preference.PreferenceScreen;
|
||||||
|
|
||||||
import com.android.settings.R;
|
|
||||||
import com.android.settings.bluetooth.Utils;
|
import com.android.settings.bluetooth.Utils;
|
||||||
import com.android.settings.core.BasePreferenceController;
|
import com.android.settings.core.BasePreferenceController;
|
||||||
import com.android.settings.core.FeatureFlags;
|
import com.android.settings.core.FeatureFlags;
|
||||||
@@ -63,15 +61,11 @@ import java.util.concurrent.FutureTask;
|
|||||||
/**
|
/**
|
||||||
* Abstract class for audio switcher controller to notify subclass
|
* Abstract class for audio switcher controller to notify subclass
|
||||||
* updating the current status of switcher entry. Subclasses must overwrite
|
* 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
|
public abstract class AudioSwitchPreferenceController extends BasePreferenceController
|
||||||
implements Preference.OnPreferenceChangeListener, BluetoothCallback,
|
implements BluetoothCallback, LifecycleObserver, OnStart, OnStop {
|
||||||
LifecycleObserver, OnStart, OnStop {
|
|
||||||
|
|
||||||
private static final String TAG = "AudioSwitchPrefCtrl";
|
private static final String TAG = "AudioSwitchPrefCtrl";
|
||||||
private static final int INVALID_INDEX = -1;
|
|
||||||
|
|
||||||
protected final List<BluetoothDevice> mConnectedDevices;
|
protected final List<BluetoothDevice> mConnectedDevices;
|
||||||
protected final AudioManager mAudioManager;
|
protected final AudioManager mAudioManager;
|
||||||
@@ -128,35 +122,6 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont
|
|||||||
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
? 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
|
@Override
|
||||||
public void displayPreference(PreferenceScreen screen) {
|
public void displayPreference(PreferenceScreen screen) {
|
||||||
super.displayPreference(screen);
|
super.displayPreference(screen);
|
||||||
@@ -184,6 +149,12 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont
|
|||||||
unregister();
|
unregister();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBluetoothStateChanged(int bluetoothState) {
|
||||||
|
// To handle the case that Bluetooth on and no connected devices
|
||||||
|
updateState(mPreference);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {
|
public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {
|
||||||
updateState(mPreference);
|
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() {
|
protected List<BluetoothDevice> getConnectableA2dpDevices() {
|
||||||
final List<BluetoothDevice> connectedDevices = new ArrayList<>();
|
|
||||||
final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
|
final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
|
||||||
if (a2dpProfile == null) {
|
if (a2dpProfile == null) {
|
||||||
return connectedDevices;
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
final List<BluetoothDevice> devices = a2dpProfile.getConnectedDevices();
|
return a2dpProfile.getConnectableDevices();
|
||||||
for (BluetoothDevice device : devices) {
|
|
||||||
if (device.isConnected()) {
|
|
||||||
connectedDevices.add(device);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return connectedDevices;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -276,6 +241,31 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont
|
|||||||
return connectedDevices;
|
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
|
* Find active hearing aid device
|
||||||
*/
|
*/
|
||||||
@@ -306,52 +296,6 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont
|
|||||||
*/
|
*/
|
||||||
public abstract BluetoothDevice findActiveDevice();
|
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() {
|
private void register() {
|
||||||
mLocalBluetoothManager.getEventManager().registerCallback(this);
|
mLocalBluetoothManager.getEventManager().registerCallback(this);
|
||||||
mAudioManager.registerAudioDeviceCallback(mAudioManagerAudioDeviceCallback, mHandler);
|
mAudioManager.registerAudioDeviceCallback(mAudioManagerAudioDeviceCallback, mHandler);
|
||||||
|
@@ -20,7 +20,9 @@ import static android.bluetooth.IBluetoothHearingAid.HI_SYNC_ID_INVALID;
|
|||||||
|
|
||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import androidx.preference.ListPreference;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
@@ -32,13 +34,55 @@ import com.android.settingslib.bluetooth.HearingAidProfile;
|
|||||||
* This class allows switching between HFP-connected & HAP-connected BT devices
|
* This class allows switching between HFP-connected & HAP-connected BT devices
|
||||||
* while in on-call state.
|
* while in on-call state.
|
||||||
*/
|
*/
|
||||||
public class HandsFreeProfileOutputPreferenceController extends
|
public class HandsFreeProfileOutputPreferenceController extends AudioSwitchPreferenceController
|
||||||
AudioSwitchPreferenceController {
|
implements Preference.OnPreferenceChangeListener {
|
||||||
|
|
||||||
|
private static final int INVALID_INDEX = -1;
|
||||||
|
|
||||||
public HandsFreeProfileOutputPreferenceController(Context context, String key) {
|
public HandsFreeProfileOutputPreferenceController(Context context, String key) {
|
||||||
super(context, key);
|
super(context, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
|
final String address = (String) newValue;
|
||||||
|
if (!(preference instanceof ListPreference)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final CharSequence defaultSummary = mContext.getText(R.string.media_output_default_summary);
|
||||||
|
final ListPreference listPreference = (ListPreference) preference;
|
||||||
|
if (TextUtils.equals(address, defaultSummary)) {
|
||||||
|
// Switch to default device which address is device name
|
||||||
|
mSelectedIndex = getDefaultDeviceIndex();
|
||||||
|
setActiveBluetoothDevice(null);
|
||||||
|
listPreference.setSummary(defaultSummary);
|
||||||
|
} 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateState(Preference preference) {
|
public void updateState(Preference preference) {
|
||||||
if (preference == null) {
|
if (preference == null) {
|
||||||
@@ -83,7 +127,41 @@ public class HandsFreeProfileOutputPreferenceController extends
|
|||||||
setPreference(mediaOutputs, mediaValues, preference);
|
setPreference(mediaOutputs, mediaValues, preference);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
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.
|
||||||
|
final CharSequence defaultSummary = mContext.getText(R.string.media_output_default_summary);
|
||||||
|
mediaOutputs[mSelectedIndex] = defaultSummary;
|
||||||
|
// use default device name as address
|
||||||
|
mediaValues[mSelectedIndex] = defaultSummary;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
public void setActiveBluetoothDevice(BluetoothDevice device) {
|
public void setActiveBluetoothDevice(BluetoothDevice device) {
|
||||||
if (!Utils.isAudioModeOngoingCall(mContext)) {
|
if (!Utils.isAudioModeOngoingCall(mContext)) {
|
||||||
return;
|
return;
|
||||||
|
@@ -16,13 +16,14 @@
|
|||||||
|
|
||||||
package com.android.settings.sound;
|
package com.android.settings.sound;
|
||||||
|
|
||||||
import static android.bluetooth.IBluetoothHearingAid.HI_SYNC_ID_INVALID;
|
|
||||||
import static android.media.AudioManager.STREAM_MUSIC;
|
import static android.media.AudioManager.STREAM_MUSIC;
|
||||||
import static android.media.AudioSystem.DEVICE_OUT_REMOTE_SUBMIX;
|
import static android.media.AudioSystem.DEVICE_OUT_REMOTE_SUBMIX;
|
||||||
|
|
||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
@@ -30,12 +31,16 @@ import com.android.settings.R;
|
|||||||
import com.android.settingslib.Utils;
|
import com.android.settingslib.Utils;
|
||||||
import com.android.settingslib.bluetooth.A2dpProfile;
|
import com.android.settingslib.bluetooth.A2dpProfile;
|
||||||
import com.android.settingslib.bluetooth.HearingAidProfile;
|
import com.android.settingslib.bluetooth.HearingAidProfile;
|
||||||
|
import com.android.settingslib.media.MediaOutputSliceConstants;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class which allows switching between A2dp-connected & HAP-connected BT devices.
|
* This class allows launching MediaOutputSlice to switch output device.
|
||||||
* A few conditions will disable this switcher:
|
* Preference would hide only when
|
||||||
* - No available BT device(s)
|
* - Bluetooth = OFF
|
||||||
* - Media stream captured by cast device
|
* - Bluetooth = ON and Connected Devices = 0 and Previously Connected = 0
|
||||||
|
* - Media stream captured by remote device
|
||||||
* - During a call.
|
* - During a call.
|
||||||
*/
|
*/
|
||||||
public class MediaOutputPreferenceController extends AudioSwitchPreferenceController {
|
public class MediaOutputPreferenceController extends AudioSwitchPreferenceController {
|
||||||
@@ -66,40 +71,22 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mConnectedDevices.clear();
|
boolean deviceConnectable = false;
|
||||||
// Otherwise, list all of the A2DP connected device and display the active device.
|
BluetoothDevice activeDevice = null;
|
||||||
if (mAudioManager.getMode() == AudioManager.MODE_NORMAL) {
|
// Show preference if there is connected or previously connected device
|
||||||
mConnectedDevices.addAll(getConnectedA2dpDevices());
|
// Find active device and set its name as the preference's summary
|
||||||
mConnectedDevices.addAll(getConnectedHearingAidDevices());
|
List<BluetoothDevice> connectableA2dpDevices = getConnectableA2dpDevices();
|
||||||
}
|
List<BluetoothDevice> connectableHADevices = getConnectableHearingAidDevices();
|
||||||
|
if (mAudioManager.getMode() == AudioManager.MODE_NORMAL
|
||||||
final int numDevices = mConnectedDevices.size();
|
&& ((connectableA2dpDevices != null && !connectableA2dpDevices.isEmpty())
|
||||||
mPreference.setVisible((numDevices == 0) ? false : true);
|
|| (connectableHADevices != null && !connectableHADevices.isEmpty()))) {
|
||||||
CharSequence[] mediaOutputs = new CharSequence[numDevices + 1];
|
deviceConnectable = true;
|
||||||
CharSequence[] mediaValues = new CharSequence[numDevices + 1];
|
activeDevice = findActiveDevice();
|
||||||
|
|
||||||
// Setup devices entries, select active connected device
|
|
||||||
setupPreferenceEntries(mediaOutputs, mediaValues, findActiveDevice());
|
|
||||||
|
|
||||||
// Display connected devices, default device and show the active device
|
|
||||||
setPreference(mediaOutputs, mediaValues, preference);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setActiveBluetoothDevice(BluetoothDevice device) {
|
|
||||||
if (mAudioManager.getMode() != AudioManager.MODE_NORMAL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final HearingAidProfile hapProfile = mProfileManager.getHearingAidProfile();
|
|
||||||
final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
|
|
||||||
if (hapProfile != null && a2dpProfile != null && device == null) {
|
|
||||||
hapProfile.setActiveDevice(null);
|
|
||||||
a2dpProfile.setActiveDevice(null);
|
|
||||||
} else if (hapProfile != null && hapProfile.getHiSyncId(device) != HI_SYNC_ID_INVALID) {
|
|
||||||
hapProfile.setActiveDevice(device);
|
|
||||||
} else if (a2dpProfile != null) {
|
|
||||||
a2dpProfile.setActiveDevice(device);
|
|
||||||
}
|
}
|
||||||
|
mPreference.setVisible(deviceConnectable);
|
||||||
|
mPreference.setSummary((activeDevice == null) ?
|
||||||
|
mContext.getText(R.string.media_output_default_summary) :
|
||||||
|
activeDevice.getAliasName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -112,4 +99,34 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro
|
|||||||
}
|
}
|
||||||
return activeDevice;
|
return activeDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find active hearing aid device
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected BluetoothDevice findActiveHearingAidDevice() {
|
||||||
|
final HearingAidProfile hearingAidProfile = mProfileManager.getHearingAidProfile();
|
||||||
|
|
||||||
|
if (hearingAidProfile != null) {
|
||||||
|
List<BluetoothDevice> activeDevices = hearingAidProfile.getActiveDevices();
|
||||||
|
for (BluetoothDevice btDevice : activeDevices) {
|
||||||
|
if (btDevice != null) {
|
||||||
|
return btDevice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handlePreferenceTreeClick(Preference preference) {
|
||||||
|
if (TextUtils.equals(preference.getKey(), getPreferenceKey())) {
|
||||||
|
final Intent intent = new Intent()
|
||||||
|
.setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
|
||||||
|
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
mContext.startActivity(intent);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -238,63 +238,6 @@ public class AudioOutputSwitchPreferenceControllerTest {
|
|||||||
verify(mLocalBluetoothManager).setForegroundActivity(null);
|
verify(mLocalBluetoothManager).setForegroundActivity(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onPreferenceChange_toThisDevice_shouldSetDefaultSummary() {
|
|
||||||
mController.mConnectedDevices.clear();
|
|
||||||
mController.mConnectedDevices.add(mBluetoothDevice);
|
|
||||||
|
|
||||||
mController.onPreferenceChange(mPreference,
|
|
||||||
mContext.getText(R.string.media_output_default_summary));
|
|
||||||
|
|
||||||
assertThat(mPreference.getSummary()).isEqualTo(
|
|
||||||
mContext.getText(R.string.media_output_default_summary));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* One Bluetooth devices are available, and select the device.
|
|
||||||
* Preference summary should be device name.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void onPreferenceChange_toBtDevice_shouldSetBtDeviceName() {
|
|
||||||
mController.mConnectedDevices.clear();
|
|
||||||
mController.mConnectedDevices.add(mBluetoothDevice);
|
|
||||||
|
|
||||||
mController.onPreferenceChange(mPreference, TEST_DEVICE_ADDRESS_1);
|
|
||||||
|
|
||||||
assertThat(mPreference.getSummary()).isEqualTo(TEST_DEVICE_NAME_1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* More than one Bluetooth devices are available, and select second device.
|
|
||||||
* Preference summary should be second device name.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void onPreferenceChange_toBtDevices_shouldSetSecondBtDeviceName() {
|
|
||||||
ShadowBluetoothDevice shadowBluetoothDevice;
|
|
||||||
BluetoothDevice secondBluetoothDevice;
|
|
||||||
secondBluetoothDevice = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_2);
|
|
||||||
shadowBluetoothDevice = Shadows.shadowOf(secondBluetoothDevice);
|
|
||||||
shadowBluetoothDevice.setName(TEST_DEVICE_NAME_2);
|
|
||||||
mController.mConnectedDevices.clear();
|
|
||||||
mController.mConnectedDevices.add(mBluetoothDevice);
|
|
||||||
mController.mConnectedDevices.add(secondBluetoothDevice);
|
|
||||||
|
|
||||||
mController.onPreferenceChange(mPreference, TEST_DEVICE_ADDRESS_2);
|
|
||||||
|
|
||||||
assertThat(mPreference.getSummary()).isEqualTo(TEST_DEVICE_NAME_2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mConnectedDevices is empty.
|
|
||||||
* onPreferenceChange should return false.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void onPreferenceChange_connectedDeviceIsNull_shouldReturnFalse() {
|
|
||||||
mController.mConnectedDevices.clear();
|
|
||||||
|
|
||||||
assertThat(mController.onPreferenceChange(mPreference, TEST_DEVICE_ADDRESS_1)).isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Audio stream output to bluetooth sco headset which is the subset of all sco device.
|
* Audio stream output to bluetooth sco headset which is the subset of all sco device.
|
||||||
* isStreamFromOutputDevice should return true.
|
* isStreamFromOutputDevice should return true.
|
||||||
@@ -415,39 +358,6 @@ public class AudioOutputSwitchPreferenceControllerTest {
|
|||||||
assertThat(mEmptyDevices).containsExactly(mLeftBluetoothHapDevice);
|
assertThat(mEmptyDevices).containsExactly(mLeftBluetoothHapDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* One A2dp device is connected.
|
|
||||||
* getConnectedA2dpDevices should add this device to list.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void getConnectedA2dpDevices_oneConnectedA2dpDevice_shouldAddDeviceToList() {
|
|
||||||
mEmptyDevices.clear();
|
|
||||||
mProfileConnectedDevices.clear();
|
|
||||||
mProfileConnectedDevices.add(mBluetoothDevice);
|
|
||||||
when(mA2dpProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
|
|
||||||
|
|
||||||
mEmptyDevices.addAll(mController.getConnectedA2dpDevices());
|
|
||||||
|
|
||||||
assertThat(mEmptyDevices).containsExactly(mBluetoothDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* More than one A2dp devices are connected.
|
|
||||||
* getConnectedA2dpDevices should add all devices to list.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void getConnectedA2dpDevices_moreThanOneConnectedA2dpDevice_shouldAddDeviceToList() {
|
|
||||||
mEmptyDevices.clear();
|
|
||||||
mProfileConnectedDevices.clear();
|
|
||||||
mProfileConnectedDevices.add(mBluetoothDevice);
|
|
||||||
mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
|
|
||||||
when(mA2dpProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
|
|
||||||
|
|
||||||
mEmptyDevices.addAll(mController.getConnectedA2dpDevices());
|
|
||||||
|
|
||||||
assertThat(mEmptyDevices).containsExactly(mBluetoothDevice, mLeftBluetoothHapDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* One hands free profile device is connected.
|
* One hands free profile device is connected.
|
||||||
* getConnectedA2dpDevices should add this device to list.
|
* getConnectedA2dpDevices should add this device to list.
|
||||||
@@ -487,10 +397,6 @@ public class AudioOutputSwitchPreferenceControllerTest {
|
|||||||
super(context, key);
|
super(context, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setActiveBluetoothDevice(BluetoothDevice device) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BluetoothDevice findActiveDevice() {
|
public BluetoothDevice findActiveDevice() {
|
||||||
return null;
|
return null;
|
||||||
|
@@ -57,6 +57,7 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
import org.robolectric.RuntimeEnvironment;
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
import org.robolectric.Shadows;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
import org.robolectric.shadows.ShadowBluetoothDevice;
|
import org.robolectric.shadows.ShadowBluetoothDevice;
|
||||||
|
|
||||||
@@ -107,7 +108,7 @@ public class HandsFreeProfileOutputPreferenceControllerTest {
|
|||||||
private BluetoothDevice mLeftBluetoothHapDevice;
|
private BluetoothDevice mLeftBluetoothHapDevice;
|
||||||
private BluetoothDevice mRightBluetoothHapDevice;
|
private BluetoothDevice mRightBluetoothHapDevice;
|
||||||
private LocalBluetoothManager mLocalBluetoothManager;
|
private LocalBluetoothManager mLocalBluetoothManager;
|
||||||
private AudioSwitchPreferenceController mController;
|
private HandsFreeProfileOutputPreferenceController mController;
|
||||||
private List<BluetoothDevice> mProfileConnectedDevices;
|
private List<BluetoothDevice> mProfileConnectedDevices;
|
||||||
private List<BluetoothDevice> mHearingAidActiveDevices;
|
private List<BluetoothDevice> mHearingAidActiveDevices;
|
||||||
|
|
||||||
@@ -478,4 +479,61 @@ public class HandsFreeProfileOutputPreferenceControllerTest {
|
|||||||
|
|
||||||
assertThat(mController.findActiveDevice()).isNull();
|
assertThat(mController.findActiveDevice()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One Bluetooth devices are available, and select the device.
|
||||||
|
* Preference summary should be device name.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void onPreferenceChange_toBtDevice_shouldSetBtDeviceName() {
|
||||||
|
mController.mConnectedDevices.clear();
|
||||||
|
mController.mConnectedDevices.add(mBluetoothDevice);
|
||||||
|
|
||||||
|
mController.onPreferenceChange(mPreference, TEST_DEVICE_ADDRESS_1);
|
||||||
|
|
||||||
|
assertThat(mPreference.getSummary()).isEqualTo(TEST_DEVICE_NAME_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* More than one Bluetooth devices are available, and select second device.
|
||||||
|
* Preference summary should be second device name.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void onPreferenceChange_toBtDevices_shouldSetSecondBtDeviceName() {
|
||||||
|
ShadowBluetoothDevice shadowBluetoothDevice;
|
||||||
|
BluetoothDevice secondBluetoothDevice;
|
||||||
|
secondBluetoothDevice = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_2);
|
||||||
|
shadowBluetoothDevice = Shadows.shadowOf(secondBluetoothDevice);
|
||||||
|
shadowBluetoothDevice.setName(TEST_DEVICE_NAME_2);
|
||||||
|
mController.mConnectedDevices.clear();
|
||||||
|
mController.mConnectedDevices.add(mBluetoothDevice);
|
||||||
|
mController.mConnectedDevices.add(secondBluetoothDevice);
|
||||||
|
|
||||||
|
mController.onPreferenceChange(mPreference, TEST_DEVICE_ADDRESS_2);
|
||||||
|
|
||||||
|
assertThat(mPreference.getSummary()).isEqualTo(TEST_DEVICE_NAME_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mConnectedDevices is empty.
|
||||||
|
* onPreferenceChange should return false.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void onPreferenceChange_connectedDeviceIsNull_shouldReturnFalse() {
|
||||||
|
mController.mConnectedDevices.clear();
|
||||||
|
|
||||||
|
assertThat(mController.onPreferenceChange(mPreference, TEST_DEVICE_ADDRESS_1)).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onPreferenceChange_toThisDevice_shouldSetDefaultSummary() {
|
||||||
|
mController.mConnectedDevices.clear();
|
||||||
|
mController.mConnectedDevices.add(mBluetoothDevice);
|
||||||
|
|
||||||
|
mController.onPreferenceChange(mPreference,
|
||||||
|
mContext.getText(R.string.media_output_default_summary));
|
||||||
|
|
||||||
|
assertThat(mPreference.getSummary()).isEqualTo(
|
||||||
|
mContext.getText(R.string.media_output_default_summary));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,16 +17,15 @@
|
|||||||
package com.android.settings.sound;
|
package com.android.settings.sound;
|
||||||
|
|
||||||
import static android.media.AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP;
|
import static android.media.AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP;
|
||||||
|
import static android.media.AudioSystem.DEVICE_OUT_EARPIECE;
|
||||||
import static android.media.AudioSystem.DEVICE_OUT_HEARING_AID;
|
import static android.media.AudioSystem.DEVICE_OUT_HEARING_AID;
|
||||||
import static android.media.AudioSystem.DEVICE_OUT_REMOTE_SUBMIX;
|
import static android.media.AudioSystem.DEVICE_OUT_REMOTE_SUBMIX;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@@ -34,9 +33,10 @@ import android.bluetooth.BluetoothAdapter;
|
|||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.bluetooth.BluetoothManager;
|
import android.bluetooth.BluetoothManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
|
|
||||||
import androidx.preference.ListPreference;
|
import androidx.preference.Preference;
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
import androidx.preference.PreferenceScreen;
|
import androidx.preference.PreferenceScreen;
|
||||||
|
|
||||||
@@ -49,11 +49,13 @@ import com.android.settingslib.bluetooth.BluetoothEventManager;
|
|||||||
import com.android.settingslib.bluetooth.HearingAidProfile;
|
import com.android.settingslib.bluetooth.HearingAidProfile;
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||||
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
||||||
|
import com.android.settingslib.media.MediaOutputSliceConstants;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
@@ -80,8 +82,6 @@ public class MediaOutputPreferenceControllerTest {
|
|||||||
private static final String TEST_DEVICE_ADDRESS_2 = "00:B2:B2:B2:B2:B2";
|
private static final String TEST_DEVICE_ADDRESS_2 = "00:B2:B2:B2:B2:B2";
|
||||||
private static final String TEST_DEVICE_ADDRESS_3 = "00:C3:C3:C3:C3:C3";
|
private static final String TEST_DEVICE_ADDRESS_3 = "00:C3:C3:C3:C3:C3";
|
||||||
private static final String TEST_DEVICE_ADDRESS_4 = "00:D4:D4:D4:D4:D4";
|
private static final String TEST_DEVICE_ADDRESS_4 = "00:D4:D4:D4:D4:D4";
|
||||||
private final static long HISYNCID1 = 10;
|
|
||||||
private final static long HISYNCID2 = 11;
|
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private LocalBluetoothManager mLocalManager;
|
private LocalBluetoothManager mLocalManager;
|
||||||
@@ -98,7 +98,7 @@ public class MediaOutputPreferenceControllerTest {
|
|||||||
|
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private PreferenceScreen mScreen;
|
private PreferenceScreen mScreen;
|
||||||
private ListPreference mPreference;
|
private Preference mPreference;
|
||||||
private AudioManager mAudioManager;
|
private AudioManager mAudioManager;
|
||||||
private ShadowAudioManager mShadowAudioManager;
|
private ShadowAudioManager mShadowAudioManager;
|
||||||
private BluetoothManager mBluetoothManager;
|
private BluetoothManager mBluetoothManager;
|
||||||
@@ -108,8 +108,8 @@ public class MediaOutputPreferenceControllerTest {
|
|||||||
private BluetoothDevice mLeftBluetoothHapDevice;
|
private BluetoothDevice mLeftBluetoothHapDevice;
|
||||||
private BluetoothDevice mRightBluetoothHapDevice;
|
private BluetoothDevice mRightBluetoothHapDevice;
|
||||||
private LocalBluetoothManager mLocalBluetoothManager;
|
private LocalBluetoothManager mLocalBluetoothManager;
|
||||||
private AudioSwitchPreferenceController mController;
|
private MediaOutputPreferenceController mController;
|
||||||
private List<BluetoothDevice> mProfileConnectedDevices;
|
private List<BluetoothDevice> mProfileConnectableDevices;
|
||||||
private List<BluetoothDevice> mHearingAidActiveDevices;
|
private List<BluetoothDevice> mHearingAidActiveDevices;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -149,8 +149,8 @@ public class MediaOutputPreferenceControllerTest {
|
|||||||
|
|
||||||
mController = new MediaOutputPreferenceController(mContext, TEST_KEY);
|
mController = new MediaOutputPreferenceController(mContext, TEST_KEY);
|
||||||
mScreen = spy(new PreferenceScreen(mContext, null));
|
mScreen = spy(new PreferenceScreen(mContext, null));
|
||||||
mPreference = new ListPreference(mContext);
|
mPreference = new Preference(mContext);
|
||||||
mProfileConnectedDevices = new ArrayList<>();
|
mProfileConnectableDevices = new ArrayList<>();
|
||||||
mHearingAidActiveDevices = new ArrayList<>(2);
|
mHearingAidActiveDevices = new ArrayList<>(2);
|
||||||
|
|
||||||
when(mScreen.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
|
when(mScreen.getPreferenceManager()).thenReturn(mock(PreferenceManager.class));
|
||||||
@@ -166,61 +166,140 @@ public class MediaOutputPreferenceControllerTest {
|
|||||||
ShadowBluetoothUtils.reset();
|
ShadowBluetoothUtils.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In normal mode, bluetooth device with HisyncId.
|
* A2DP Bluetooth device(s) are not connected nor previously connected
|
||||||
* HearingAidProfile should set active device to this device.
|
* Preference should be invisible
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void setActiveBluetoothDevice_btDeviceWithHisyncId_shouldSetBtDeviceActive() {
|
public void updateState_withoutConnectableBtDevice_preferenceInvisible() {
|
||||||
|
mShadowAudioManager.setOutputDevice(DEVICE_OUT_EARPIECE);
|
||||||
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
||||||
when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
|
mProfileConnectableDevices.clear();
|
||||||
|
when(mA2dpProfile.getConnectableDevices()).thenReturn(mProfileConnectableDevices);
|
||||||
|
mPreference.setVisible(true);
|
||||||
|
|
||||||
mController.setActiveBluetoothDevice(mLeftBluetoothHapDevice);
|
assertThat(mPreference.isVisible()).isTrue();
|
||||||
|
mController.updateState(mPreference);
|
||||||
verify(mHearingAidProfile).setActiveDevice(mLeftBluetoothHapDevice);
|
assertThat(mPreference.isVisible()).isFalse();
|
||||||
verify(mA2dpProfile, never()).setActiveDevice(mLeftBluetoothHapDevice);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In normal mode, bluetooth device without HisyncId.
|
* A2DP Bluetooth device(s) are connectable, no matter active or inactive
|
||||||
* A2dpProfile should set active device to this device.
|
* Preference should be visible
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void setActiveBluetoothDevice_btDeviceWithoutHisyncId_shouldSetBtDeviceActive() {
|
public void updateState_withConnectableBtDevice_preferenceVisible() {
|
||||||
|
mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLUETOOTH_A2DP);
|
||||||
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
||||||
|
mProfileConnectableDevices.clear();
|
||||||
|
mProfileConnectableDevices.add(mBluetoothDevice);
|
||||||
|
when(mA2dpProfile.getConnectableDevices()).thenReturn(mProfileConnectableDevices);
|
||||||
|
assertThat(mPreference.isVisible()).isFalse();
|
||||||
|
|
||||||
mController.setActiveBluetoothDevice(mBluetoothDevice);
|
// Without Active Bluetooth Device
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
assertThat(mPreference.isVisible()).isTrue();
|
||||||
|
|
||||||
verify(mA2dpProfile).setActiveDevice(mBluetoothDevice);
|
// With Active Bluetooth Device
|
||||||
verify(mHearingAidProfile, never()).setActiveDevice(mBluetoothDevice);
|
when(mA2dpProfile.getActiveDevice()).thenReturn(mBluetoothDevice);
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
assertThat(mPreference.isVisible()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In normal mode, set active device to "this device".
|
* A2DP Bluetooth device(s) are connectable, but no device is set as activated
|
||||||
* A2dpProfile should set to null.
|
* Preference summary should be "This device"
|
||||||
* HearingAidProfile should set to null.
|
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void setActiveBluetoothDevice_setNull_shouldSetNullToBothProfiles() {
|
public void updateState_withConnectableBtDevice_withoutActiveBtDevice_setDefaultSummary() {
|
||||||
|
mShadowAudioManager.setOutputDevice(DEVICE_OUT_EARPIECE);
|
||||||
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
||||||
|
mProfileConnectableDevices.clear();
|
||||||
|
mProfileConnectableDevices.add(mBluetoothDevice);
|
||||||
|
mProfileConnectableDevices.add(mSecondBluetoothDevice);
|
||||||
|
when(mA2dpProfile.getConnectableDevices()).thenReturn(mProfileConnectableDevices);
|
||||||
|
when(mA2dpProfile.getActiveDevice()).thenReturn(null);
|
||||||
|
|
||||||
mController.setActiveBluetoothDevice(null);
|
assertThat(mPreference.getSummary()).isNull();
|
||||||
|
mController.updateState(mPreference);
|
||||||
verify(mA2dpProfile).setActiveDevice(null);
|
assertThat(mPreference.getSummary()).isEqualTo(
|
||||||
verify(mHearingAidProfile).setActiveDevice(null);
|
mContext.getText(R.string.media_output_default_summary));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* During a call
|
* A2DP Bluetooth device(s) are connected and active
|
||||||
* A2dpProfile should not set active device.
|
* Preference summary should be device's name
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void setActiveBluetoothDevice_duringACall_shouldNotSetActiveDeviceToA2dpProfile() {
|
public void updateState_withActiveBtDevice_setActivatedDeviceName() {
|
||||||
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
|
mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLUETOOTH_A2DP);
|
||||||
|
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
||||||
|
mProfileConnectableDevices.clear();
|
||||||
|
mProfileConnectableDevices.add(mBluetoothDevice);
|
||||||
|
mProfileConnectableDevices.add(mSecondBluetoothDevice);
|
||||||
|
when(mA2dpProfile.getConnectableDevices()).thenReturn(mProfileConnectableDevices);
|
||||||
|
when(mA2dpProfile.getActiveDevice()).thenReturn(mBluetoothDevice);
|
||||||
|
|
||||||
mController.setActiveBluetoothDevice(mBluetoothDevice);
|
assertThat(mPreference.getSummary()).isNull();
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
assertThat(mPreference.getSummary()).isEqualTo(TEST_DEVICE_NAME_1);
|
||||||
|
}
|
||||||
|
|
||||||
verify(mA2dpProfile, times(0)).setActiveDevice(any(BluetoothDevice.class));
|
|
||||||
|
/**
|
||||||
|
* Hearing Aid device(s) are connectable, no matter active or inactive
|
||||||
|
* Preference should be visible
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void updateState_withConnectableHADevice_preferenceVisible() {
|
||||||
|
mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
|
||||||
|
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
||||||
|
mHearingAidActiveDevices.clear();
|
||||||
|
mHearingAidActiveDevices.add(mLeftBluetoothHapDevice);
|
||||||
|
when(mHearingAidProfile.getConnectableDevices()).thenReturn(mHearingAidActiveDevices);
|
||||||
|
assertThat(mPreference.isVisible()).isFalse();
|
||||||
|
|
||||||
|
// Without Active Hearing Aid Device
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
assertThat(mPreference.isVisible()).isTrue();
|
||||||
|
|
||||||
|
// With Active Hearing Aid Device
|
||||||
|
when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
assertThat(mPreference.isVisible()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hearing Aid device(s) are connected and active
|
||||||
|
* Preference summary should be device's name
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void updateState_withActiveHADevice_setActivatedDeviceName() {
|
||||||
|
mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
|
||||||
|
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
||||||
|
mHearingAidActiveDevices.clear();
|
||||||
|
mHearingAidActiveDevices.add(mLeftBluetoothHapDevice);
|
||||||
|
when(mHearingAidProfile.getConnectableDevices()).thenReturn(mHearingAidActiveDevices);
|
||||||
|
when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
|
||||||
|
|
||||||
|
assertThat(mPreference.getSummary()).isNull();
|
||||||
|
mController.updateState(mPreference);
|
||||||
|
assertThat(mPreference.getSummary()).isEqualTo(TEST_HAP_DEVICE_NAME_1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void click_launch_outputSwitcherSlice() {
|
||||||
|
final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
|
||||||
|
mController.handlePreferenceTreeClick(mPreference);
|
||||||
|
verify(mContext, never()).startActivity(intentCaptor.capture());
|
||||||
|
|
||||||
|
mPreference.setKey(TEST_KEY);
|
||||||
|
mController.handlePreferenceTreeClick(mPreference);
|
||||||
|
verify(mContext).startActivity(intentCaptor.capture());
|
||||||
|
assertThat(intentCaptor.getValue().getAction())
|
||||||
|
.isEqualTo(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -253,24 +332,6 @@ public class MediaOutputPreferenceControllerTest {
|
|||||||
mContext.getText(R.string.media_out_summary_ongoing_call_state));
|
mContext.getText(R.string.media_out_summary_ongoing_call_state));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* No available A2dp BT devices:
|
|
||||||
* Preference should be invisible
|
|
||||||
* Preference summary should be "This device"
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void updateState_noAvailableA2dpBtDevices_shouldDisableAndSetDefaultSummary() {
|
|
||||||
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
|
||||||
List<BluetoothDevice> emptyDeviceList = new ArrayList<>();
|
|
||||||
when(mA2dpProfile.getConnectedDevices()).thenReturn(emptyDeviceList);
|
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
|
||||||
|
|
||||||
assertThat(mPreference.isVisible()).isFalse();
|
|
||||||
String defaultString = mContext.getString(R.string.media_output_default_summary);
|
|
||||||
assertThat(mPreference.getSummary()).isEqualTo(defaultString);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Media stream is captured by something else (cast device):
|
* Media stream is captured by something else (cast device):
|
||||||
* Preference should be invisible
|
* Preference should be invisible
|
||||||
@@ -287,235 +348,6 @@ public class MediaOutputPreferenceControllerTest {
|
|||||||
assertThat(mPreference.getSummary()).isEqualTo(defaultString);
|
assertThat(mPreference.getSummary()).isEqualTo(defaultString);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* One A2DP Bluetooth device is available and active.
|
|
||||||
* Preference should be visible
|
|
||||||
* Preference summary should be the activated device name
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void updateState_oneA2dpBtDeviceAreAvailable_shouldSetActivatedDeviceName() {
|
|
||||||
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
|
||||||
mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLUETOOTH_A2DP);
|
|
||||||
mProfileConnectedDevices.clear();
|
|
||||||
mProfileConnectedDevices.add(mBluetoothDevice);
|
|
||||||
when(mA2dpProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
|
|
||||||
when(mA2dpProfile.getActiveDevice()).thenReturn(mBluetoothDevice);
|
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
|
||||||
|
|
||||||
assertThat(mPreference.isVisible()).isTrue();
|
|
||||||
assertThat(mPreference.getSummary()).isEqualTo(TEST_DEVICE_NAME_1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* More than one A2DP Bluetooth devices are available, and second device is active.
|
|
||||||
* Preference should be visible
|
|
||||||
* Preference summary should be the activated device name
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void updateState_moreThanOneA2DpBtDevicesAreAvailable_shouldSetActivatedDeviceName() {
|
|
||||||
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
|
||||||
mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLUETOOTH_A2DP);
|
|
||||||
mProfileConnectedDevices.clear();
|
|
||||||
mProfileConnectedDevices.add(mBluetoothDevice);
|
|
||||||
mProfileConnectedDevices.add(mSecondBluetoothDevice);
|
|
||||||
when(mA2dpProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
|
|
||||||
when(mA2dpProfile.getActiveDevice()).thenReturn(mSecondBluetoothDevice);
|
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
|
||||||
|
|
||||||
assertThat(mPreference.isVisible()).isTrue();
|
|
||||||
assertThat(mPreference.getSummary()).isEqualTo(TEST_DEVICE_NAME_2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A2DP Bluetooth device(s) are available, but wired headset is plugged in and activated
|
|
||||||
* Preference should be visible
|
|
||||||
* Preference summary should be "This device"
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void updateState_a2dpDevicesAvailableWiredHeadsetIsActivated_shouldSetDefaultSummary() {
|
|
||||||
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
|
||||||
mProfileConnectedDevices.clear();
|
|
||||||
mProfileConnectedDevices.add(mBluetoothDevice);
|
|
||||||
when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(null);
|
|
||||||
when(mA2dpProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
|
|
||||||
when(mA2dpProfile.getActiveDevice()).thenReturn(null);
|
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
|
||||||
|
|
||||||
assertThat(mPreference.isVisible()).isTrue();
|
|
||||||
assertThat(mPreference.getSummary()).isEqualTo(
|
|
||||||
mContext.getString(R.string.media_output_default_summary));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A2DP Bluetooth device(s) are available, but current device speaker is activated
|
|
||||||
* Preference should be visible
|
|
||||||
* Preference summary should be "This device"
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void updateState_a2dpDevicesAvailableCurrentDeviceActivated_shouldSetDefaultSummary() {
|
|
||||||
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
|
||||||
mProfileConnectedDevices.clear();
|
|
||||||
mProfileConnectedDevices.add(mBluetoothDevice);
|
|
||||||
when(mA2dpProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
|
|
||||||
when(mA2dpProfile.getActiveDevice()).thenReturn(null);
|
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
|
||||||
|
|
||||||
assertThat(mPreference.isVisible()).isTrue();
|
|
||||||
assertThat(mPreference.getSummary()).isEqualTo(
|
|
||||||
mContext.getString(R.string.media_output_default_summary));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* One hearing aid profile Bluetooth device is available and active.
|
|
||||||
* Preference should be visible
|
|
||||||
* Preference summary should be the activated device name
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void updateState_oneHapBtDeviceAreAvailable_shouldSetActivatedDeviceName() {
|
|
||||||
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
|
||||||
mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
|
|
||||||
mProfileConnectedDevices.clear();
|
|
||||||
mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
|
|
||||||
mHearingAidActiveDevices.clear();
|
|
||||||
mHearingAidActiveDevices.add(mLeftBluetoothHapDevice);
|
|
||||||
when(mHearingAidProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
|
|
||||||
when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
|
|
||||||
when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
|
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
|
||||||
|
|
||||||
assertThat(mPreference.isVisible()).isTrue();
|
|
||||||
assertThat(mPreference.getSummary()).isEqualTo(mLeftBluetoothHapDevice.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* More than one hearing aid profile Bluetooth devices are available, and second
|
|
||||||
* device is active.
|
|
||||||
* Preference should be visible
|
|
||||||
* Preference summary should be the activated device name
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void updateState_moreThanOneHapBtDevicesAreAvailable_shouldSetActivatedDeviceName() {
|
|
||||||
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
|
||||||
mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
|
|
||||||
mProfileConnectedDevices.clear();
|
|
||||||
mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
|
|
||||||
mProfileConnectedDevices.add(mRightBluetoothHapDevice);
|
|
||||||
mHearingAidActiveDevices.clear();
|
|
||||||
mHearingAidActiveDevices.add(mRightBluetoothHapDevice);
|
|
||||||
when(mHearingAidProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
|
|
||||||
when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
|
|
||||||
when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
|
|
||||||
when(mHearingAidProfile.getHiSyncId(mRightBluetoothHapDevice)).thenReturn(HISYNCID2);
|
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
|
||||||
|
|
||||||
assertThat(mPreference.isVisible()).isTrue();
|
|
||||||
assertThat(mPreference.getSummary()).isEqualTo(mRightBluetoothHapDevice.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Both hearing aid profile and A2dp Bluetooth devices are available, and two hearing aid
|
|
||||||
* profile devices with same HisyncId are active. Both of HAP device are active,
|
|
||||||
* "left" side HAP device is added first.
|
|
||||||
* Preference should be visible
|
|
||||||
* Preference summary should be the activated device name
|
|
||||||
* ConnectedDevice should not contain second HAP device with same HisyncId
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void updateState_hapBtDeviceWithSameId_shouldSetActivatedDeviceName() {
|
|
||||||
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
|
||||||
mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
|
|
||||||
mProfileConnectedDevices.clear();
|
|
||||||
mProfileConnectedDevices.add(mBluetoothDevice);
|
|
||||||
//with same HisyncId, first one will remain in UI.
|
|
||||||
mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
|
|
||||||
mProfileConnectedDevices.add(mRightBluetoothHapDevice);
|
|
||||||
mHearingAidActiveDevices.clear();
|
|
||||||
mHearingAidActiveDevices.add(mLeftBluetoothHapDevice);
|
|
||||||
mHearingAidActiveDevices.add(mRightBluetoothHapDevice);
|
|
||||||
when(mHearingAidProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
|
|
||||||
when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
|
|
||||||
when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
|
|
||||||
when(mHearingAidProfile.getHiSyncId(mRightBluetoothHapDevice)).thenReturn(HISYNCID1);
|
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
|
||||||
|
|
||||||
assertThat(mPreference.isVisible()).isTrue();
|
|
||||||
assertThat(mPreference.getSummary()).isEqualTo(mLeftBluetoothHapDevice.getName());
|
|
||||||
assertThat(mController.mConnectedDevices.contains(mLeftBluetoothHapDevice)).isTrue();
|
|
||||||
assertThat(mController.mConnectedDevices.contains(mRightBluetoothHapDevice)).isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Both hearing aid profile and A2dp Bluetooth devices are available, and two hearing aid
|
|
||||||
* profile devices with same HisyncId. Both of HAP device are active,
|
|
||||||
* "right" side HAP device is added first.
|
|
||||||
* Preference should be visible
|
|
||||||
* Preference summary should be the activated device name
|
|
||||||
* ConnectedDevice should not contain second HAP device with same HisyncId
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void updateState_hapBtDeviceWithSameIdButDifferentOrder_shouldSetActivatedDeviceName() {
|
|
||||||
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
|
||||||
mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
|
|
||||||
mProfileConnectedDevices.clear();
|
|
||||||
mProfileConnectedDevices.add(mBluetoothDevice);
|
|
||||||
//with same HisyncId, first one will remain in UI.
|
|
||||||
mProfileConnectedDevices.add(mRightBluetoothHapDevice);
|
|
||||||
mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
|
|
||||||
mHearingAidActiveDevices.clear();
|
|
||||||
mHearingAidActiveDevices.add(mLeftBluetoothHapDevice);
|
|
||||||
mHearingAidActiveDevices.add(mRightBluetoothHapDevice);
|
|
||||||
when(mHearingAidProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
|
|
||||||
when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
|
|
||||||
when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
|
|
||||||
when(mHearingAidProfile.getHiSyncId(mRightBluetoothHapDevice)).thenReturn(HISYNCID1);
|
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
|
||||||
|
|
||||||
assertThat(mPreference.isVisible()).isTrue();
|
|
||||||
assertThat(mPreference.getSummary()).isEqualTo(mRightBluetoothHapDevice.getName());
|
|
||||||
assertThat(mController.mConnectedDevices.contains(mRightBluetoothHapDevice)).isTrue();
|
|
||||||
assertThat(mController.mConnectedDevices.contains(mLeftBluetoothHapDevice)).isFalse();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Both hearing aid profile and A2dp Bluetooth devices are available, and two hearing aid
|
|
||||||
* profile devices with different HisyncId. One of HAP device is active.
|
|
||||||
* Preference should be visible
|
|
||||||
* Preference summary should be the activated device name
|
|
||||||
* ConnectedDevice should contain both HAP device with different HisyncId
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void updateState_hapBtDeviceWithDifferentId_shouldSetActivatedDeviceName() {
|
|
||||||
mAudioManager.setMode(AudioManager.MODE_NORMAL);
|
|
||||||
mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID);
|
|
||||||
mProfileConnectedDevices.clear();
|
|
||||||
mProfileConnectedDevices.add(mBluetoothDevice);
|
|
||||||
mProfileConnectedDevices.add(mLeftBluetoothHapDevice);
|
|
||||||
mProfileConnectedDevices.add(mRightBluetoothHapDevice);
|
|
||||||
mHearingAidActiveDevices.clear();
|
|
||||||
mHearingAidActiveDevices.add(null);
|
|
||||||
mHearingAidActiveDevices.add(mRightBluetoothHapDevice);
|
|
||||||
when(mHearingAidProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices);
|
|
||||||
when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices);
|
|
||||||
when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1);
|
|
||||||
when(mHearingAidProfile.getHiSyncId(mRightBluetoothHapDevice)).thenReturn(HISYNCID2);
|
|
||||||
|
|
||||||
mController.updateState(mPreference);
|
|
||||||
|
|
||||||
assertThat(mPreference.isVisible()).isTrue();
|
|
||||||
assertThat(mPreference.getSummary()).isEqualTo(mRightBluetoothHapDevice.getName());
|
|
||||||
assertThat(mController.mConnectedDevices).containsExactly(mBluetoothDevice,
|
|
||||||
mLeftBluetoothHapDevice, mRightBluetoothHapDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findActiveDevice_onlyA2dpDeviceActive_returnA2dpDevice() {
|
public void findActiveDevice_onlyA2dpDeviceActive_returnA2dpDevice() {
|
||||||
when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(null);
|
when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(null);
|
||||||
|
Reference in New Issue
Block a user