• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "BTAudioProviderStub"
18 
19 #include "BluetoothAudioProvider.h"
20 
21 #include <BluetoothAudioSessionReport.h>
22 #include <android-base/logging.h>
23 
24 namespace aidl {
25 namespace android {
26 namespace hardware {
27 namespace bluetooth {
28 namespace audio {
29 
BluetoothAudioProvider()30 BluetoothAudioProvider::BluetoothAudioProvider() {
31   death_recipient_ = ::ndk::ScopedAIBinder_DeathRecipient(
32       AIBinder_DeathRecipient_new(binderDiedCallbackAidl));
33 }
34 
startSession(const std::shared_ptr<IBluetoothAudioPort> & host_if,const AudioConfiguration & audio_config,const std::vector<LatencyMode> & latencyModes,DataMQDesc * _aidl_return)35 ndk::ScopedAStatus BluetoothAudioProvider::startSession(
36     const std::shared_ptr<IBluetoothAudioPort>& host_if,
37     const AudioConfiguration& audio_config,
38     const std::vector<LatencyMode>& latencyModes,
39     DataMQDesc* _aidl_return) {
40   if (host_if == nullptr) {
41     *_aidl_return = DataMQDesc();
42     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
43   }
44 
45   latency_modes_ = latencyModes;
46   audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
47   stack_iface_ = host_if;
48   is_binder_died = false;
49 
50   AIBinder_linkToDeath(stack_iface_->asBinder().get(), death_recipient_.get(),
51                        this);
52 
53   onSessionReady(_aidl_return);
54   return ndk::ScopedAStatus::ok();
55 }
56 
endSession()57 ndk::ScopedAStatus BluetoothAudioProvider::endSession() {
58   LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
59 
60   if (stack_iface_ != nullptr) {
61     BluetoothAudioSessionReport::OnSessionEnded(session_type_);
62 
63     if (!is_binder_died) {
64       AIBinder_unlinkToDeath(stack_iface_->asBinder().get(),
65                              death_recipient_.get(), this);
66     }
67   } else {
68     LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
69               << " has NO session";
70   }
71 
72   stack_iface_ = nullptr;
73   audio_config_ = nullptr;
74 
75   return ndk::ScopedAStatus::ok();
76 }
77 
streamStarted(BluetoothAudioStatus status)78 ndk::ScopedAStatus BluetoothAudioProvider::streamStarted(
79     BluetoothAudioStatus status) {
80   LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
81             << ", status=" << toString(status);
82 
83   if (stack_iface_ != nullptr) {
84     BluetoothAudioSessionReport::ReportControlStatus(session_type_, true,
85                                                      status);
86   } else {
87     LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
88                  << ", status=" << toString(status) << " has NO session";
89   }
90 
91   return ndk::ScopedAStatus::ok();
92 }
93 
streamSuspended(BluetoothAudioStatus status)94 ndk::ScopedAStatus BluetoothAudioProvider::streamSuspended(
95     BluetoothAudioStatus status) {
96   LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
97             << ", status=" << toString(status);
98 
99   if (stack_iface_ != nullptr) {
100     BluetoothAudioSessionReport::ReportControlStatus(session_type_, false,
101                                                      status);
102   } else {
103     LOG(WARNING) << __func__ << " - SessionType=" << toString(session_type_)
104                  << ", status=" << toString(status) << " has NO session";
105   }
106   return ndk::ScopedAStatus::ok();
107 }
108 
updateAudioConfiguration(const AudioConfiguration & audio_config)109 ndk::ScopedAStatus BluetoothAudioProvider::updateAudioConfiguration(
110     const AudioConfiguration& audio_config) {
111   LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
112 
113   if (stack_iface_ == nullptr || audio_config_ == nullptr) {
114     LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
115               << " has NO session";
116     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
117   }
118 
119   if (audio_config.getTag() != audio_config_->getTag()) {
120     LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
121               << " audio config type is not match";
122     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
123   }
124 
125   audio_config_ = std::make_unique<AudioConfiguration>(audio_config);
126   BluetoothAudioSessionReport::ReportAudioConfigChanged(session_type_,
127                                                         *audio_config_);
128   return ndk::ScopedAStatus::ok();
129 }
130 
setLowLatencyModeAllowed(bool allowed)131 ndk::ScopedAStatus BluetoothAudioProvider::setLowLatencyModeAllowed(
132     bool allowed) {
133   LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_);
134 
135   if (stack_iface_ == nullptr) {
136     LOG(INFO) << __func__ << " - SessionType=" << toString(session_type_)
137               << " has NO session";
138     return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
139   }
140   LOG(INFO) << __func__ << " - allowed " << allowed;
141   BluetoothAudioSessionReport::ReportLowLatencyModeAllowedChanged(
142     session_type_, allowed);
143   return ndk::ScopedAStatus::ok();
144 }
145 
binderDiedCallbackAidl(void * ptr)146 void BluetoothAudioProvider::binderDiedCallbackAidl(void* ptr) {
147   LOG(ERROR) << __func__ << " - BluetoothAudio Service died";
148   auto provider = static_cast<BluetoothAudioProvider*>(ptr);
149   if (provider == nullptr) {
150     LOG(ERROR) << __func__ << ": Null AudioProvider HAL died";
151     return;
152   }
153   provider->is_binder_died = true;
154   provider->endSession();
155 }
156 
157 }  // namespace audio
158 }  // namespace bluetooth
159 }  // namespace hardware
160 }  // namespace android
161 }  // namespace aidl