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

Commit 27fd7981 authored by Etienne Ruffieux's avatar Etienne Ruffieux Committed by Automerger Merge Worker
Browse files

Merge "Handle AVRCP SDP search collisions" into main am: 24fb74ae

parents f03458ab 24fb74ae
Loading
Loading
Loading
Loading
+13 −3
Original line number Diff line number Diff line
@@ -396,9 +396,19 @@ void ConnectionHandler::AcceptorControlCb(uint8_t handle, uint8_t event,
        }
      };

      SdpLookup(*peer_addr, base::Bind(sdp_lambda, this, handle), false);

      if (SdpLookup(*peer_addr, base::Bind(sdp_lambda, this, handle), false)) {
        avrc_->OpenBrowse(handle, AVCT_ACP);
      } else {
        // SDP search failed, this could be due to a collision between outgoing
        // and incoming connection. In any case, we need to reject the current
        // connection.
        LOG(ERROR) << __PRETTY_FUNCTION__
                   << ": SDP search failed for handle: " << loghex(handle)
                   << ", closing connection";
        DisconnectDevice(*peer_addr);
      }
      // Open for the next incoming connection. The handle will not be the same
      // as this one which will be closed when the device is disconnected.
      AvrcpConnect(false, RawAddress::kAny);
    } break;

+116 −8
Original line number Diff line number Diff line
@@ -166,8 +166,10 @@ TEST_F(AvrcpConnectionHandlerTest, disconnectAfterCleanupTest) {
  conn_cb.ctrl_cback.Run(1, AVRC_CLOSE_IND_EVT, 0, &RawAddress::kAny);
};

// Check that we can handle having a remote device connect to us, start SDP, and
// open another acceptor connection
/**
 * Check that we can handle having a remote device connect to us, start SDP, and
 * open another acceptor connection.
 */
