diff options
author | 2020-06-22 04:30:30 +0000 | |
---|---|---|
committer | 2020-06-22 04:30:30 +0000 | |
commit | 4b6472722e763d1aa9ba4abcb302a671d2fb9354 (patch) | |
tree | 07d420d40a3b3c5f1e3db452bdd18396769cd1ab | |
parent | 98e874e58590a3dd76e6c5aa5d5bc42bdf01ecfe (diff) | |
parent | e1b8006e2bedf8a7ae2c4cf489ab424804b77730 (diff) |
Merge "Handle multiple active bluetooth devices" into rvc-dev
-rw-r--r-- | media/java/android/media/MediaRouter2Manager.java | 2 | ||||
-rw-r--r-- | services/core/java/com/android/server/media/BluetoothRouteProvider.java | 126 |
2 files changed, 94 insertions, 34 deletions
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java index 773263865135..ce036deb6164 100644 --- a/media/java/android/media/MediaRouter2Manager.java +++ b/media/java/android/media/MediaRouter2Manager.java @@ -344,6 +344,8 @@ public final class MediaRouter2Manager { Objects.requireNonNull(sessionInfo, "sessionInfo must not be null"); Objects.requireNonNull(route, "route must not be null"); + Log.v(TAG, "Transferring routing session. session= " + sessionInfo + ", route=" + route); + synchronized (mRoutesLock) { if (!mRoutes.containsKey(route.getId())) { Log.w(TAG, "transfer: Ignoring an unknown route id=" + route.getId()); diff --git a/services/core/java/com/android/server/media/BluetoothRouteProvider.java b/services/core/java/com/android/server/media/BluetoothRouteProvider.java index 4def7db76bc5..25d54db0f839 100644 --- a/services/core/java/com/android/server/media/BluetoothRouteProvider.java +++ b/services/core/java/com/android/server/media/BluetoothRouteProvider.java @@ -17,6 +17,8 @@ package com.android.server.media; import static android.bluetooth.BluetoothAdapter.ACTIVE_DEVICE_AUDIO; +import static android.bluetooth.BluetoothAdapter.STATE_CONNECTED; +import static android.bluetooth.BluetoothAdapter.STATE_DISCONNECTED; import android.annotation.NonNull; import android.annotation.Nullable; @@ -33,6 +35,7 @@ import android.media.AudioManager; import android.media.AudioSystem; import android.media.MediaRoute2Info; import android.text.TextUtils; +import android.util.Log; import android.util.Slog; import android.util.SparseBooleanArray; import android.util.SparseIntArray; @@ -48,6 +51,8 @@ import java.util.Objects; class BluetoothRouteProvider { private static final String TAG = "BTRouteProvider"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + private static final String HEARING_AID_ROUTE_ID_PREFIX = "HEARING_AID_"; private static BluetoothRouteProvider sInstance; @@ -55,7 +60,7 @@ class BluetoothRouteProvider { // Maps hardware address to BluetoothRouteInfo final Map<String, BluetoothRouteInfo> mBluetoothRoutes = new HashMap<>(); @SuppressWarnings("WeakerAccess") /* synthetic access */ - BluetoothRouteInfo mSelectedRoute = null; + final List<BluetoothRouteInfo> mActiveRoutes = new ArrayList<>(); @SuppressWarnings("WeakerAccess") /* synthetic access */ BluetoothA2dp mA2dpProfile; @SuppressWarnings("WeakerAccess") /* synthetic access */ @@ -104,7 +109,7 @@ class BluetoothRouteProvider { // Bluetooth on/off broadcasts addEventReceiver(BluetoothAdapter.ACTION_STATE_CHANGED, new AdapterStateChangedReceiver()); - DeviceStateChangedRecevier deviceStateChangedReceiver = new DeviceStateChangedRecevier(); + DeviceStateChangedReceiver deviceStateChangedReceiver = new DeviceStateChangedReceiver(); addEventReceiver(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED, deviceStateChangedReceiver); addEventReceiver(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED, deviceStateChangedReceiver); addEventReceiver(BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED, @@ -168,14 +173,16 @@ class BluetoothRouteProvider { @Nullable MediaRoute2Info getSelectedRoute() { - return (mSelectedRoute == null) ? null : mSelectedRoute.route; + // For now, active routes can be multiple only when a pair of hearing aid devices is active. + // Let the first active device represent them. + return (mActiveRoutes.isEmpty() ? null : mActiveRoutes.get(0).route); } @NonNull List<MediaRoute2Info> getTransferableRoutes() { List<MediaRoute2Info> routes = getAllBluetoothRoutes(); - if (mSelectedRoute != null) { - routes.remove(mSelectedRoute.route); + for (BluetoothRouteInfo btRoute : mActiveRoutes) { + routes.remove(btRoute.route); } return routes; } @@ -185,8 +192,14 @@ class BluetoothRouteProvider { List<MediaRoute2Info> routes = new ArrayList<>(); List<String> routeIds = new ArrayList<>(); + MediaRoute2Info selectedRoute = getSelectedRoute(); + if (selectedRoute != null) { + routes.add(selectedRoute); + routeIds.add(selectedRoute.getId()); + } + for (BluetoothRouteInfo btRoute : mBluetoothRoutes.values()) { - // A pair of hearing aid devices or the same hardware address + // A pair of hearing aid devices or having the same hardware address if (routeIds.contains(btRoute.route.getId())) { continue; } @@ -225,13 +238,20 @@ class BluetoothRouteProvider { return false; } mVolumeMap.put(routeType, volume); - if (mSelectedRoute == null || mSelectedRoute.route.getType() != routeType) { - return true; + + boolean shouldNotify = false; + for (BluetoothRouteInfo btRoute : mActiveRoutes) { + if (btRoute.route.getType() != routeType) { + continue; + } + btRoute.route = new MediaRoute2Info.Builder(btRoute.route) + .setVolume(volume) + .build(); + shouldNotify = true; + } + if (shouldNotify) { + notifyBluetoothRoutesUpdated(); } - mSelectedRoute.route = new MediaRoute2Info.Builder(mSelectedRoute.route) - .setVolume(volume) - .build(); - notifyBluetoothRoutesUpdated(); return true; } @@ -297,6 +317,53 @@ class BluetoothRouteProvider { btRoute.route = builder.build(); } + private void clearActiveRoutes() { + if (DEBUG) { + Log.d(TAG, "Clearing active routes"); + } + for (BluetoothRouteInfo btRoute : mActiveRoutes) { + setRouteConnectionState(btRoute, STATE_DISCONNECTED); + } + mActiveRoutes.clear(); + } + + private void addActiveRoute(BluetoothRouteInfo btRoute) { + if (DEBUG) { + Log.d(TAG, "Adding active route: " + btRoute.route); + } + if (btRoute == null || mActiveRoutes.contains(btRoute)) { + return; + } + setRouteConnectionState(btRoute, STATE_CONNECTED); + mActiveRoutes.add(btRoute); + } + + private void removeActiveRoute(BluetoothRouteInfo btRoute) { + if (DEBUG) { + Log.d(TAG, "Removing active route: " + btRoute.route); + } + if (mActiveRoutes.remove(btRoute)) { + setRouteConnectionState(btRoute, STATE_DISCONNECTED); + } + } + + private void findAndSetActiveHearingAidDevices() { + if (DEBUG) { + Log.d(TAG, "Setting active hearing aid devices"); + } + + BluetoothHearingAid hearingAidProfile = mHearingAidProfile; + if (hearingAidProfile == null) { + return; + } + List<BluetoothDevice> activeDevices = hearingAidProfile.getActiveDevices(); + for (BluetoothRouteInfo btRoute : mBluetoothRoutes.values()) { + if (activeDevices.contains(btRoute.btDevice)) { + addActiveRoute(btRoute); + } + } + } + interface BluetoothRoutesUpdatedListener { void onBluetoothRoutesUpdated(@NonNull List<MediaRoute2Info> routes); } @@ -333,7 +400,6 @@ class BluetoothRouteProvider { default: return; } - //TODO(b/157708273): Handle two active devices in the binaural case. for (BluetoothDevice device : proxy.getConnectedDevices()) { BluetoothRouteInfo btRoute = mBluetoothRoutes.get(device.getAddress()); if (btRoute == null) { @@ -341,9 +407,7 @@ class BluetoothRouteProvider { mBluetoothRoutes.put(device.getAddress(), btRoute); } if (activeDevices.contains(device)) { - mSelectedRoute = btRoute; - setRouteConnectionState(mSelectedRoute, - MediaRoute2Info.CONNECTION_STATE_CONNECTED); + addActiveRoute(btRoute); } } notifyBluetoothRoutesUpdated(); @@ -395,26 +459,23 @@ class BluetoothRouteProvider { } } - private class DeviceStateChangedRecevier implements BluetoothEventReceiver { + private class DeviceStateChangedReceiver implements BluetoothEventReceiver { @Override public void onReceive(Context context, Intent intent, BluetoothDevice device) { switch (intent.getAction()) { case BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED: + clearActiveRoutes(); + if (device != null) { + addActiveRoute(mBluetoothRoutes.get(device.getAddress())); + } + notifyBluetoothRoutesUpdated(); + break; case BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED: - if (mSelectedRoute == null - || !mSelectedRoute.btDevice.equals(device)) { - if (mSelectedRoute != null) { - setRouteConnectionState(mSelectedRoute, - MediaRoute2Info.CONNECTION_STATE_DISCONNECTED); - } - mSelectedRoute = (device == null) ? null - : mBluetoothRoutes.get(device.getAddress()); - if (mSelectedRoute != null) { - setRouteConnectionState(mSelectedRoute, - MediaRoute2Info.CONNECTION_STATE_CONNECTED); - } - notifyBluetoothRoutesUpdated(); + clearActiveDevices(); + if (device != null) { + findAndSetActiveHearingAidDevices(); } + notifyBluetoothRoutesUpdated(); break; case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED: handleConnectionStateChanged(BluetoothProfile.A2DP, intent, device); @@ -444,10 +505,7 @@ class BluetoothRouteProvider { if (btRoute != null) { btRoute.connectedProfiles.delete(profile); if (btRoute.connectedProfiles.size() == 0) { - mBluetoothRoutes.remove(device.getAddress()); - if (mSelectedRoute != null && mSelectedRoute.btDevice.equals(device)) { - mSelectedRoute = null; - } + removeActiveRoute(mBluetoothRoutes.remove(device.getAddress())); notifyBluetoothRoutesUpdated(); } } |