1 /*
2  * Copyright 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 "BTAudioHearingAidAIDL"
18 
19 #include "hearing_aid_software_encoding_aidl.h"
20 
21 #include <bluetooth/log.h>
22 
23 #include "audio_hearing_aid_hw/include/audio_hearing_aid_hw.h"
24 #include "client_interface_aidl.h"
25 #include "os/log.h"
26 #include "osi/include/properties.h"
27 
28 namespace fmt {
29 template <>
30 struct formatter<audio_usage_t> : enum_formatter<audio_usage_t> {};
31 template <>
32 struct formatter<audio_content_type_t> : enum_formatter<audio_content_type_t> {
33 };
34 }  // namespace fmt
35 
36 namespace {
37 
38 using ::aidl::android::hardware::bluetooth::audio::ChannelMode;
39 using ::aidl::android::hardware::bluetooth::audio::CodecType;
40 using ::bluetooth::audio::aidl::AudioConfiguration;
41 using ::bluetooth::audio::aidl::BluetoothAudioCtrlAck;
42 using ::bluetooth::audio::aidl::LatencyMode;
43 using ::bluetooth::audio::aidl::PcmConfiguration;
44 using ::bluetooth::audio::aidl::SessionType;
45 using ::bluetooth::audio::aidl::hearing_aid::StreamCallbacks;
46 using namespace bluetooth;
47 
48 // Transport implementation for Hearing Aids
49 class HearingAidTransport
50     : public bluetooth::audio::aidl::IBluetoothSinkTransportInstance {
51  public:
HearingAidTransport(StreamCallbacks stream_cb)52   HearingAidTransport(StreamCallbacks stream_cb)
53       : IBluetoothSinkTransportInstance(
54             SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH,
55             (AudioConfiguration){}),
56         stream_cb_(std::move(stream_cb)),
57         remote_delay_report_ms_(0),
58         total_bytes_read_(0),
59         data_position_({}){};
60 
StartRequest(bool is_low_latency)61   BluetoothAudioCtrlAck StartRequest(bool is_low_latency) override {
62     log::info("");
63     if (stream_cb_.on_resume_(true)) {
64       return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
65     }
66     return BluetoothAudioCtrlAck::FAILURE;
67   }
68 
SuspendRequest()69   BluetoothAudioCtrlAck SuspendRequest() override {
70     log::info("");
71     if (stream_cb_.on_suspend_()) {
72       uint8_t p_buf[AUDIO_STREAM_OUTPUT_BUFFER_SZ * 2];
73       ::bluetooth::audio::aidl::hearing_aid::read(p_buf, sizeof(p_buf));
74       return BluetoothAudioCtrlAck::SUCCESS_FINISHED;
75     } else {
76       return BluetoothAudioCtrlAck::FAILURE;
77     }
78   }
79 
StopRequest()80   void StopRequest() override {
81     log::info("");
82     if (stream_cb_.on_suspend_()) {
83       // flush
84       uint8_t p_buf[AUDIO_STREAM_OUTPUT_BUFFER_SZ * 2];
85       ::bluetooth::audio::aidl::hearing_aid::read(p_buf, sizeof(p_buf));
86     }
87   }
88 
SetLatencyMode(LatencyMode latency_mode)89   void SetLatencyMode(LatencyMode latency_mode) override {}
90 
GetPresentationPosition(uint64_t * remote_delay_report_ns,uint64_t * total_bytes_read,timespec * data_position)91   bool GetPresentationPosition(uint64_t* remote_delay_report_ns,
92                                uint64_t* total_bytes_read,
93                                timespec* data_position) override {
94     log::verbose("data={} byte(s), timestamp={}.{}s, delay report={} msec.",
95                  total_bytes_read_, data_position_.tv_sec,
96                  data_position_.tv_nsec, remote_delay_report_ms_);
97     if (remote_delay_report_ns != nullptr) {
98       *remote_delay_report_ns = remote_delay_report_ms_ * 1000000u;
99     }
100     if (total_bytes_read != nullptr) {
101       *total_bytes_read = total_bytes_read_;
102     }
103     if (data_position != nullptr) {
104       *data_position = data_position_;
105     }
106 
107     return true;
108   }
109 
SourceMetadataChanged(const source_metadata_v7_t & source_metadata)110   void SourceMetadataChanged(
111       const source_metadata_v7_t& source_metadata) override {
112     auto track_count = source_metadata.track_count;
113     auto tracks = source_metadata.tracks;
114     log::info("{} track(s) received", track_count);
115     while (track_count) {
116       log::verbose("usage={}, content_type={}, gain={}", tracks->base.usage,
117                    tracks->base.content_type, tracks->base.gain);
118       --track_count;
119       ++tracks;
120     }
121   }
122 
SinkMetadataChanged(const sink_metadata_v7_t &)123   void SinkMetadataChanged(const sink_metadata_v7_t&) override {}
124 
ResetPresentationPosition()125   void ResetPresentationPosition() override {
126     log::verbose("called.");
127     remote_delay_report_ms_ = 0;
128     total_bytes_read_ = 0;
129     data_position_ = {};
130   }
131 
LogBytesRead(size_t bytes_read)132   void LogBytesRead(size_t bytes_read) override {
133     if (bytes_read) {
134       total_bytes_read_ += bytes_read;
135       clock_gettime(CLOCK_MONOTONIC, &data_position_);
136     }
137   }
138 
SetRemoteDelay(uint16_t delay_report_ms)139   void SetRemoteDelay(uint16_t delay_report_ms) {
140     log::info("delay_report={} msec", delay_report_ms);
141     remote_delay_report_ms_ = delay_report_ms;
142   }
143 
144  private:
145   StreamCallbacks stream_cb_;
146   uint16_t remote_delay_report_ms_;
147   uint64_t total_bytes_read_;
148   timespec data_position_;
149 };
150 
HearingAidGetSelectedHalPcmConfig(PcmConfiguration * hal_pcm_config)151 bool HearingAidGetSelectedHalPcmConfig(PcmConfiguration* hal_pcm_config) {
152   if (hal_pcm_config == nullptr) return false;
153   // TODO: we only support one config for now!
154   hal_pcm_config->sampleRateHz = 16000;
155   hal_pcm_config->bitsPerSample = 16;
156   hal_pcm_config->channelMode = ChannelMode::STEREO;
157   return true;
158 }
159 
160 // Sink instance of Hearing Aids to provide call-in APIs for Bluetooth Audio Hal
161 HearingAidTransport* hearing_aid_sink = nullptr;
162 // Common interface to call-out into Bluetooth Audio Hal
163 bluetooth::audio::aidl::BluetoothAudioSinkClientInterface*
164     hearing_aid_hal_clientinterface = nullptr;
165 bool btaudio_hearing_aid_disabled = false;
166 bool is_configured = false;
167 
168 // Save the value if the remote reports its delay before hearing_aid_sink is
169 // initialized
170 uint16_t remote_delay_ms = 0;
171 
is_hal_force_disabled()172 bool is_hal_force_disabled() {
173   if (!is_configured) {
174     btaudio_hearing_aid_disabled =
175         osi_property_get_bool(BLUETOOTH_AUDIO_HAL_PROP_DISABLED, false);
176     is_configured = true;
177   }
178   return btaudio_hearing_aid_disabled;
179 }
180 
181 }  // namespace
182 
183 namespace bluetooth {
184 namespace audio {
185 namespace aidl {
186 namespace hearing_aid {
187 
is_hal_enabled()188 bool is_hal_enabled() { return hearing_aid_hal_clientinterface != nullptr; }
189 
init(StreamCallbacks stream_cb,bluetooth::common::MessageLoopThread *)190 bool init(StreamCallbacks stream_cb,
191           bluetooth::common::MessageLoopThread* /*message_loop*/) {
192   log::info("");
193 
194   if (is_hal_force_disabled()) {
195     log::error("BluetoothAudio HAL is disabled");
196     return false;
197   }
198 
199   if (!BluetoothAudioClientInterface::is_aidl_available()) {
200     log::error("BluetoothAudio AIDL implementation does not exist");
201     return false;
202   }
203 
204   hearing_aid_sink = new HearingAidTransport(std::move(stream_cb));
205   hearing_aid_hal_clientinterface =
206       new bluetooth::audio::aidl::BluetoothAudioSinkClientInterface(
207           hearing_aid_sink);
208   if (!hearing_aid_hal_clientinterface->IsValid()) {
209     log::warn("BluetoothAudio HAL for Hearing Aid is invalid?!");
210     delete hearing_aid_hal_clientinterface;
211     hearing_aid_hal_clientinterface = nullptr;
212     delete hearing_aid_sink;
213     hearing_aid_sink = nullptr;
214     return false;
215   }
216 
217   if (remote_delay_ms != 0) {
218     log::info("restore DELAY {} ms", remote_delay_ms);
219     hearing_aid_sink->SetRemoteDelay(remote_delay_ms);
220     remote_delay_ms = 0;
221   }
222 
223   return true;
224 }
225 
cleanup()226 void cleanup() {
227   log::info("");
228   if (!is_hal_enabled()) return;
229   end_session();
230   delete hearing_aid_hal_clientinterface;
231   hearing_aid_hal_clientinterface = nullptr;
232   delete hearing_aid_sink;
233   hearing_aid_sink = nullptr;
234   remote_delay_ms = 0;
235 }
236 
start_session()237 void start_session() {
238   log::info("");
239   if (!is_hal_enabled()) return;
240   AudioConfiguration audio_config;
241   PcmConfiguration pcm_config{};
242   if (!HearingAidGetSelectedHalPcmConfig(&pcm_config)) {
243     log::error("cannot get PCM config");
244     return;
245   }
246   audio_config.set<AudioConfiguration::pcmConfig>(pcm_config);
247   if (!hearing_aid_hal_clientinterface->UpdateAudioConfig(audio_config)) {
248     log::error("cannot update audio config to HAL");
249     return;
250   }
251   hearing_aid_hal_clientinterface->StartSession();
252 }
253 
end_session()254 void end_session() {
255   log::info("");
256   if (!is_hal_enabled()) return;
257   hearing_aid_hal_clientinterface->EndSession();
258 }
259 
read(uint8_t * p_buf,uint32_t len)260 size_t read(uint8_t* p_buf, uint32_t len) {
261   if (!is_hal_enabled()) return 0;
262   return hearing_aid_hal_clientinterface->ReadAudioData(p_buf, len);
263 }
264 
265 // Update Hearing Aids delay report to BluetoothAudio HAL
set_remote_delay(uint16_t delay_report_ms)266 void set_remote_delay(uint16_t delay_report_ms) {
267   if (!is_hal_enabled()) {
268     log::info("not ready for DelayReport {} ms", delay_report_ms);
269     remote_delay_ms = delay_report_ms;
270     return;
271   }
272   log::info("delay_report_ms={} ms", delay_report_ms);
273   hearing_aid_sink->SetRemoteDelay(delay_report_ms);
274 }
275 
276 }  // namespace hearing_aid
277 }  // namespace aidl
278 }  // namespace audio
279 }  // namespace bluetooth
280