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

Commit 45bc4df3 authored by Grant Menke's avatar Grant Menke
Browse files

Skip Switch To Baseline when Audio Route is not BT.

This CL resolves a call audio routing bug by skipping the switch back to baseline when when call audio is not currently routed to bluetooth in BluetoothDeviceManager#handleAudioRefactoringServiceDisconnected. This resolves a bug where the audio would be errantly routed to earpeiece when BT is disabled while the call is routed to speaker.

Flag: com.android.server.telecom.flags.skip_baseline_switch_when_route_not_bluetooth
Test: build + manual + atest BluetoothDeviceManagerTest
Fixes: 382118789
Change-Id: I355ffcdf94e034a143a057036562b622370f540e
parent 06d8c745
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -18,3 +18,13 @@ flag {
    purpose: PURPOSE_BUGFIX
  }
}
# OWNER=grantmenke TARGET=25Q2
flag {
  name: "skip_baseline_switch_when_route_not_bluetooth"
  namespace: "telecom"
  description: "Only switch back to baseline if the call audio is currently routed to bluetooth"
  bug: "333417369"
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}
 No newline at end of file
+20 −3
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.content.Context;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.os.Bundle;
import android.telecom.CallAudioState;
import android.telecom.Log;
import android.util.ArraySet;
import android.util.LocalLog;
@@ -233,7 +234,8 @@ public class BluetoothDeviceManager {
                }
           };

    private void handleAudioRefactoringServiceDisconnected(int profile) {
    @VisibleForTesting
    public void handleAudioRefactoringServiceDisconnected(int profile) {
        CallAudioRouteController controller = (CallAudioRouteController)
                mCallAudioRouteAdapter;
        Map<AudioRoute, BluetoothDevice> btRoutes = controller
@@ -257,9 +259,24 @@ public class BluetoothDeviceManager {
            mCallAudioRouteAdapter.sendMessageWithSessionInfo(
                    BT_DEVICE_REMOVED, route.getType(), device);
        }

        if (mFeatureFlags.skipBaselineSwitchWhenRouteNotBluetooth()) {
            CallAudioState currentAudioState = controller.getCurrentCallAudioState();
            int currentRoute = currentAudioState.getRoute();
            if (currentRoute == CallAudioState.ROUTE_BLUETOOTH) {
                Log.d(this, "handleAudioRefactoringServiceDisconnected: call audio "
                        + "is currently routed to BT so switching back to baseline");
                mCallAudioRouteAdapter.sendMessageWithSessionInfo(
                        SWITCH_BASELINE_ROUTE, INCLUDE_BLUETOOTH_IN_BASELINE, (String) null);
            } else {
                Log.d(this, "handleAudioRefactoringServiceDisconnected: call audio "
                        + "is not currently routed to BT so skipping switch to baseline");
            }
        } else {
            mCallAudioRouteAdapter.sendMessageWithSessionInfo(
                    SWITCH_BASELINE_ROUTE, INCLUDE_BLUETOOTH_IN_BASELINE, (String) null);
        }
    }

    private final LinkedHashMap<String, BluetoothDevice> mHfpDevicesByAddress =
            new LinkedHashMap<>();
+43 −0
Original line number Diff line number Diff line
@@ -18,6 +18,9 @@ package com.android.server.telecom.tests;

import static android.media.AudioDeviceInfo.TYPE_BUILTIN_SPEAKER;

import static com.android.server.telecom.CallAudioRouteAdapter.SWITCH_BASELINE_ROUTE;
import static com.android.server.telecom.CallAudioRouteController.INCLUDE_BLUETOOTH_IN_BASELINE;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
@@ -44,11 +47,14 @@ import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Parcel;
import android.telecom.CallAudioState;

import androidx.test.filters.SmallTest;

import com.android.server.telecom.AudioRoute;
import com.android.server.telecom.CallAudioCommunicationDeviceTracker;
import com.android.server.telecom.CallAudioRouteAdapter;
import com.android.server.telecom.CallAudioRouteController;
import com.android.server.telecom.bluetooth.BluetoothDeviceManager;
import com.android.server.telecom.bluetooth.BluetoothRouteManager;
import com.android.server.telecom.bluetooth.BluetoothStateReceiver;
@@ -64,7 +70,9 @@ import org.mockito.Mock;
import static org.mockito.Mockito.reset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;

@RunWith(JUnit4.class)
@@ -79,6 +87,8 @@ public class BluetoothDeviceManagerTest extends TelecomTestCase {
    @Mock AudioManager mockAudioManager;
    @Mock AudioDeviceInfo mSpeakerInfo;
    @Mock Executor mExecutor;
    @Mock CallAudioRouteController mCallAudioRouteController;
    @Mock CallAudioState mCallAudioState;

    BluetoothDeviceManager mBluetoothDeviceManager;
    BluetoothProfile.ServiceListener serviceListenerUnderTest;
@@ -115,6 +125,7 @@ public class BluetoothDeviceManagerTest extends TelecomTestCase {
        mBluetoothDeviceManager = new BluetoothDeviceManager(mContext, mAdapter,
                mCommunicationDeviceTracker, mFeatureFlags);
        mBluetoothDeviceManager.setBluetoothRouteManager(mRouteManager);
        mBluetoothDeviceManager.setCallAudioRouteAdapter(mCallAudioRouteController);
        mCommunicationDeviceTracker.setBluetoothRouteManager(mRouteManager);

        mockAudioManager = mContext.getSystemService(AudioManager.class);
@@ -297,6 +308,38 @@ public class BluetoothDeviceManagerTest extends TelecomTestCase {
        assertEquals(2, mBluetoothDeviceManager.getUniqueConnectedDevices().size());
    }

    @SmallTest
    @Test
    public void testHandleAudioRefactoringServiceDisconnectedWhileBluetooth() {
        when(mFeatureFlags.skipBaselineSwitchWhenRouteNotBluetooth()).thenReturn(true);
        Map<AudioRoute, BluetoothDevice> btRoutes = new HashMap<>();
        when(mCallAudioRouteController.getBluetoothRoutes()).thenReturn(btRoutes);
        when(mCallAudioRouteController.getCurrentCallAudioState()).thenReturn(mCallAudioState);
        when(mCallAudioState.getRoute()).thenReturn(CallAudioState.ROUTE_BLUETOOTH);

        mBluetoothDeviceManager
                .handleAudioRefactoringServiceDisconnected(BluetoothProfile.LE_AUDIO);

        verify(mCallAudioRouteController).sendMessageWithSessionInfo(SWITCH_BASELINE_ROUTE,
                INCLUDE_BLUETOOTH_IN_BASELINE, (String) null);
    }

    @SmallTest
    @Test
    public void testHandleAudioRefactoringServiceDisconnectedWhileSpeaker() {
        when(mFeatureFlags.skipBaselineSwitchWhenRouteNotBluetooth()).thenReturn(true);
        Map<AudioRoute, BluetoothDevice> btRoutes = new HashMap<>();
        when(mCallAudioRouteController.getBluetoothRoutes()).thenReturn(btRoutes);
        when(mCallAudioRouteController.getCurrentCallAudioState()).thenReturn(mCallAudioState);
        when(mCallAudioState.getRoute()).thenReturn(CallAudioState.ROUTE_SPEAKER);

        mBluetoothDeviceManager
                .handleAudioRefactoringServiceDisconnected(BluetoothProfile.LE_AUDIO);

        verify(mCallAudioRouteController, never()).sendMessageWithSessionInfo(SWITCH_BASELINE_ROUTE,
                INCLUDE_BLUETOOTH_IN_BASELINE, (String) null);
    }

    @SmallTest
    @Test
    public void testHeadsetServiceDisconnect() {