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

Commit 6d00e411 authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

AudioService: check for audio device connection success

When connecting/disconnecting and audio device, AudioService
  was assuming that the call was always successful through
  AudioSystem.setDeviceConnectionState(). In the case of the
  connection of a wired headset (mic + headphones), this also
  causes A2DP to not be used for media playback.
The connection can fail if the audio device being connected
  is not supported by the platform. But if this failure is
  not taken into account for DEVICE_OUT_WIRED_HEADSET or
  HEADPHONES, A2DP would still be avoided even when an A2DP
  device reconnects at boot.
The fix consists in executing the connection logic only when
  the connection was deemed successful. Nothing is altered
  on the disconnection code path, or the direct connection
  of A2DP.
The javadoc is updated in AudioSystem to indicate the return
  codes to take into account in setDeviceConnectionState().

Bug 22511833

Change-Id: I22f0d2c7d4ab4fb9ee1be2f248907f721596a16f
parent d0694da4
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -604,6 +604,10 @@ public class AudioSystem
    public static final int SYNC_EVENT_NONE = 0;
    public static final int SYNC_EVENT_PRESENTATION_COMPLETE = 1;

    /**
     * @return command completion status, one of {@link #AUDIO_STATUS_OK},
     *     {@link #AUDIO_STATUS_ERROR} or {@link #AUDIO_STATUS_SERVER_DIED}
     */
    public static native int setDeviceConnectionState(int device, int state,
                                                      String device_address, String device_name);
    public static native int getDeviceConnectionState(int device, String device_address);
+14 −5
Original line number Diff line number Diff line
@@ -4726,13 +4726,19 @@ public class AudioService extends IAudioService.Stub {
                Slog.i(TAG, "deviceSpec:" + deviceSpec + " is(already)Connected:" + isConnected);
            }
            if (connect && !isConnected) {
                AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_AVAILABLE,
                        address, deviceName);
                final int res = AudioSystem.setDeviceConnectionState(device,
                        AudioSystem.DEVICE_STATE_AVAILABLE, address, deviceName);
                if (res != AudioSystem.AUDIO_STATUS_OK) {
                    Slog.e(TAG, "not connecting device 0x" + Integer.toHexString(device) +
                            " due to command error " + res );
                    return false;
                }
                mConnectedDevices.put(deviceKey, new DeviceListSpec(device, deviceName, address));
                return true;
            } else if (!connect && isConnected) {
                AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_UNAVAILABLE,
                        address, deviceName);
                AudioSystem.setDeviceConnectionState(device,
                        AudioSystem.DEVICE_STATE_UNAVAILABLE, address, deviceName);
                // always remove even if disconnection failed
                mConnectedDevices.remove(deviceKey);
                return true;
            }
@@ -4865,7 +4871,10 @@ public class AudioService extends IAudioService.Stub {
            boolean isUsb = ((device & ~AudioSystem.DEVICE_OUT_ALL_USB) == 0) ||
                            (((device & AudioSystem.DEVICE_BIT_IN) != 0) &&
                             ((device & ~AudioSystem.DEVICE_IN_ALL_USB) == 0));
            handleDeviceConnection(state == 1, device, address, deviceName);
            if (!handleDeviceConnection(state == 1, device, address, deviceName)) {
                // change of connection state failed, bailout
                return;
            }
            if (state != 0) {
                if ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) ||
                    (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) ||