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

Commit d8797110 authored by Jason Hsu's avatar Jason Hsu Committed by Android (Google) Code Review
Browse files

Merge "Fix default microphone for calls sometimes not work and not show UI" into main

parents 71eb7337 691a3fd6
Loading
Loading
Loading
Loading
+32 −7
Original line number Diff line number Diff line
@@ -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));
        }
    }
}
+17 −0
Original line number Diff line number Diff line
@@ -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);