/* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "BTAudioProviderStub" #include "BluetoothAudioProvider.h" #include #include namespace aidl { namespace android { namespace hardware { namespace bluetooth { namespace audio { BluetoothAudioProvider::BluetoothAudioProvider() { death_recipient_ = ::ndk::ScopedAIBinder_DeathRecipient( AIBinder_DeathRecipient_new(binderDiedCallbackAidl)); } ndk::ScopedAStatus BluetoothAudioProvider::startSession( const std::shared_ptr& host_if, const AudioConfiguration& audio_config, const std::vector& latencyModes, DataMQDesc* _aidl_return) { if (host_if == nullptr) { *_aidl_return = DataMQDesc(); return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } latency_modes_ = latencyModes; audio_config_ = std::make_unique(audio_config); stack_iface_ = host_if; is_binder_died = false; AIBinder_linkToDeath(stack_iface_->asBinder().get(), death_recipient_.get(), this); onSessionReady(_aidl_return); return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus BluetoothAudioProvider::endSession() { LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_); if (stack_iface_ != nullptr) { BluetoothAudioSessionReport::OnSessionEnded(session_type_); if (!is_binder_died) { AIBinder_unlinkToDeath(stack_iface_->asBinder().get(), death_recipient_.get(), this); } } else { LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << " has NO session"; } stack_iface_ = nullptr; audio_config_ = nullptr; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus BluetoothAudioProvider::streamStarted( BluetoothAudioStatus status) { LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ", status=" << toString(status); if (stack_iface_ != nullptr) { BluetoothAudioSessionReport::ReportControlStatus(session_type_, true, status); } else { LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) << ", status=" << toString(status) << " has NO session"; } return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus BluetoothAudioProvider::streamSuspended( BluetoothAudioStatus status) { LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << ", status=" << toString(status); if (stack_iface_ != nullptr) { BluetoothAudioSessionReport::ReportControlStatus(session_type_, false, status); } else { LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_) << ", status=" << toString(status) << " has NO session"; } return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus BluetoothAudioProvider::updateAudioConfiguration( const AudioConfiguration& audio_config) { LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_); if (stack_iface_ == nullptr || audio_config_ == nullptr) { LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << " has NO session"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } if (audio_config.getTag() != audio_config_->getTag()) { LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << " audio config type is not match"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } audio_config_ = std::make_unique(audio_config); BluetoothAudioSessionReport::ReportAudioConfigChanged(session_type_, *audio_config_); return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus BluetoothAudioProvider::setLowLatencyModeAllowed( bool allowed) { LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_); if (stack_iface_ == nullptr) { LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_) << " has NO session"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); } LOG(INFO) << __func__ << " - allowed " << allowed; BluetoothAudioSessionReport::ReportLowLatencyModeAllowedChanged( session_type_, allowed); return ndk::ScopedAStatus::ok(); } void BluetoothAudioProvider::binderDiedCallbackAidl(void* ptr) { LOG(ERROR) << __func__ << " - BluetoothAudio Service died"; auto provider = static_cast(ptr); if (provider == nullptr) { LOG(ERROR) << __func__ << ": Null AudioProvider HAL died"; return; } provider->is_binder_died = true; provider->endSession(); } } // namespace audio } // namespace bluetooth } // namespace hardware } // namespace android } // namespace aidl