Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cabe9dd4 authored by Pranav Madapurmath's avatar Pranav Madapurmath
Browse files

Resolve multiple BT device switching and active device updates

This CL fixes issues found around device switching between multiple
BT devices (LE) where we reroute back into the same device. We should
exclude the BT address for the device which became inactive so
that it isn't selected in the base routing.

Bug: 372197811
Test: Manual log verification from QA test
Flag: com.android.server.telecom.flags.resolve_active_bt_routing_and_bt_timing_issue
Change-Id: Ie19342494687ec6b7cd80d598cc242c5a1a5e9fa
parent 54d56453
Loading
Loading
Loading
Loading
+37 −5
Original line number Diff line number Diff line
@@ -766,6 +766,7 @@ public class CallAudioRouteController implements CallAudioRouteAdapter {
        if (bluetoothRoute != null) {
            Log.i(this, "request to route to bluetooth route: %s (active=%b)", bluetoothRoute,
                    mIsActive);
            updateActiveBluetoothDevice(new Pair<>(type, deviceAddress));
            routeTo(mIsActive, bluetoothRoute);
        } else {
            Log.i(this, "request to route to unavailable bluetooth route - type (%s), address (%s)",
@@ -784,10 +785,34 @@ public class CallAudioRouteController implements CallAudioRouteAdapter {
     * Message being handled: BT_ACTIVE_DEVICE_GONE
     */
    private void handleBtActiveDeviceGone(@AudioRoute.AudioRouteType int type) {
        if ((mIsPending && mPendingAudioRoute.getDestRoute().getType() == type)
                || (!mIsPending && mCurrentRoute.getType() == type)) {
            // Fallback to an available route
            routeTo(mIsActive, getBaseRoute(true, null));
        // Determine what the active device for the BT audio type was so that we can exclude this
        // device from being used when calculating the base route.
        String previouslyActiveDeviceAddress = mFeatureFlags
                .resolveActiveBtRoutingAndBtTimingIssue()
                ? mActiveDeviceCache.get(type)
                : null;
        // It's possible that the dest route hasn't been set yet when the controller is first
        // initialized.
        boolean pendingRouteNeedsUpdate = mPendingAudioRoute.getDestRoute() != null
                && mPendingAudioRoute.getDestRoute().getType() == type;
        boolean currentRouteNeedsUpdate = mCurrentRoute.getType() == type;
        if (mFeatureFlags.resolveActiveBtRoutingAndBtTimingIssue()) {
            if (pendingRouteNeedsUpdate) {
                pendingRouteNeedsUpdate &= mPendingAudioRoute.getDestRoute().getBluetoothAddress()
                        .equals(previouslyActiveDeviceAddress);
            }
            if (currentRouteNeedsUpdate) {
                currentRouteNeedsUpdate &= mCurrentRoute.getBluetoothAddress()
                        .equals(previouslyActiveDeviceAddress);
            }
        }
        if ((mIsPending && pendingRouteNeedsUpdate) || (!mIsPending && currentRouteNeedsUpdate)) {
            // Fallback to an available route excluding the previously active device.
            routeTo(mIsActive, getBaseRoute(true, previouslyActiveDeviceAddress));
        }
        // Clear out the active device for the BT audio type.
        if (mFeatureFlags.resolveActiveBtRoutingAndBtTimingIssue()) {
            updateActiveBluetoothDevice(new Pair(type, null));
        }
    }

@@ -1490,9 +1515,16 @@ public class CallAudioRouteController implements CallAudioRouteAdapter {
            // If a device was removed, check to ensure that no other device is still considered
            // active.
            boolean hasActiveDevice = false;
            for (String address : mActiveDeviceCache.values()) {
            List<Map.Entry<Integer, String>> activeBtDevices = new ArrayList<>(
                    mActiveDeviceCache.entrySet());
            for (Map.Entry<Integer,String> activeDevice : activeBtDevices) {
                Integer btAudioType = activeDevice.getKey();
                String address = activeDevice.getValue();
                if (address != null) {
                    hasActiveDevice = true;
                    if (mFeatureFlags.resolveActiveBtRoutingAndBtTimingIssue()) {
                        mActiveBluetoothDevice = new Pair<>(btAudioType, address);
                    }
                    break;
                }
            }
+13 −6
Original line number Diff line number Diff line
@@ -252,12 +252,17 @@ public class BluetoothStateReceiver extends BroadcastReceiver {
            CallAudioRouteController audioRouteController = (CallAudioRouteController)
                    mCallAudioRouteAdapter;
            if (device == null) {
                audioRouteController.updateActiveBluetoothDevice(new Pair(audioRouteType, null));
                if (!mFeatureFlags.resolveActiveBtRoutingAndBtTimingIssue()) {
                    audioRouteController.updateActiveBluetoothDevice(
                            new Pair(audioRouteType, null));
                }
                mCallAudioRouteAdapter.sendMessageWithSessionInfo(BT_ACTIVE_DEVICE_GONE,
                        audioRouteType);
            } else {
                if (!mFeatureFlags.resolveActiveBtRoutingAndBtTimingIssue()) {
                    audioRouteController.updateActiveBluetoothDevice(
                            new Pair(audioRouteType, device.getAddress()));
                }
                mCallAudioRouteAdapter.sendMessageWithSessionInfo(BT_ACTIVE_DEVICE_PRESENT,
                        audioRouteType, device.getAddress());
                if (deviceType == BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID
@@ -267,9 +272,11 @@ public class BluetoothStateReceiver extends BroadcastReceiver {
                        Log.i(this, "handleActiveDeviceChanged: Failed to set "
                                + "communication device for %s. Sending PENDING_ROUTE_FAILED to "
                                + "pending audio route.", device);
                        if (!mFeatureFlags.resolveActiveBtRoutingAndBtTimingIssue()) {
                            mCallAudioRouteAdapter.getPendingAudioRoute()
                                    .onMessageReceived(new Pair<>(PENDING_ROUTE_FAILED,
                                            device.getAddress()), device.getAddress());
                        }
                    } else {
                        // Track the currently set communication device.
                        int routeType = deviceType == BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO