static void btif_a2dp_sink_init_delayed();
static void btif_a2dp_sink_startup_delayed();
-static void btif_a2dp_sink_start_session_delayed();
+static void btif_a2dp_sink_start_session_delayed(
+ std::promise<void> peer_ready_promise);
static void btif_a2dp_sink_end_session_delayed();
static void btif_a2dp_sink_shutdown_delayed();
static void btif_a2dp_sink_cleanup_delayed();
// Nothing to do
}
-bool btif_a2dp_sink_start_session(const RawAddress& peer_address) {
- LOG_INFO(LOG_TAG, "%s: peer_address=%s", __func__,
- peer_address.ToString().c_str());
- btif_a2dp_sink_cb.worker_thread.DoInThread(
- FROM_HERE, base::BindOnce(btif_a2dp_sink_start_session_delayed));
- return true;
+bool btif_a2dp_sink_start_session(const RawAddress& peer_address,
+ std::promise<void> peer_ready_promise) {
+ LOG(INFO) << __func__ << ": peer_address=" << peer_address;
+ if (btif_a2dp_sink_cb.worker_thread.DoInThread(
+ FROM_HERE, base::BindOnce(btif_a2dp_sink_start_session_delayed,
+ std::move(peer_ready_promise)))) {
+ return true;
+ } else {
+ // cannot set promise but triggers crash
+ LOG(FATAL) << __func__ << ": peer_address=" << peer_address
+ << " fails to context switch";
+ return false;
+ }
}
-static void btif_a2dp_sink_start_session_delayed() {
- LOG_INFO(LOG_TAG, "%s", __func__);
+static void btif_a2dp_sink_start_session_delayed(
+ std::promise<void> peer_ready_promise) {
+ LOG(INFO) << __func__;
LockGuard lock(g_mutex);
+ peer_ready_promise.set_value();
// Nothing to do
}
bool btif_a2dp_sink_restart_session(const RawAddress& old_peer_address,
- const RawAddress& new_peer_address) {
- LOG_INFO(LOG_TAG, "%s: old_peer_address=%s new_peer_address=%s", __func__,
- old_peer_address.ToString().c_str(),
- new_peer_address.ToString().c_str());
+ const RawAddress& new_peer_address,
+ std::promise<void> peer_ready_promise) {
+ LOG(INFO) << __func__ << ": old_peer_address=" << old_peer_address
+ << " new_peer_address=" << new_peer_address;
CHECK(!new_peer_address.IsEmpty());
}
if (!bta_av_co_set_active_peer(new_peer_address)) {
- LOG_ERROR(LOG_TAG, "%s: Cannot stream audio: cannot set active peer to %s",
- __func__, new_peer_address.ToString().c_str());
+ LOG(ERROR) << __func__
+ << ": Cannot stream audio: cannot set active peer to "
+ << new_peer_address;
+ peer_ready_promise.set_value();
return false;
}
if (old_peer_address.IsEmpty()) {
btif_a2dp_sink_startup();
}
- btif_a2dp_sink_start_session(new_peer_address);
+ btif_a2dp_sink_start_session(new_peer_address, std::move(peer_ready_promise));
return true;
}
static void btif_a2dp_source_init_delayed(void);
static void btif_a2dp_source_startup_delayed(void);
static void btif_a2dp_source_start_session_delayed(
- const RawAddress& peer_address);
+ const RawAddress& peer_address, std::promise<void> start_session_promise);
static void btif_a2dp_source_end_session_delayed(
const RawAddress& peer_address);
static void btif_a2dp_source_shutdown_delayed(void);
btif_a2dp_source_cb.SetState(BtifA2dpSource::kStateRunning);
}
-bool btif_a2dp_source_start_session(const RawAddress& peer_address) {
- LOG_INFO(LOG_TAG, "%s: peer_address=%s state=%s", __func__,
- peer_address.ToString().c_str(),
- btif_a2dp_source_cb.StateStr().c_str());
+bool btif_a2dp_source_start_session(const RawAddress& peer_address,
+ std::promise<void> peer_ready_promise) {
+ LOG(INFO) << __func__ << ": peer_address=" << peer_address
+ << " state=" << btif_a2dp_source_cb.StateStr();
btif_a2dp_source_setup_codec(peer_address);
- btif_a2dp_source_thread.DoInThread(
- FROM_HERE,
- base::Bind(&btif_a2dp_source_start_session_delayed, peer_address));
- return true;
+ if (btif_a2dp_source_thread.DoInThread(
+ FROM_HERE,
+ base::BindOnce(&btif_a2dp_source_start_session_delayed, peer_address,
+ std::move(peer_ready_promise)))) {
+ return true;
+ } else {
+ // cannot set promise but triggers crash
+ LOG(FATAL) << __func__ << ": peer_address=" << peer_address
+ << " state=" << btif_a2dp_source_cb.StateStr()
+ << " fails to context switch";
+ return false;
+ }
}
static void btif_a2dp_source_start_session_delayed(
- const RawAddress& peer_address) {
- LOG_INFO(LOG_TAG, "%s: peer_address=%s state=%s", __func__,
- peer_address.ToString().c_str(),
- btif_a2dp_source_cb.StateStr().c_str());
+ const RawAddress& peer_address, std::promise<void> peer_ready_promise) {
+ LOG(INFO) << __func__ << ": peer_address=" << peer_address
+ << " state=" << btif_a2dp_source_cb.StateStr();
if (btif_a2dp_source_cb.State() != BtifA2dpSource::kStateRunning) {
- LOG_ERROR(LOG_TAG, "%s: A2DP Source media task is not running", __func__);
+ LOG(ERROR) << __func__ << ": A2DP Source media task is not running";
+ peer_ready_promise.set_value();
return;
}
if (btif_av_is_a2dp_offload_enabled()) {
BluetoothMetricsLogger::GetInstance()->LogBluetoothSessionStart(
bluetooth::common::CONNECTION_TECHNOLOGY_TYPE_BREDR, 0);
}
+ peer_ready_promise.set_value();
}
bool btif_a2dp_source_restart_session(const RawAddress& old_peer_address,
- const RawAddress& new_peer_address) {
+ const RawAddress& new_peer_address,
+ std::promise<void> peer_ready_promise) {
bool is_streaming = btif_a2dp_source_cb.media_alarm.IsScheduled();
- LOG_INFO(LOG_TAG,
- "%s: old_peer_address=%s new_peer_address=%s is_streaming=%s "
- "state=%s",
- __func__, old_peer_address.ToString().c_str(),
- new_peer_address.ToString().c_str(), logbool(is_streaming).c_str(),
- btif_a2dp_source_cb.StateStr().c_str());
+ LOG(INFO) << __func__ << ": old_peer_address=" << old_peer_address
+ << " new_peer_address=" << new_peer_address
+ << " is_streaming=" << logbool(is_streaming)
+ << " state=" << btif_a2dp_source_cb.StateStr();
CHECK(!new_peer_address.IsEmpty());
// Start the session.
// If audio was streaming before, start audio streaming as well.
- btif_a2dp_source_start_session(new_peer_address);
+ btif_a2dp_source_start_session(new_peer_address,
+ std::move(peer_ready_promise));
if (is_streaming) {
btif_a2dp_source_start_audio_req();
}
* reset the active peer
* @return true on success, otherwise false
*/
- bool SetActivePeer(const RawAddress& peer_address) {
- LOG_INFO(LOG_TAG, "%s: peer: %s", __PRETTY_FUNCTION__,
- peer_address.ToString().c_str());
+ bool SetActivePeer(const RawAddress& peer_address,
+ std::promise<void> peer_ready_promise) {
+ LOG(INFO) << __PRETTY_FUNCTION__ << ": peer: " << peer_address;
- if (active_peer_ == peer_address) return true; // Nothing has changed
+ if (active_peer_ == peer_address) {
+ peer_ready_promise.set_value();
+ return true; // Nothing has changed
+ }
if (peer_address.IsEmpty()) {
BTIF_TRACE_EVENT("%s: peer address is empty, shutdown the Audio source",
__func__);
if (!bta_av_co_set_active_peer(peer_address)) {
- BTIF_TRACE_WARNING("%s: unable to set active peer to empty in BtaAvCo",
- __func__);
+ LOG(WARNING) << __func__
+ << ": unable to set active peer to empty in BtaAvCo";
}
btif_a2dp_source_end_session(active_peer_);
btif_a2dp_source_shutdown();
active_peer_ = peer_address;
+ peer_ready_promise.set_value();
return true;
}
BtifAvPeer* peer = FindPeer(peer_address);
if (peer != nullptr && !peer->IsConnected()) {
- BTIF_TRACE_ERROR("%s: Error setting %s as active Source peer", __func__,
- peer->PeerAddress().ToString().c_str());
+ LOG(ERROR) << __func__ << ": Error setting " << peer->PeerAddress()
+ << " as active Source peer";
+ peer_ready_promise.set_value();
return false;
}
- if (!btif_a2dp_source_restart_session(active_peer_, peer_address)) {
+ if (!btif_a2dp_source_restart_session(active_peer_, peer_address,
+ std::move(peer_ready_promise))) {
+ // cannot set promise but need to be handled within restart_session
return false;
}
active_peer_ = peer_address;
*/
void UpdateCodecConfig(
const RawAddress& peer_address,
- const std::vector<btav_a2dp_codec_config_t>& codec_preferences) {
+ const std::vector<btav_a2dp_codec_config_t>& codec_preferences,
+ std::promise<void> peer_ready_promise) {
// Restart the session if the codec for the active peer is updated
bool restart_session =
((active_peer_ == peer_address) && !active_peer_.IsEmpty());
btif_a2dp_source_encoder_user_config_update_req(peer_address, cp);
}
if (restart_session) {
- btif_a2dp_source_start_session(active_peer_);
+ btif_a2dp_source_start_session(active_peer_,
+ std::move(peer_ready_promise));
+ } else {
+ peer_ready_promise.set_value();
}
}
* reset the active peer
* @return true on success, otherwise false
*/
- bool SetActivePeer(const RawAddress& peer_address) {
- LOG_INFO(LOG_TAG, "%s: peer: %s", __PRETTY_FUNCTION__,
- peer_address.ToString().c_str());
+ bool SetActivePeer(const RawAddress& peer_address,
+ std::promise<void> peer_ready_promise) {
+ LOG(INFO) << __PRETTY_FUNCTION__ << ": peer: " << peer_address;
- if (active_peer_ == peer_address) return true; // Nothing has changed
+ if (active_peer_ == peer_address) {
+ peer_ready_promise.set_value();
+ return true; // Nothing has changed
+ }
if (peer_address.IsEmpty()) {
BTIF_TRACE_EVENT("%s: peer address is empty, shutdown the Audio sink",
__func__);
if (!bta_av_co_set_active_peer(peer_address)) {
- BTIF_TRACE_WARNING("%s: unable to set active peer to empty in BtaAvCo",
- __func__);
+ LOG(WARNING) << __func__
+ << ": unable to set active peer to empty in BtaAvCo";
}
btif_a2dp_sink_end_session(active_peer_);
btif_a2dp_sink_shutdown();
active_peer_ = peer_address;
+ peer_ready_promise.set_value();
return true;
}
BtifAvPeer* peer = FindPeer(peer_address);
if (peer != nullptr && !peer->IsConnected()) {
- BTIF_TRACE_ERROR("%s: Error setting %s as active Sink peer", __func__,
- peer->PeerAddress().ToString().c_str());
+ LOG(ERROR) << __func__ << ": Error setting " << peer->PeerAddress()
+ << " as active Sink peer";
+ peer_ready_promise.set_value();
return false;
}
- if (!btif_a2dp_sink_restart_session(active_peer_, peer_address)) {
+ if (!btif_a2dp_sink_restart_session(active_peer_, peer_address,
+ std::move(peer_ready_promise))) {
+ // cannot set promise but need to be handled within restart_session
return false;
}
active_peer_ = peer_address;
btif_queue_cleanup(UUID_SERVCLASS_AUDIO_SOURCE);
+ std::promise<void> peer_ready_promise;
do_in_main_thread(
FROM_HERE,
- base::Bind(base::IgnoreResult(&BtifAvSource::SetActivePeer),
- base::Unretained(&btif_av_source), RawAddress::kEmpty));
+ base::BindOnce(base::IgnoreResult(&BtifAvSource::SetActivePeer),
+ base::Unretained(&btif_av_source), RawAddress::kEmpty,
+ std::move(peer_ready_promise)));
do_in_main_thread(FROM_HERE, base::Bind(&btif_a2dp_source_cleanup));
btif_disable_service(BTA_A2DP_SOURCE_SERVICE_ID);
btif_queue_cleanup(UUID_SERVCLASS_AUDIO_SINK);
+ std::promise<void> peer_ready_promise;
do_in_main_thread(
FROM_HERE,
- base::Bind(base::IgnoreResult(&BtifAvSink::SetActivePeer),
- base::Unretained(&btif_av_sink), RawAddress::kEmpty));
+ base::BindOnce(base::IgnoreResult(&BtifAvSink::SetActivePeer),
+ base::Unretained(&btif_av_sink), RawAddress::kEmpty,
+ std::move(peer_ready_promise)));
do_in_main_thread(FROM_HERE, base::Bind(&btif_a2dp_sink_cleanup));
btif_disable_service(BTA_A2DP_SINK_SERVICE_ID);
// Reset the active peer if this was the active peer and
// the Idle state was reentered
if (peer_.IsActivePeer() && peer_.CanBeDeleted()) {
+ std::promise<void> peer_ready_promise;
if (peer_.IsSink()) {
- btif_av_source.SetActivePeer(RawAddress::kEmpty);
+ btif_av_source.SetActivePeer(RawAddress::kEmpty,
+ std::move(peer_ready_promise));
} else if (peer_.IsSource()) {
- btif_av_sink.SetActivePeer(RawAddress::kEmpty);
+ btif_av_sink.SetActivePeer(RawAddress::kEmpty,
+ std::move(peer_ready_promise));
}
}
// For A2DP Source, the setting of the Active device is done by the
// ActiveDeviceManager in Java.
if (peer_.IsSource() && btif_av_sink.ActivePeer().IsEmpty()) {
- if (!btif_av_sink.SetActivePeer(peer_.PeerAddress())) {
+ std::promise<void> peer_ready_promise;
+ if (!btif_av_sink.SetActivePeer(peer_.PeerAddress(),
+ std::move(peer_ready_promise))) {
BTIF_TRACE_ERROR("%s: Error setting %s as active Source peer", __func__,
peer_.PeerAddress().ToString().c_str());
}
// Set the active peer
static void set_active_peer_int(uint8_t peer_sep,
- const RawAddress& peer_address) {
+ const RawAddress& peer_address,
+ std::promise<void> peer_ready_promise) {
BTIF_TRACE_EVENT("%s: peer_sep=%s (%d) peer_address=%s", __func__,
(peer_sep == AVDT_TSEP_SRC) ? "Source" : "Sink", peer_sep,
peer_address.ToString().c_str());
BtifAvPeer* peer = nullptr;
if (peer_sep == AVDT_TSEP_SNK) {
- if (!btif_av_source.SetActivePeer(peer_address)) {
+ if (!btif_av_source.SetActivePeer(peer_address,
+ std::move(peer_ready_promise))) {
BTIF_TRACE_ERROR("%s: Error setting %s as active Sink peer", __func__,
peer_address.ToString().c_str());
}
return;
}
if (peer_sep == AVDT_TSEP_SRC) {
- if (!btif_av_sink.SetActivePeer(peer_address)) {
+ if (!btif_av_sink.SetActivePeer(peer_address,
+ std::move(peer_ready_promise))) {
BTIF_TRACE_ERROR("%s: Error setting %s as active Source peer", __func__,
peer_address.ToString().c_str());
}
(peer_sep == AVDT_TSEP_SRC) ? "Source" : "Sink",
peer_address.ToString().c_str(),
(peer == nullptr) ? "found" : "connected");
+ peer_ready_promise.set_value();
}
static bt_status_t src_connect_sink(const RawAddress& peer_address) {
BTIF_TRACE_EVENT("%s: Peer %s", __func__, peer_address.ToString().c_str());
if (!btif_av_source.Enabled()) {
- BTIF_TRACE_WARNING("%s: BTIF AV Source is not enabled", __func__);
+ LOG(WARNING) << __func__ << ": BTIF AV Source is not enabled";
return BT_STATUS_NOT_READY;
}
- return do_in_main_thread(FROM_HERE, base::Bind(&set_active_peer_int,
- AVDT_TSEP_SNK, // peer_sep
- peer_address));
+ std::promise<void> peer_ready_promise;
+ std::future<void> peer_ready_future = peer_ready_promise.get_future();
+ bt_status_t status = do_in_main_thread(
+ FROM_HERE, base::BindOnce(&set_active_peer_int,
+ AVDT_TSEP_SNK, // peer_sep
+ peer_address, std::move(peer_ready_promise)));
+ if (status == BT_STATUS_SUCCESS) {
+ peer_ready_future.wait();
+ } else {
+ LOG(WARNING) << __func__ << ": BTIF AV Source fails to change peer";
+ }
+ return status;
}
static bt_status_t codec_config_src(
BTIF_TRACE_EVENT("%s", __func__);
if (!btif_av_source.Enabled()) {
- BTIF_TRACE_WARNING("%s: BTIF AV Source is not enabled", __func__);
+ LOG(WARNING) << __func__ << ": BTIF AV Source is not enabled";
return BT_STATUS_NOT_READY;
}
- return do_in_main_thread(
- FROM_HERE, base::Bind(&BtifAvSource::UpdateCodecConfig,
- base::Unretained(&btif_av_source), peer_address,
- codec_preferences));
+ std::promise<void> peer_ready_promise;
+ std::future<void> peer_ready_future = peer_ready_promise.get_future();
+ bt_status_t status = do_in_main_thread(
+ FROM_HERE,
+ base::BindOnce(&BtifAvSource::UpdateCodecConfig,
+ base::Unretained(&btif_av_source), peer_address,
+ codec_preferences, std::move(peer_ready_promise)));
+ if (status == BT_STATUS_SUCCESS) {
+ peer_ready_future.wait();
+ } else {
+ LOG(WARNING) << __func__ << ": BTIF AV Source fails to config codec";
+ }
+ return status;
}
static void cleanup_src(void) {