TEST_F(AvrcpConnectionHandlerTest, remoteDeviceConnectionTest) {
  // Set an Expectation that Open will be called twice as an acceptor and save
  // the connection callback once it is called.
@@ -210,8 +212,10 @@ TEST_F(AvrcpConnectionHandlerTest, remoteDeviceConnectionTest) {
  ConnectionHandler::CleanUp();
}

// Check that when a device does not support absolute volume, that the
// handler reports that via the volume interface.
/**
 *  Check that when a device does not support absolute volume, that the
 * handler reports that via the volume interface.
 */
TEST_F(AvrcpConnectionHandlerTest, noAbsoluteVolumeTest) {
  // Set an Expectation that Open will be called twice as an acceptor and save
  // the connection callback once it is called.
@@ -246,8 +250,10 @@ TEST_F(AvrcpConnectionHandlerTest, noAbsoluteVolumeTest) {
  ConnectionHandler::CleanUp();
}

// Check that when a device does support absolute volume, that the handler
// doesn't report it. Instead that will be left up to the device.
/**
 *  Check that when a device does support absolute volume, that the handler
 * doesn't report it. Instead that will be left up to the device.
 */
TEST_F(AvrcpConnectionHandlerTest, absoluteVolumeTest) {
  // Set an Expectation that Open will be called twice as an acceptor and save
  // the connection callback once it is called.
@@ -314,8 +320,10 @@ TEST_F(AvrcpConnectionHandlerTest, disconnectTest) {
  ConnectionHandler::CleanUp();
}

// Check that we can handle having a remote device connect to us, start SDP, and
// open another acceptor connection
/**
 * Check that we can handle having a remote device connect to us, start SDP, and
 * open another acceptor connection.
 */
TEST_F(AvrcpConnectionHandlerTest, multipleRemoteDeviceConnectionTest) {
  // Set an Expectation that Open will be called three times as an acceptor and
  // save the connection callback once it is called.
@@ -534,5 +542,105 @@ TEST_F(AvrcpConnectionHandlerTest, disconnectWhileDoingSdpTest) {
  ConnectionHandler::CleanUp();
}

/**
 * Check that when an incoming connection happens at the same time as the
 * that the SDP search for initiator is running the collision is handled.
 */
TEST_F(AvrcpConnectionHandlerTest, connectionCollisionTest) {
  tAVRC_CONN_CB conn_cb;
  EXPECT_CALL(mock_avrcp_, Open(_, _, RawAddress::kAny))
      .Times(2)
      .WillOnce(
          DoAll(SetArgPointee<0>(1), SaveArgPointee<1>(&conn_cb), Return(0)))
      .WillOnce(
          DoAll(SetArgPointee<0>(2), SaveArgPointee<1>(&conn_cb), Return(0)));

  // Initialize the interface
  auto bound_callback = base::Bind(&MockFunction<void(device_ptr)>::Call,
                                   base::Unretained(&device_cb));
  ASSERT_TRUE(ConnectionHandler::Initialize(bound_callback, &mock_avrcp_,
                                            &mock_sdp_, &mock_volume_));
  connection_handler_ = ConnectionHandler::Get();

  // Check that the callback was sent with us as the acceptor
  ASSERT_EQ(conn_cb.conn, 1);

  // Set an Expectations that SDP will be performed
  tAVRC_FIND_CBACK sdp_cb;
  SetUpSdp(&sdp_cb, false, false);

  connection_handler_->ConnectDevice(RawAddress::kAny);

  // Set an expectation that a device will be created
  EXPECT_CALL(device_cb, Call(_)).Times(1);

  // Set an Expectations that SDP search will be performed again but will fail
  EXPECT_CALL(mock_avrcp_, FindService(_, _, _, _))
      .Times(1)
      .WillOnce(DoAll(SaveArg<3>(&sdp_cb), Return(1)));

  // Set an expectation that the incoming connection will be closed
  EXPECT_CALL(mock_avrcp_, Close(1));

  // Call the callback with a message saying that a remote device has connected
  conn_cb.ctrl_cback.Run(1, AVRC_OPEN_IND_EVT, 0, &RawAddress::kAny);

  // Set an expectation that cleanup will close the last connection
  EXPECT_CALL(mock_avrcp_, Close(_));

  // Run the SDP callback with status success
  sdp_cb.Run(0);

  connection_handler_ = nullptr;
  ConnectionHandler::CleanUp();
}

/**
 * Check that we are not proceeding with the connection if the SDP search
 * failed.
 */
TEST_F(AvrcpConnectionHandlerTest, acceptorSdpSearchFailTest) {
  // Set an Expectation that Open will be called twice as an acceptor and
  // save the connection callback once it is called.
  tAVRC_CONN_CB conn_cb;
  EXPECT_CALL(mock_avrcp_, Open(_, _, RawAddress::kAny))
      .Times(2)
      .WillOnce(
          DoAll(SetArgPointee<0>(1), SaveArgPointee<1>(&conn_cb), Return(0)))
      .WillOnce(
          DoAll(SetArgPointee<0>(2), SaveArgPointee<1>(&conn_cb), Return(0)));

  // Initialize the interface
  auto bound_callback = base::Bind(&MockFunction<void(device_ptr)>::Call,
                                   base::Unretained(&device_cb));
  ASSERT_TRUE(ConnectionHandler::Initialize(bound_callback, &mock_avrcp_,
                                            &mock_sdp_, &mock_volume_));
  connection_handler_ = ConnectionHandler::Get();

  // Check that the callback was sent with us as the acceptor
  ASSERT_EQ(conn_cb.conn, 1);

  // Set an expectation that a device will be created
  EXPECT_CALL(device_cb, Call(_)).Times(1);

  // Set an expectation that SDP search will be performed but will fail
  tAVRC_FIND_CBACK sdp_cb;
  EXPECT_CALL(mock_avrcp_, FindService(_, _, _, _))
      .Times(1)
      .WillOnce(DoAll(SaveArg<3>(&sdp_cb), Return(1)));

  // Set an expectation that the incoming connection will be closed
  EXPECT_CALL(mock_avrcp_, Close(1));

  // Call the callback with a message saying that a remote device has connected
  conn_cb.ctrl_cback.Run(1, AVRC_OPEN_IND_EVT, 0, &RawAddress::kAny);

  // Set an expectation that cleanup will close the last connection
  EXPECT_CALL(mock_avrcp_, Close(_));

  connection_handler_ = nullptr;
  ConnectionHandler::CleanUp();
}

}  // namespace avrcp
}  // namespace bluetooth