bool IsConnected() const;
bool IsStreaming() const;
+ bool IsInSilenceMode() const { return is_silenced_; };
+
+ void SetSilence(bool silence) { is_silenced_ = silence; };
/**
* Check whether any of the flags specified by the bitlags mask is set.
tBTA_AV_EDR edr_;
uint8_t flags_;
bool self_initiated_connection_;
+ bool is_silenced_;
};
class BtifAvSource {
const RawAddress& ActivePeer() const { return active_peer_; }
/**
+ * Check whether peer is silenced
+ *
+ * @param peer_address the peer to check
+ * @return true on silence mode enabled, otherwise false
+ */
+ bool IsPeerSilenced(const RawAddress& peer_address) {
+ if (peer_address.IsEmpty()) {
+ return false;
+ }
+ BtifAvPeer* peer = FindPeer(peer_address);
+ if (peer == nullptr) {
+ BTIF_TRACE_WARNING("%s: peer is null", __func__);
+ return false;
+ }
+ if (!peer->IsConnected()) {
+ BTIF_TRACE_WARNING("%s: peer is not connected", __func__);
+ return false;
+ }
+ return peer->IsInSilenceMode();
+ }
+
+ /**
+ * Set peer silence mode
+ *
+ * @param peer_address the peer to set
+ * @param silence true on enable silence mode, false on disable
+ * @return true on success, otherwise false
+ */
+ bool SetSilencePeer(const RawAddress& peer_address, const bool silence) {
+ if (peer_address.IsEmpty()) {
+ return false;
+ }
+ LOG_INFO(LOG_TAG, "%s: peer: %s", __PRETTY_FUNCTION__,
+ peer_address.ToString().c_str());
+ BtifAvPeer* peer = FindPeer(peer_address);
+ if (peer == nullptr) {
+ BTIF_TRACE_WARNING("%s: peer is null", __func__);
+ return false;
+ }
+ if (!peer->IsConnected()) {
+ BTIF_TRACE_WARNING("%s: peer is not connected", __func__);
+ return false;
+ }
+ peer->SetSilence(silence);
+ return true;
+ }
+
+ /**
* Set the active peer.
*
* @param peer_address the active peer address or RawAddress::kEmpty to
bool a2dp_offload_enabled_;
int max_connected_peers_;
std::map<RawAddress, BtifAvPeer*> peers_;
+ std::set<RawAddress> silenced_peers_;
RawAddress active_peer_;
std::map<uint8_t, tBTA_AV_HNDL> peer_id2bta_handle_;
};
bt_status_t BtifAvPeer::Init() {
alarm_free(av_open_on_rc_timer_);
av_open_on_rc_timer_ = alarm_new("btif_av_peer.av_open_on_rc_timer");
+ is_silenced_ = false;
state_machine_.Start();
return BT_STATUS_SUCCESS;
return BT_STATUS_SUCCESS;
}
+static void set_source_silence_peer_int(const RawAddress& peer_address,
+ bool silence) {
+ BTIF_TRACE_EVENT("%s: peer_address=%s, silence=%s", __func__,
+ peer_address.ToString().c_str(), silence ? "true" : "false");
+ if (!btif_av_source.SetSilencePeer(peer_address, silence)) {
+ BTIF_TRACE_ERROR("%s: Error setting silence state to %s", __func__,
+ peer_address.ToString().c_str());
+ }
+}
+
// Set the active peer
static void set_active_peer_int(uint8_t peer_sep,
const RawAddress& peer_address) {
peer_address, kBtaHandleUnknown, btif_av_event));
}
+static bt_status_t src_set_silence_sink(const RawAddress& peer_address,
+ bool silence) {
+ 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__);
+ return BT_STATUS_NOT_READY;
+ }
+
+ return do_in_main_thread(FROM_HERE, base::Bind(&set_source_silence_peer_int,
+ peer_address, silence));
+}
+
static bt_status_t src_set_active_sink(const RawAddress& peer_address) {
BTIF_TRACE_EVENT("%s: Peer %s", __func__, peer_address.ToString().c_str());
init_src,
src_connect_sink,
src_disconnect_sink,
+ src_set_silence_sink,
src_set_active_sink,
codec_config_src,
cleanup_src,
bool btif_av_is_a2dp_offload_enabled() {
return btif_av_source.A2dpOffloadEnabled();
}
+
+bool btif_av_is_peer_silenced(const RawAddress& peer_address) {
+ return btif_av_source.IsPeerSilenced(peer_address);
+}
return address_ == a2dp_interface_->active_peer();
}
+bool Device::IsInSilenceMode() const {
+ return a2dp_interface_->is_peer_in_silence_mode(address_);
+}
+
void Device::VendorPacketHandler(uint8_t label,
std::shared_ptr<VendorPacket> pkt) {
CHECK(media_interface_);
// We still try to send updates while music is playing to the non active
// device even though the device thinks the music is paused. This makes
// the status bar on the remote device move.
- if (status.state == PlayState::PLAYING) {
+ if (status.state == PlayState::PLAYING && !IsInSilenceMode()) {
DEVICE_VLOG(0) << __func__ << ": Queue next play position update";
play_pos_update_cb_.Reset(base::Bind(&Device::HandlePlayPosUpdate,
weak_ptr_factory_.GetWeakPtr()));
}
void Device::SendMediaUpdate(bool metadata, bool play_status, bool queue) {
+ bool is_silence = IsInSilenceMode();
+
CHECK(media_interface_);
DEVICE_VLOG(4) << __func__ << ": Metadata=" << metadata
- << " : play_status= " << play_status << " : queue=" << queue;
+ << " : play_status= " << play_status << " : queue=" << queue
+ << " ; is_silence=" << is_silence;
if (queue) {
HandleNowPlayingUpdate();
if (play_status) {
HandlePlayStatusUpdate();
- HandlePlayPosUpdate();
+ if (!is_silence) {
+ HandlePlayPosUpdate();
+ }
}
if (metadata) HandleTrackUpdate();