Loading src/com/android/settings/sound/AudioSwitchPreferenceController.java +107 −6 Original line number Diff line number Diff line Loading @@ -16,8 +16,12 @@ package com.android.settings.sound; import static android.media.AudioManager.STREAM_DEVICES_CHANGED_ACTION; import static android.media.AudioManager.STREAM_MUSIC; import static android.media.AudioManager.STREAM_VOICE_CALL; import static android.media.AudioSystem.DEVICE_OUT_ALL_A2DP; import static android.media.AudioSystem.DEVICE_OUT_ALL_SCO; import static android.media.AudioSystem.DEVICE_OUT_HEARING_AID; import static android.media.MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY; import android.bluetooth.BluetoothDevice; Loading @@ -38,19 +42,22 @@ import androidx.preference.PreferenceScreen; import android.text.TextUtils; import android.util.FeatureFlagUtils; import com.android.internal.util.ArrayUtils; import com.android.settings.R; import com.android.settings.bluetooth.Utils; import com.android.settings.core.BasePreferenceController; import com.android.settings.core.FeatureFlags; import com.android.settingslib.bluetooth.A2dpProfile; import com.android.settingslib.bluetooth.BluetoothCallback; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.HeadsetProfile; import com.android.settingslib.bluetooth.HearingAidProfile; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; import java.util.ArrayList; import java.util.List; /** Loading @@ -65,12 +72,12 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont private static final int INVALID_INDEX = -1; protected final List<BluetoothDevice> mConnectedDevices; protected final AudioManager mAudioManager; protected final MediaRouter mMediaRouter; protected final LocalBluetoothProfileManager mProfileManager; protected int mSelectedIndex; protected Preference mPreference; protected List<BluetoothDevice> mConnectedDevices; private final AudioManagerAudioDeviceCallback mAudioManagerAudioDeviceCallback; private final LocalBluetoothManager mLocalBluetoothManager; Loading @@ -89,6 +96,7 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont mAudioManagerAudioDeviceCallback = new AudioManagerAudioDeviceCallback(); mReceiver = new WiredHeadsetBroadcastReceiver(); mMediaRouterCallback = new MediaRouterCallback(); mConnectedDevices = new ArrayList<>(); } /** Loading Loading @@ -195,12 +203,105 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont } protected boolean isStreamFromOutputDevice(int streamType, int device) { return mAudioManager.getDevicesForStream(streamType) == device; return (device & mAudioManager.getDevicesForStream(streamType)) != 0; } /** * get hands free profile(HFP) connected device */ protected List<BluetoothDevice> getConnectedHfpDevices() { final List<BluetoothDevice> connectedDevices = new ArrayList<>(); final HeadsetProfile hfpProfile = mProfileManager.getHeadsetProfile(); if (hfpProfile == null) { return connectedDevices; } final List<BluetoothDevice> devices = hfpProfile.getConnectedDevices(); for (BluetoothDevice device : devices) { if (device.isConnected()) { connectedDevices.add(device); } } return connectedDevices; } /** * get A2dp connected device */ protected List<BluetoothDevice> getConnectedA2dpDevices() { final List<BluetoothDevice> connectedDevices = new ArrayList<>(); final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile(); if (a2dpProfile == null) { return connectedDevices; } final List<BluetoothDevice> devices = a2dpProfile.getConnectedDevices(); for (BluetoothDevice device : devices) { if (device.isConnected()) { connectedDevices.add(device); } } return connectedDevices; } /** * get hearing aid profile connected device, exclude other devices with same hiSyncId. */ protected List<BluetoothDevice> getConnectedHearingAidDevices() { 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.getConnectedDevices(); 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) && device.isConnected()) { devicesHiSyncIds.add(hiSyncId); connectedDevices.add(device); } } return connectedDevices; } /** * According to different stream and output device, find the active device from * the corresponding profile. Hearing aid device could stream both STREAM_MUSIC * and STREAM_VOICE_CALL. * * @param streamType the type of audio streams. * @return the active device. Return null if the active device is current device * or streamType is not STREAM_MUSIC or STREAM_VOICE_CALL. */ protected BluetoothDevice findActiveDevice(int streamType) { if (streamType != STREAM_MUSIC && streamType != STREAM_VOICE_CALL) { return null; } if (isStreamFromOutputDevice(STREAM_MUSIC, DEVICE_OUT_ALL_A2DP)) { return mProfileManager.getA2dpProfile().getActiveDevice(); } else if (isStreamFromOutputDevice(STREAM_VOICE_CALL, DEVICE_OUT_ALL_SCO)) { return mProfileManager.getHeadsetProfile().getActiveDevice(); } else if (isStreamFromOutputDevice(streamType, DEVICE_OUT_HEARING_AID)) { // The first element is the left active device; the second element is // the right active device. And they will have same hiSyncId. If either // or both side is not active, it will be null on that position. List<BluetoothDevice> activeDevices = mProfileManager.getHearingAidProfile().getActiveDevices(); for (BluetoothDevice btDevice : activeDevices) { if (btDevice != null && mConnectedDevices.contains(btDevice)) { // also need to check mConnectedDevices, because one of // the device(same hiSyncId) might not be shown in the UI. return btDevice; } } } return null; } int getDefaultDeviceIndex() { // Default device is after all connected devices. return ArrayUtils.size(mConnectedDevices); return mConnectedDevices.size(); } void setupPreferenceEntries(CharSequence[] mediaOutputs, CharSequence[] mediaValues, Loading Loading @@ -261,7 +362,7 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont mContext.unregisterReceiver(mReceiver); } /** Callback for headset plugged and unplugged events. */ /** Notifications of audio device connection and disconnection events. */ private class AudioManagerAudioDeviceCallback extends AudioDeviceCallback { @Override public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) { Loading src/com/android/settings/sound/HandsFreeProfileOutputPreferenceController.java +23 −14 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.settings.sound; import static android.bluetooth.IBluetoothHearingAid.HI_SYNC_ID_INVALID; import static android.media.AudioManager.STREAM_VOICE_CALL; import static android.media.AudioSystem.DEVICE_OUT_USB_HEADSET; Loading @@ -25,12 +26,12 @@ import android.bluetooth.BluetoothDevice; import android.content.Context; import androidx.preference.Preference; import com.android.internal.util.ArrayUtils; import com.android.settings.R; import com.android.settingslib.bluetooth.HeadsetProfile; import com.android.settingslib.bluetooth.HearingAidProfile; /** * This class allows switching between HFP-connected BT devices * This class allows switching between HFP-connected & HAP-connected BT devices * while in on-call state. */ public class HandsFreeProfileOutputPreferenceController extends Loading @@ -57,16 +58,11 @@ public class HandsFreeProfileOutputPreferenceController extends // Ongoing call status, list all the connected devices support hands free profile. // Select current active device. // Disable switch entry if there is no connected device. mConnectedDevices = null; BluetoothDevice activeDevice = null; mConnectedDevices.clear(); mConnectedDevices.addAll(getConnectedHfpDevices()); mConnectedDevices.addAll(getConnectedHearingAidDevices()); final HeadsetProfile headsetProfile = mProfileManager.getHeadsetProfile(); if (headsetProfile != null) { mConnectedDevices = headsetProfile.getConnectedDevices(); activeDevice = headsetProfile.getActiveDevice(); } final int numDevices = ArrayUtils.size(mConnectedDevices); final int numDevices = mConnectedDevices.size(); if (numDevices == 0) { // No connected devices, disable switch entry. mPreference.setVisible(false); Loading @@ -79,7 +75,7 @@ public class HandsFreeProfileOutputPreferenceController extends CharSequence[] mediaValues = new CharSequence[numDevices + 1]; // Setup devices entries, select active connected device setupPreferenceEntries(mediaOutputs, mediaValues, activeDevice); setupPreferenceEntries(mediaOutputs, mediaValues, findActiveDevice(STREAM_VOICE_CALL)); if (isStreamFromOutputDevice(STREAM_VOICE_CALL, DEVICE_OUT_USB_HEADSET)) { // If wired headset is plugged in and active, select to default device. Loading @@ -92,8 +88,21 @@ public class HandsFreeProfileOutputPreferenceController extends @Override public void setActiveBluetoothDevice(BluetoothDevice device) { if (Utils.isAudioModeOngoingCall(mContext)) { mProfileManager.getHeadsetProfile().setActiveDevice(device); if (!Utils.isAudioModeOngoingCall(mContext)) { return; } final HearingAidProfile hapProfile = mProfileManager.getHearingAidProfile(); final HeadsetProfile hfpProfile = mProfileManager.getHeadsetProfile(); if (hapProfile != null && hfpProfile != null && device == null) { hfpProfile.setActiveDevice(null); hapProfile.setActiveDevice(null); return; } if (hapProfile != null && hapProfile.getHiSyncId(device) != HI_SYNC_ID_INVALID) { hapProfile.setActiveDevice(device); } if (hfpProfile != null) { hfpProfile.setActiveDevice(device); } } } src/com/android/settings/sound/MediaOutputPreferenceController.java +23 −14 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ 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.AudioSystem.DEVICE_OUT_REMOTE_SUBMIX; import static android.media.AudioSystem.DEVICE_OUT_USB_HEADSET; Loading @@ -27,13 +28,12 @@ import android.content.Context; import android.media.AudioManager; import androidx.preference.Preference; import com.android.internal.util.ArrayUtils; import com.android.settings.R; import com.android.settingslib.bluetooth.A2dpProfile; import com.android.settingslib.bluetooth.HearingAidProfile; /** * This class which allows switching between a2dp-connected BT devices. * This class which allows switching between A2dp-connected & HAP-connected BT devices. * A few conditions will disable this switcher: * - No available BT device(s) * - Media stream captured by cast device Loading Loading @@ -67,18 +67,14 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro return; } mConnectedDevices.clear(); // Otherwise, list all of the A2DP connected device and display the active device. mConnectedDevices = null; BluetoothDevice activeDevice = null; if (mAudioManager.getMode() == AudioManager.MODE_NORMAL) { final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile(); if (a2dpProfile != null) { mConnectedDevices = a2dpProfile.getConnectedDevices(); activeDevice = a2dpProfile.getActiveDevice(); } mConnectedDevices.addAll(getConnectedA2dpDevices()); mConnectedDevices.addAll(getConnectedHearingAidDevices()); } final int numDevices = ArrayUtils.size(mConnectedDevices); final int numDevices = mConnectedDevices.size(); if (numDevices == 0) { // Disable switch entry if there is no connected devices. mPreference.setVisible(false); Loading @@ -91,7 +87,7 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro CharSequence[] mediaValues = new CharSequence[numDevices + 1]; // Setup devices entries, select active connected device setupPreferenceEntries(mediaOutputs, mediaValues, activeDevice); setupPreferenceEntries(mediaOutputs, mediaValues, findActiveDevice(STREAM_MUSIC)); if (isStreamFromOutputDevice(STREAM_MUSIC, DEVICE_OUT_USB_HEADSET)) { // If wired headset is plugged in and active, select to default device. Loading @@ -104,8 +100,21 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro @Override public void setActiveBluetoothDevice(BluetoothDevice device) { if (mAudioManager.getMode() == AudioManager.MODE_NORMAL) { mProfileManager.getA2dpProfile().setActiveDevice(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); return; } if (hapProfile != null && hapProfile.getHiSyncId(device) != HI_SYNC_ID_INVALID) { hapProfile.setActiveDevice(device); } if (a2dpProfile != null) { a2dpProfile.setActiveDevice(device); } } } Loading
src/com/android/settings/sound/AudioSwitchPreferenceController.java +107 −6 Original line number Diff line number Diff line Loading @@ -16,8 +16,12 @@ package com.android.settings.sound; import static android.media.AudioManager.STREAM_DEVICES_CHANGED_ACTION; import static android.media.AudioManager.STREAM_MUSIC; import static android.media.AudioManager.STREAM_VOICE_CALL; import static android.media.AudioSystem.DEVICE_OUT_ALL_A2DP; import static android.media.AudioSystem.DEVICE_OUT_ALL_SCO; import static android.media.AudioSystem.DEVICE_OUT_HEARING_AID; import static android.media.MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY; import android.bluetooth.BluetoothDevice; Loading @@ -38,19 +42,22 @@ import androidx.preference.PreferenceScreen; import android.text.TextUtils; import android.util.FeatureFlagUtils; import com.android.internal.util.ArrayUtils; import com.android.settings.R; import com.android.settings.bluetooth.Utils; import com.android.settings.core.BasePreferenceController; import com.android.settings.core.FeatureFlags; import com.android.settingslib.bluetooth.A2dpProfile; import com.android.settingslib.bluetooth.BluetoothCallback; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.HeadsetProfile; import com.android.settingslib.bluetooth.HearingAidProfile; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; import java.util.ArrayList; import java.util.List; /** Loading @@ -65,12 +72,12 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont private static final int INVALID_INDEX = -1; protected final List<BluetoothDevice> mConnectedDevices; protected final AudioManager mAudioManager; protected final MediaRouter mMediaRouter; protected final LocalBluetoothProfileManager mProfileManager; protected int mSelectedIndex; protected Preference mPreference; protected List<BluetoothDevice> mConnectedDevices; private final AudioManagerAudioDeviceCallback mAudioManagerAudioDeviceCallback; private final LocalBluetoothManager mLocalBluetoothManager; Loading @@ -89,6 +96,7 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont mAudioManagerAudioDeviceCallback = new AudioManagerAudioDeviceCallback(); mReceiver = new WiredHeadsetBroadcastReceiver(); mMediaRouterCallback = new MediaRouterCallback(); mConnectedDevices = new ArrayList<>(); } /** Loading Loading @@ -195,12 +203,105 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont } protected boolean isStreamFromOutputDevice(int streamType, int device) { return mAudioManager.getDevicesForStream(streamType) == device; return (device & mAudioManager.getDevicesForStream(streamType)) != 0; } /** * get hands free profile(HFP) connected device */ protected List<BluetoothDevice> getConnectedHfpDevices() { final List<BluetoothDevice> connectedDevices = new ArrayList<>(); final HeadsetProfile hfpProfile = mProfileManager.getHeadsetProfile(); if (hfpProfile == null) { return connectedDevices; } final List<BluetoothDevice> devices = hfpProfile.getConnectedDevices(); for (BluetoothDevice device : devices) { if (device.isConnected()) { connectedDevices.add(device); } } return connectedDevices; } /** * get A2dp connected device */ protected List<BluetoothDevice> getConnectedA2dpDevices() { final List<BluetoothDevice> connectedDevices = new ArrayList<>(); final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile(); if (a2dpProfile == null) { return connectedDevices; } final List<BluetoothDevice> devices = a2dpProfile.getConnectedDevices(); for (BluetoothDevice device : devices) { if (device.isConnected()) { connectedDevices.add(device); } } return connectedDevices; } /** * get hearing aid profile connected device, exclude other devices with same hiSyncId. */ protected List<BluetoothDevice> getConnectedHearingAidDevices() { 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.getConnectedDevices(); 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) && device.isConnected()) { devicesHiSyncIds.add(hiSyncId); connectedDevices.add(device); } } return connectedDevices; } /** * According to different stream and output device, find the active device from * the corresponding profile. Hearing aid device could stream both STREAM_MUSIC * and STREAM_VOICE_CALL. * * @param streamType the type of audio streams. * @return the active device. Return null if the active device is current device * or streamType is not STREAM_MUSIC or STREAM_VOICE_CALL. */ protected BluetoothDevice findActiveDevice(int streamType) { if (streamType != STREAM_MUSIC && streamType != STREAM_VOICE_CALL) { return null; } if (isStreamFromOutputDevice(STREAM_MUSIC, DEVICE_OUT_ALL_A2DP)) { return mProfileManager.getA2dpProfile().getActiveDevice(); } else if (isStreamFromOutputDevice(STREAM_VOICE_CALL, DEVICE_OUT_ALL_SCO)) { return mProfileManager.getHeadsetProfile().getActiveDevice(); } else if (isStreamFromOutputDevice(streamType, DEVICE_OUT_HEARING_AID)) { // The first element is the left active device; the second element is // the right active device. And they will have same hiSyncId. If either // or both side is not active, it will be null on that position. List<BluetoothDevice> activeDevices = mProfileManager.getHearingAidProfile().getActiveDevices(); for (BluetoothDevice btDevice : activeDevices) { if (btDevice != null && mConnectedDevices.contains(btDevice)) { // also need to check mConnectedDevices, because one of // the device(same hiSyncId) might not be shown in the UI. return btDevice; } } } return null; } int getDefaultDeviceIndex() { // Default device is after all connected devices. return ArrayUtils.size(mConnectedDevices); return mConnectedDevices.size(); } void setupPreferenceEntries(CharSequence[] mediaOutputs, CharSequence[] mediaValues, Loading Loading @@ -261,7 +362,7 @@ public abstract class AudioSwitchPreferenceController extends BasePreferenceCont mContext.unregisterReceiver(mReceiver); } /** Callback for headset plugged and unplugged events. */ /** Notifications of audio device connection and disconnection events. */ private class AudioManagerAudioDeviceCallback extends AudioDeviceCallback { @Override public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) { Loading
src/com/android/settings/sound/HandsFreeProfileOutputPreferenceController.java +23 −14 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.settings.sound; import static android.bluetooth.IBluetoothHearingAid.HI_SYNC_ID_INVALID; import static android.media.AudioManager.STREAM_VOICE_CALL; import static android.media.AudioSystem.DEVICE_OUT_USB_HEADSET; Loading @@ -25,12 +26,12 @@ import android.bluetooth.BluetoothDevice; import android.content.Context; import androidx.preference.Preference; import com.android.internal.util.ArrayUtils; import com.android.settings.R; import com.android.settingslib.bluetooth.HeadsetProfile; import com.android.settingslib.bluetooth.HearingAidProfile; /** * This class allows switching between HFP-connected BT devices * This class allows switching between HFP-connected & HAP-connected BT devices * while in on-call state. */ public class HandsFreeProfileOutputPreferenceController extends Loading @@ -57,16 +58,11 @@ public class HandsFreeProfileOutputPreferenceController extends // Ongoing call status, list all the connected devices support hands free profile. // Select current active device. // Disable switch entry if there is no connected device. mConnectedDevices = null; BluetoothDevice activeDevice = null; mConnectedDevices.clear(); mConnectedDevices.addAll(getConnectedHfpDevices()); mConnectedDevices.addAll(getConnectedHearingAidDevices()); final HeadsetProfile headsetProfile = mProfileManager.getHeadsetProfile(); if (headsetProfile != null) { mConnectedDevices = headsetProfile.getConnectedDevices(); activeDevice = headsetProfile.getActiveDevice(); } final int numDevices = ArrayUtils.size(mConnectedDevices); final int numDevices = mConnectedDevices.size(); if (numDevices == 0) { // No connected devices, disable switch entry. mPreference.setVisible(false); Loading @@ -79,7 +75,7 @@ public class HandsFreeProfileOutputPreferenceController extends CharSequence[] mediaValues = new CharSequence[numDevices + 1]; // Setup devices entries, select active connected device setupPreferenceEntries(mediaOutputs, mediaValues, activeDevice); setupPreferenceEntries(mediaOutputs, mediaValues, findActiveDevice(STREAM_VOICE_CALL)); if (isStreamFromOutputDevice(STREAM_VOICE_CALL, DEVICE_OUT_USB_HEADSET)) { // If wired headset is plugged in and active, select to default device. Loading @@ -92,8 +88,21 @@ public class HandsFreeProfileOutputPreferenceController extends @Override public void setActiveBluetoothDevice(BluetoothDevice device) { if (Utils.isAudioModeOngoingCall(mContext)) { mProfileManager.getHeadsetProfile().setActiveDevice(device); if (!Utils.isAudioModeOngoingCall(mContext)) { return; } final HearingAidProfile hapProfile = mProfileManager.getHearingAidProfile(); final HeadsetProfile hfpProfile = mProfileManager.getHeadsetProfile(); if (hapProfile != null && hfpProfile != null && device == null) { hfpProfile.setActiveDevice(null); hapProfile.setActiveDevice(null); return; } if (hapProfile != null && hapProfile.getHiSyncId(device) != HI_SYNC_ID_INVALID) { hapProfile.setActiveDevice(device); } if (hfpProfile != null) { hfpProfile.setActiveDevice(device); } } }
src/com/android/settings/sound/MediaOutputPreferenceController.java +23 −14 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ 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.AudioSystem.DEVICE_OUT_REMOTE_SUBMIX; import static android.media.AudioSystem.DEVICE_OUT_USB_HEADSET; Loading @@ -27,13 +28,12 @@ import android.content.Context; import android.media.AudioManager; import androidx.preference.Preference; import com.android.internal.util.ArrayUtils; import com.android.settings.R; import com.android.settingslib.bluetooth.A2dpProfile; import com.android.settingslib.bluetooth.HearingAidProfile; /** * This class which allows switching between a2dp-connected BT devices. * This class which allows switching between A2dp-connected & HAP-connected BT devices. * A few conditions will disable this switcher: * - No available BT device(s) * - Media stream captured by cast device Loading Loading @@ -67,18 +67,14 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro return; } mConnectedDevices.clear(); // Otherwise, list all of the A2DP connected device and display the active device. mConnectedDevices = null; BluetoothDevice activeDevice = null; if (mAudioManager.getMode() == AudioManager.MODE_NORMAL) { final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile(); if (a2dpProfile != null) { mConnectedDevices = a2dpProfile.getConnectedDevices(); activeDevice = a2dpProfile.getActiveDevice(); } mConnectedDevices.addAll(getConnectedA2dpDevices()); mConnectedDevices.addAll(getConnectedHearingAidDevices()); } final int numDevices = ArrayUtils.size(mConnectedDevices); final int numDevices = mConnectedDevices.size(); if (numDevices == 0) { // Disable switch entry if there is no connected devices. mPreference.setVisible(false); Loading @@ -91,7 +87,7 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro CharSequence[] mediaValues = new CharSequence[numDevices + 1]; // Setup devices entries, select active connected device setupPreferenceEntries(mediaOutputs, mediaValues, activeDevice); setupPreferenceEntries(mediaOutputs, mediaValues, findActiveDevice(STREAM_MUSIC)); if (isStreamFromOutputDevice(STREAM_MUSIC, DEVICE_OUT_USB_HEADSET)) { // If wired headset is plugged in and active, select to default device. Loading @@ -104,8 +100,21 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro @Override public void setActiveBluetoothDevice(BluetoothDevice device) { if (mAudioManager.getMode() == AudioManager.MODE_NORMAL) { mProfileManager.getA2dpProfile().setActiveDevice(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); return; } if (hapProfile != null && hapProfile.getHiSyncId(device) != HI_SYNC_ID_INVALID) { hapProfile.setActiveDevice(device); } if (a2dpProfile != null) { a2dpProfile.setActiveDevice(device); } } }