Merge "Add audio configuration API and the callback function for bluetooth.audo@2.2"
This commit is contained in:
commit
e944c8538f
7 changed files with 278 additions and 5 deletions
|
@ -59,4 +59,14 @@ interface IBluetoothAudioProvider extends @2.1::IBluetoothAudioProvider {
|
|||
*/
|
||||
startSession_2_2(IBluetoothAudioPort hostIf, AudioConfiguration audioConfig)
|
||||
generates (Status status, fmq_sync<uint8_t> dataMQ);
|
||||
|
||||
/**
|
||||
* Called when the audio configuration of the stream has been changed.
|
||||
*
|
||||
* @param audioConfig The audio configuration negotiated with the remote
|
||||
* device. The PCM parameters are set if software based encoding,
|
||||
* otherwise the correct codec configuration is used for hardware
|
||||
* encoding.
|
||||
*/
|
||||
updateAudioConfiguration(AudioConfiguration audioConfig);
|
||||
};
|
||||
|
|
|
@ -186,6 +186,29 @@ Return<void> BluetoothAudioProvider::endSession() {
|
|||
return Void();
|
||||
}
|
||||
|
||||
Return<void> BluetoothAudioProvider::updateAudioConfiguration(
|
||||
const AudioConfiguration& audioConfig) {
|
||||
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
|
||||
|
||||
if (stack_iface_ == nullptr) {
|
||||
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
|
||||
<< " has NO session";
|
||||
return Void();
|
||||
}
|
||||
|
||||
if (audioConfig.getDiscriminator() != audio_config_.getDiscriminator()) {
|
||||
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
|
||||
<< " audio config type is not match";
|
||||
return Void();
|
||||
}
|
||||
|
||||
audio_config_ = audioConfig;
|
||||
BluetoothAudioSessionReport_2_2::ReportAudioConfigChanged(session_type_,
|
||||
audio_config_);
|
||||
|
||||
return Void();
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_2
|
||||
} // namespace audio
|
||||
|
|
|
@ -53,6 +53,8 @@ class BluetoothAudioProvider : public IBluetoothAudioProvider {
|
|||
Return<void> streamStarted(BluetoothAudioStatus status) override;
|
||||
Return<void> streamSuspended(BluetoothAudioStatus status) override;
|
||||
Return<void> endSession() override;
|
||||
Return<void> updateAudioConfiguration(
|
||||
const AudioConfiguration& audioConfig) override;
|
||||
|
||||
protected:
|
||||
sp<BluetoothAudioDeathRecipient> death_recipient_;
|
||||
|
|
|
@ -48,20 +48,38 @@ class BluetoothAudioSessionControl_2_2 {
|
|||
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
|
||||
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
|
||||
if (session_ptr != nullptr) {
|
||||
return session_ptr->GetAudioSession()->RegisterStatusCback(cbacks);
|
||||
PortStatusCallbacks_2_2 cb = {
|
||||
.control_result_cb_ = cbacks.control_result_cb_,
|
||||
.session_changed_cb_ = cbacks.session_changed_cb_,
|
||||
.audio_configuration_changed_cb_ = nullptr};
|
||||
return session_ptr->RegisterStatusCback(cb);
|
||||
}
|
||||
return kObserversCookieUndefined;
|
||||
}
|
||||
|
||||
// The control API helps the bluetooth_audio module to register
|
||||
// PortStatusCallbacks_2_2
|
||||
// @return: cookie - the assigned number to this bluetooth_audio output
|
||||
static uint16_t RegisterControlResultCback(
|
||||
const SessionType_2_1& session_type,
|
||||
const PortStatusCallbacks_2_2& cbacks) {
|
||||
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
|
||||
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
|
||||
if (session_ptr != nullptr) {
|
||||
return session_ptr->RegisterStatusCback(cbacks);
|
||||
}
|
||||
return kObserversCookieUndefined;
|
||||
}
|
||||
|
||||
// The control API helps the bluetooth_audio module to unregister
|
||||
// PortStatusCallbacks
|
||||
// PortStatusCallbacks and PortStatusCallbacks_2_2
|
||||
// @param: cookie - indicates which bluetooth_audio output is
|
||||
static void UnregisterControlResultCback(const SessionType_2_1& session_type,
|
||||
uint16_t cookie) {
|
||||
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
|
||||
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
|
||||
if (session_ptr != nullptr) {
|
||||
session_ptr->GetAudioSession()->UnregisterStatusCback(cookie);
|
||||
session_ptr->UnregisterStatusCback(cookie);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,20 @@ class BluetoothAudioSessionReport_2_2 {
|
|||
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
|
||||
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
|
||||
if (session_ptr != nullptr) {
|
||||
session_ptr->GetAudioSession()->ReportControlStatus(start_resp, status);
|
||||
session_ptr->ReportControlStatus(start_resp, status);
|
||||
}
|
||||
}
|
||||
// The API reports the Bluetooth stack has replied the changed of the audio
|
||||
// configuration, and will inform registered bluetooth_audio outputs
|
||||
static void ReportAudioConfigChanged(
|
||||
const ::android::hardware::bluetooth::audio::V2_1::SessionType&
|
||||
session_type,
|
||||
const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
|
||||
audio_config) {
|
||||
std::shared_ptr<BluetoothAudioSession_2_2> session_ptr =
|
||||
BluetoothAudioSessionInstance_2_2::GetSessionInstance(session_type);
|
||||
if (session_ptr != nullptr) {
|
||||
session_ptr->ReportAudioConfigChanged(audio_config);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -359,7 +359,7 @@ void BluetoothAudioSession_2_2::OnSessionStarted(
|
|||
audio_session->stack_iface_ = stack_iface;
|
||||
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
|
||||
<< ", AudioConfiguration=" << toString(audio_config);
|
||||
audio_session->ReportSessionStatus();
|
||||
ReportSessionStatus();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -386,7 +386,150 @@ void BluetoothAudioSession_2_2::OnSessionEnded() {
|
|||
audio_session->stack_iface_ = nullptr;
|
||||
audio_session->UpdateDataPath(nullptr);
|
||||
if (toggled) {
|
||||
ReportSessionStatus();
|
||||
}
|
||||
}
|
||||
|
||||
// The control function helps the bluetooth_audio module to register
|
||||
// PortStatusCallbacks_2_2
|
||||
// @return: cookie - the assigned number to this bluetooth_audio output
|
||||
uint16_t BluetoothAudioSession_2_2::RegisterStatusCback(
|
||||
const PortStatusCallbacks_2_2& cbacks) {
|
||||
if (session_type_2_1_ !=
|
||||
SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
|
||||
session_type_2_1_ !=
|
||||
SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
|
||||
PortStatusCallbacks cb = {
|
||||
.control_result_cb_ = cbacks.control_result_cb_,
|
||||
.session_changed_cb_ = cbacks.session_changed_cb_};
|
||||
return audio_session->RegisterStatusCback(cb);
|
||||
}
|
||||
|
||||
std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
|
||||
uint16_t cookie = ObserversCookieGetInitValue(session_type_2_1_);
|
||||
uint16_t cookie_upper_bound = ObserversCookieGetUpperBound(session_type_2_1_);
|
||||
|
||||
while (cookie < cookie_upper_bound) {
|
||||
if (observers_.find(cookie) == observers_.end()) {
|
||||
break;
|
||||
}
|
||||
++cookie;
|
||||
}
|
||||
if (cookie >= cookie_upper_bound) {
|
||||
LOG(ERROR) << __func__ << " - SessionType=" << toString(session_type_2_1_)
|
||||
<< " has " << observers_.size()
|
||||
<< " observers already (No Resource)";
|
||||
return kObserversCookieUndefined;
|
||||
}
|
||||
std::shared_ptr<struct PortStatusCallbacks_2_2> cb =
|
||||
std::make_shared<struct PortStatusCallbacks_2_2>();
|
||||
*cb = cbacks;
|
||||
observers_[cookie] = cb;
|
||||
return cookie;
|
||||
}
|
||||
|
||||
// The control function helps the bluetooth_audio module to unregister
|
||||
// PortStatusCallbacks_2_2
|
||||
// @param: cookie - indicates which bluetooth_audio output is
|
||||
void BluetoothAudioSession_2_2::UnregisterStatusCback(uint16_t cookie) {
|
||||
std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
|
||||
if (session_type_2_1_ !=
|
||||
SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
|
||||
session_type_2_1_ !=
|
||||
SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
|
||||
audio_session->UnregisterStatusCback(cookie);
|
||||
return;
|
||||
}
|
||||
if (observers_.erase(cookie) != 1) {
|
||||
LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_2_1_)
|
||||
<< " no such provider=0x"
|
||||
<< android::base::StringPrintf("%04x", cookie);
|
||||
}
|
||||
}
|
||||
|
||||
// invoking the registered session_changed_cb_
|
||||
void BluetoothAudioSession_2_2::ReportSessionStatus() {
|
||||
// This is locked already by OnSessionStarted / OnSessionEnded
|
||||
if (session_type_2_1_ !=
|
||||
SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
|
||||
session_type_2_1_ !=
|
||||
SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
|
||||
audio_session->ReportSessionStatus();
|
||||
return;
|
||||
}
|
||||
if (observers_.empty()) {
|
||||
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
|
||||
<< " has NO port state observer";
|
||||
return;
|
||||
}
|
||||
for (auto& observer : observers_) {
|
||||
uint16_t cookie = observer.first;
|
||||
std::shared_ptr<struct PortStatusCallbacks_2_2> cb = observer.second;
|
||||
LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_2_1_)
|
||||
<< " notify to bluetooth_audio=0x"
|
||||
<< android::base::StringPrintf("%04x", cookie);
|
||||
cb->session_changed_cb_(cookie);
|
||||
}
|
||||
}
|
||||
|
||||
// The report function is used to report that the Bluetooth stack has notified
|
||||
// the result of startStream or suspendStream, and will invoke
|
||||
// control_result_cb_ to notify registered bluetooth_audio outputs
|
||||
void BluetoothAudioSession_2_2::ReportControlStatus(
|
||||
bool start_resp, const BluetoothAudioStatus& status) {
|
||||
if (session_type_2_1_ !=
|
||||
SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
|
||||
session_type_2_1_ !=
|
||||
SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
|
||||
audio_session->ReportControlStatus(start_resp, status);
|
||||
return;
|
||||
}
|
||||
std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
|
||||
if (observers_.empty()) {
|
||||
LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_2_1_)
|
||||
<< " has NO port state observer";
|
||||
return;
|
||||
}
|
||||
for (auto& observer : observers_) {
|
||||
uint16_t cookie = observer.first;
|
||||
std::shared_ptr<struct PortStatusCallbacks_2_2> cb = observer.second;
|
||||
LOG(INFO) << __func__ << " - status=" << toString(status)
|
||||
<< " for SessionType=" << toString(session_type_2_1_)
|
||||
<< ", bluetooth_audio=0x"
|
||||
<< android::base::StringPrintf("%04x", cookie)
|
||||
<< (start_resp ? " started" : " suspended");
|
||||
cb->control_result_cb_(cookie, start_resp, status);
|
||||
}
|
||||
}
|
||||
|
||||
// The report function is used to report that the Bluetooth stack has notified
|
||||
// the result of startStream or suspendStream, and will invoke
|
||||
// control_result_cb_ to notify registered bluetooth_audio outputs
|
||||
void BluetoothAudioSession_2_2::ReportAudioConfigChanged(
|
||||
const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
|
||||
audio_config) {
|
||||
if (session_type_2_1_ !=
|
||||
SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_ENCODING_DATAPATH &&
|
||||
session_type_2_1_ !=
|
||||
SessionType_2_1::LE_AUDIO_HARDWARE_OFFLOAD_DECODING_DATAPATH) {
|
||||
return;
|
||||
}
|
||||
std::lock_guard<std::recursive_mutex> guard(audio_session->mutex_);
|
||||
audio_config_2_2_ = audio_config;
|
||||
if (observers_.empty()) {
|
||||
LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_2_1_)
|
||||
<< " has NO port state observer";
|
||||
return;
|
||||
}
|
||||
for (auto& observer : observers_) {
|
||||
uint16_t cookie = observer.first;
|
||||
std::shared_ptr<struct PortStatusCallbacks_2_2> cb = observer.second;
|
||||
LOG(INFO) << __func__ << " for SessionType=" << toString(session_type_2_1_)
|
||||
<< ", bluetooth_audio=0x"
|
||||
<< android::base::StringPrintf("%04x", cookie);
|
||||
if (cb->audio_configuration_changed_cb_ != nullptr) {
|
||||
cb->audio_configuration_changed_cb_(cookie);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,40 @@ namespace android {
|
|||
namespace bluetooth {
|
||||
namespace audio {
|
||||
|
||||
inline uint16_t ObserversCookieGetInitValue(
|
||||
const ::android::hardware::bluetooth::audio::V2_1::SessionType&
|
||||
session_type) {
|
||||
return (static_cast<uint16_t>(session_type) << 8 & 0xff00);
|
||||
}
|
||||
inline uint16_t ObserversCookieGetUpperBound(
|
||||
const ::android::hardware::bluetooth::audio::V2_1::SessionType&
|
||||
session_type) {
|
||||
return (static_cast<uint16_t>(session_type) << 8 & 0xff00) +
|
||||
kObserversCookieSize;
|
||||
}
|
||||
|
||||
struct PortStatusCallbacks_2_2 {
|
||||
// control_result_cb_ - when the Bluetooth stack reports results of
|
||||
// streamStarted or streamSuspended, the BluetoothAudioProvider will invoke
|
||||
// this callback to report to the bluetooth_audio module.
|
||||
// @param: cookie - indicates which bluetooth_audio output should handle
|
||||
// @param: start_resp - this report is for startStream or not
|
||||
// @param: status - the result of startStream
|
||||
std::function<void(uint16_t cookie, bool start_resp,
|
||||
const BluetoothAudioStatus& status)>
|
||||
control_result_cb_;
|
||||
// session_changed_cb_ - when the Bluetooth stack start / end session, the
|
||||
// BluetoothAudioProvider will invoke this callback to notify to the
|
||||
// bluetooth_audio module.
|
||||
// @param: cookie - indicates which bluetooth_audio output should handle
|
||||
std::function<void(uint16_t cookie)> session_changed_cb_;
|
||||
// audio_configuration_changed_cb_ - when the Bluetooth stack change the audio
|
||||
// configuration, the BluetoothAudioProvider will invoke this callback to
|
||||
// notify to the bluetooth_audio module.
|
||||
// @param: cookie - indicates which bluetooth_audio output should handle
|
||||
std::function<void(uint16_t cookie)> audio_configuration_changed_cb_;
|
||||
};
|
||||
|
||||
class BluetoothAudioSession_2_2 {
|
||||
private:
|
||||
std::shared_ptr<BluetoothAudioSession> audio_session;
|
||||
|
@ -50,6 +84,13 @@ class BluetoothAudioSession_2_2 {
|
|||
static ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
|
||||
invalidLeOffloadAudioConfiguration;
|
||||
|
||||
// saving those registered bluetooth_audio's callbacks
|
||||
std::unordered_map<uint16_t, std::shared_ptr<struct PortStatusCallbacks_2_2>>
|
||||
observers_;
|
||||
|
||||
// invoking the registered session_changed_cb_
|
||||
void ReportSessionStatus();
|
||||
|
||||
public:
|
||||
BluetoothAudioSession_2_2(
|
||||
const ::android::hardware::bluetooth::audio::V2_1::SessionType&
|
||||
|
@ -82,6 +123,29 @@ class BluetoothAudioSession_2_2 {
|
|||
bool SuspendStream();
|
||||
void StopStream();
|
||||
|
||||
// The control function helps the bluetooth_audio module to register
|
||||
// PortStatusCallbacks_2_2
|
||||
// @return: cookie - the assigned number to this bluetooth_audio output
|
||||
uint16_t RegisterStatusCback(const PortStatusCallbacks_2_2& cbacks);
|
||||
|
||||
// The control function helps the bluetooth_audio module to unregister
|
||||
// PortStatusCallbacks_2_2
|
||||
// @param: cookie - indicates which bluetooth_audio output is
|
||||
void UnregisterStatusCback(uint16_t cookie);
|
||||
|
||||
// The report function is used to report that the Bluetooth stack has notified
|
||||
// the result of startStream or suspendStream, and will invoke
|
||||
// control_result_cb_ to notify registered bluetooth_audio outputs
|
||||
void ReportControlStatus(bool start_resp, const BluetoothAudioStatus& status);
|
||||
|
||||
// The report function is used to report that the Bluetooth stack has notified
|
||||
// the audio configuration changed, and will invoke
|
||||
// audio_configuration_changed_cb_ to notify registered bluetooth_audio
|
||||
// outputs
|
||||
void ReportAudioConfigChanged(
|
||||
const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration&
|
||||
audio_config);
|
||||
|
||||
// The control function is for the bluetooth_audio module to get the current
|
||||
// AudioConfiguration
|
||||
const ::android::hardware::bluetooth::audio::V2_2::AudioConfiguration
|
||||
|
|
Loading…
Reference in a new issue