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

Commit e47d2a69 authored by Henri Chataing's avatar Henri Chataing
Browse files

a2dp: Do not call btif_a2dp_on_started when BTA_AV_START_EVT is received as source and responder

btif_a2dp_on_started starts a2dp offload and sends back an acknowledgment
to the BT audio HAL, which is not at all expected in this case:

1. the BT audio HAL was not initiator of the request and
   invoking stream started can fail / cause errors in the HAL.
2. the stream is already being suspended (see code), sending the a2dp
   offload command here can fail if another link is already active.

Bug: 338959084
Bug: 341178856
Flag: com.android.bluetooth.flags.a2dp_ignore_started_when_responder
Test: m com.android.btservices
Test: Manual
Change-Id: I0675a21a7d227948c8ae2c671f9706c03e9b6517
parent ab192b16
Loading
Loading
Loading
Loading
+15 −7
Original line number Diff line number Diff line
@@ -2434,6 +2434,9 @@ bool BtifAvStateMachine::StateOpened::ProcessEvent(uint32_t event,
    case BTIF_AV_ACL_DISCONNECTED:
      break;  // Ignore

    // Event sent by the Bluetooth Audio HAL to a source A2DP stack
    // when a stream is ready to play. The stack shall send AVDTP Start to the
    // remote device to start the stream.
    case BTIF_AV_START_STREAM_REQ_EVT: {
      log::info("Peer {} : event={} flags={}", peer_.PeerAddress(),
                BtifAvEvent::EventName(event), peer_.FlagsToString());
@@ -2449,6 +2452,10 @@ bool BtifAvStateMachine::StateOpened::ProcessEvent(uint32_t event,
      peer_.SetFlags(BtifAvPeer::kFlagPendingStart);
    } break;

    // Event sent by lower layer to indicate that the AVDTP stream is started.
    // May be initiated by the remote device to start a stream, in this case the
    // event is ignored by source A2DP, and the stack shall immediately suspend
    // the stream.
    case BTA_AV_START_EVT: {
      log::info(
          "Peer {} : event={} status={} suspending={} initiator={} flags={}",
@@ -2475,15 +2482,16 @@ bool BtifAvStateMachine::StateOpened::ProcessEvent(uint32_t event,
          should_suspend = true;
        }

        // If peer is A2DP Source, do ACK commands to audio HAL and start
        // media task
        // Invoke the started handler only when initiator.
        if (!com::android::bluetooth::flags::a2dp_ignore_started_when_responder() ||
            peer_.CheckFlags(BtifAvPeer::kFlagPendingStart)) {
          if (btif_a2dp_on_started(
                peer_.PeerAddress(), &p_av->start,
                peer_.IsSource() ? A2dpType::kSink : A2dpType::kSource)) {
                  peer_.PeerAddress(), &p_av->start, A2dpType::kSource)) {
            // Only clear pending flag after acknowledgement
            peer_.ClearFlags(BtifAvPeer::kFlagPendingStart);
          }
        }
      }

      // Remain in Open state if status failed
      if (p_av->start.status != BTA_AV_SUCCESS) return false;