Fix default microphone for calls sometimes not work and not show UI
Root Cause: Only setMicrophonePreferredForCalls and show UI to current device, but audioManager might hold other device in the same set Solution: setMicrophonePreferredForCalls to whole device set and also check if any address in device set contain in audioManager GET_DEVICES_INPUTS list Bug: 392902067 Test: atest BluetoothDetailsHearingDeviceInputRoutingControllerTest Flag: EXEMPT bugfix Change-Id: Ic5846de26df4a8db67fa8efcf474fa4509f7918a
This commit is contained in:
@@ -20,11 +20,13 @@ import static com.android.settings.bluetooth.BluetoothDetailsHearingDeviceContro
|
||||
import static com.android.settings.bluetooth.BluetoothDetailsHearingDeviceController.ORDER_HEARING_DEVICE_INPUT_ROUTING;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioDeviceInfo;
|
||||
import android.media.AudioManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.collection.ArraySet;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
@@ -38,6 +40,7 @@ import com.android.settingslib.bluetooth.HearingAidAudioRoutingHelper;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The controller of the hearing device input routing
|
||||
@@ -66,15 +69,25 @@ public class BluetoothDetailsHearingDeviceInputRoutingController extends
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
boolean isSupportedProfile = mCachedDevice.getProfiles().stream().anyMatch(
|
||||
final Set<CachedBluetoothDevice> memberDevices = mCachedDevice.getMemberDevice();
|
||||
final AudioDeviceInfo[] inputInfos = mAudioManager.getDevices(
|
||||
AudioManager.GET_DEVICES_INPUTS);
|
||||
final Set<String> supportedInputDeviceAddresses = new ArraySet<>();
|
||||
supportedInputDeviceAddresses.add(mCachedDevice.getAddress());
|
||||
if (!memberDevices.isEmpty()) {
|
||||
memberDevices.forEach(member -> supportedInputDeviceAddresses.add(member.getAddress()));
|
||||
}
|
||||
|
||||
boolean isHapHearingDevice = mCachedDevice.getProfiles().stream().anyMatch(
|
||||
profile -> profile instanceof HapClientProfile);
|
||||
boolean isSupportedInputDevice = Arrays.stream(
|
||||
mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)).anyMatch(
|
||||
info -> mCachedDevice.getAddress().equals(info.getAddress()));
|
||||
if (isSupportedProfile && !isSupportedInputDevice) {
|
||||
// Not support ASHA hearing device for input routing feature
|
||||
boolean isValidInputDevice = Arrays.stream(inputInfos).anyMatch(
|
||||
info -> supportedInputDeviceAddresses.contains(info.getAddress()));
|
||||
|
||||
if (isHapHearingDevice && !isValidInputDevice) {
|
||||
Log.d(TAG, "Not supported input type hearing device.");
|
||||
}
|
||||
return isSupportedProfile && isSupportedInputDevice;
|
||||
return isHapHearingDevice && isValidInputDevice;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -121,6 +134,18 @@ public class BluetoothDetailsHearingDeviceInputRoutingController extends
|
||||
if (!status) {
|
||||
Log.d(TAG, "Fail to configure setPreferredInputDeviceForCalls");
|
||||
}
|
||||
mCachedDevice.getDevice().setMicrophonePreferredForCalls(!useBuiltinMic);
|
||||
setMicrophonePreferredForCallsForDeviceSet(mCachedDevice, !useBuiltinMic);
|
||||
}
|
||||
|
||||
private void setMicrophonePreferredForCallsForDeviceSet(CachedBluetoothDevice device,
|
||||
boolean enabled) {
|
||||
if (device == null) {
|
||||
return;
|
||||
}
|
||||
device.getDevice().setMicrophonePreferredForCalls(enabled);
|
||||
final Set<CachedBluetoothDevice> memberDevices = device.getMemberDevice();
|
||||
if (!memberDevices.isEmpty()) {
|
||||
memberDevices.forEach(d -> d.getDevice().setMicrophonePreferredForCalls(enabled));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -36,6 +36,7 @@ import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.bluetooth.HearingDeviceInputRoutingPreference.InputRoutingValue;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.HapClientProfile;
|
||||
|
||||
import org.junit.Rule;
|
||||
@@ -49,6 +50,7 @@ import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/** Tests for {@link BluetoothDetailsHearingDeviceInputRoutingController}. */
|
||||
|
||||
@@ -59,11 +61,14 @@ public class BluetoothDetailsHearingDeviceInputRoutingControllerTest extends
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
private static final String TEST_ADDRESS = "55:66:77:88:99:AA";
|
||||
private static final String TEST_ADDRESS_2 = "55:66:77:88:99:BB";
|
||||
|
||||
@Mock
|
||||
private BluetoothDevice mBluetoothDevice;
|
||||
@Mock
|
||||
private HapClientProfile mHapClientProfile;
|
||||
@Mock
|
||||
private CachedBluetoothDevice mMemberCachedDevice;
|
||||
@Spy
|
||||
private AudioManager mAudioManager;
|
||||
|
||||
@@ -162,6 +167,18 @@ public class BluetoothDetailsHearingDeviceInputRoutingControllerTest extends
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_validInputMember_supportHapProfile_returnTrue() {
|
||||
when(mCachedDevice.getMemberDevice()).thenReturn(Set.of(mMemberCachedDevice));
|
||||
when(mCachedDevice.getAddress()).thenReturn(TEST_ADDRESS);
|
||||
when(mMemberCachedDevice.getAddress()).thenReturn(TEST_ADDRESS_2);
|
||||
AudioDeviceInfo[] mockInfo = new AudioDeviceInfo[] {mockTestAddressInfo(TEST_ADDRESS_2)};
|
||||
when(mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)).thenReturn(mockInfo);
|
||||
when(mCachedDevice.getProfiles()).thenReturn(List.of(mHapClientProfile));
|
||||
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
|
||||
private AudioDeviceInfo mockTestAddressInfo(String address) {
|
||||
final AudioDeviceInfo info = mock(AudioDeviceInfo.class);
|
||||
when(info.getType()).thenReturn(AudioDeviceInfo.TYPE_BLE_HEADSET);
|
||||
|
Reference in New Issue
Block a user