• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright 2018 The Android Open Source Project
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 #include "audio_hal_interface/hearing_aid_software_encoding.h"
20 #include "audio_hearing_aid_hw/include/audio_hearing_aid_hw.h"
21 #include "bta_hearing_aid_api.h"
22 #include "btu.h"
23 #include "osi/include/wakelock.h"
24 #include "uipc.h"
25 
26 #include <base/files/file_util.h>
27 #include <include/hardware/bt_av.h>
28 
29 #include "common/repeating_timer.h"
30 #include "common/time_util.h"
31 
32 using base::FilePath;
33 extern const char* audio_ha_hw_dump_ctrl_event(tHEARING_AID_CTRL_CMD event);
34 
35 namespace {
36 int bit_rate = -1;
37 int sample_rate = -1;
38 int data_interval_ms = -1;
39 int num_channels = 2;
40 bluetooth::common::RepeatingTimer audio_timer;
41 HearingAidAudioReceiver* localAudioReceiver = nullptr;
42 std::unique_ptr<tUIPC_STATE> uipc_hearing_aid = nullptr;
43 
44 struct AudioHalStats {
45   size_t media_read_total_underflow_bytes;
46   size_t media_read_total_underflow_count;
47   uint64_t media_read_last_underflow_us;
48 
AudioHalStats__anond0d475210111::AudioHalStats49   AudioHalStats() { Reset(); }
50 
Reset__anond0d475210111::AudioHalStats51   void Reset() {
52     media_read_total_underflow_bytes = 0;
53     media_read_total_underflow_count = 0;
54     media_read_last_underflow_us = 0;
55   }
56 };
57 
58 AudioHalStats stats;
59 
60 bool hearing_aid_on_resume_req(bool start_media_task);
61 bool hearing_aid_on_suspend_req();
62 
send_audio_data()63 void send_audio_data() {
64   uint32_t bytes_per_tick =
65       (num_channels * sample_rate * data_interval_ms * (bit_rate / 8)) / 1000;
66 
67   uint16_t event;
68   uint8_t p_buf[bytes_per_tick];
69 
70   uint32_t bytes_read;
71   if (bluetooth::audio::hearing_aid::is_hal_2_0_enabled()) {
72     bytes_read = bluetooth::audio::hearing_aid::read(p_buf, bytes_per_tick);
73   } else {
74     bytes_read = UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, &event,
75                            p_buf, bytes_per_tick);
76   }
77 
78   VLOG(2) << "bytes_read: " << bytes_read;
79   if (bytes_read < bytes_per_tick) {
80     stats.media_read_total_underflow_bytes += bytes_per_tick - bytes_read;
81     stats.media_read_total_underflow_count++;
82     stats.media_read_last_underflow_us =
83         bluetooth::common::time_get_os_boottime_us();
84   }
85 
86   std::vector<uint8_t> data(p_buf, p_buf + bytes_read);
87 
88   if (localAudioReceiver != nullptr) {
89     localAudioReceiver->OnAudioDataReady(data);
90   }
91 }
92 
hearing_aid_send_ack(tHEARING_AID_CTRL_ACK status)93 void hearing_aid_send_ack(tHEARING_AID_CTRL_ACK status) {
94   uint8_t ack = status;
95   DVLOG(2) << "Hearing Aid audio ctrl ack: " << status;
96   UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0, &ack, sizeof(ack));
97 }
98 
start_audio_ticks()99 void start_audio_ticks() {
100   wakelock_acquire();
101   audio_timer.SchedulePeriodic(get_main_thread()->GetWeakPtr(), FROM_HERE, base::Bind(&send_audio_data),
102                                base::TimeDelta::FromMilliseconds(data_interval_ms));
103 }
104 
stop_audio_ticks()105 void stop_audio_ticks() {
106   audio_timer.CancelAndWait();
107   wakelock_release();
108 }
109 
hearing_aid_data_cb(tUIPC_CH_ID,tUIPC_EVENT event)110 void hearing_aid_data_cb(tUIPC_CH_ID, tUIPC_EVENT event) {
111   DVLOG(2) << "Hearing Aid audio data event: " << event;
112   switch (event) {
113     case UIPC_OPEN_EVT:
114       LOG(INFO) << __func__ << ": UIPC_OPEN_EVT";
115       /*
116        * Read directly from media task from here on (keep callback for
117        * connection events.
118        */
119       UIPC_Ioctl(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO,
120                  UIPC_REG_REMOVE_ACTIVE_READSET, NULL);
121       UIPC_Ioctl(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO,
122                  reinterpret_cast<void*>(0));
123 
124       if (data_interval_ms != HA_INTERVAL_10_MS &&
125           data_interval_ms != HA_INTERVAL_20_MS) {
126         LOG(FATAL) << " Unsupported data interval: " << data_interval_ms;
127       }
128 
129       start_audio_ticks();
130       break;
131     case UIPC_CLOSE_EVT:
132       LOG(INFO) << __func__ << ": UIPC_CLOSE_EVT";
133       hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
134       stop_audio_ticks();
135       break;
136     default:
137       LOG(ERROR) << "Hearing Aid audio data event not recognized:" << event;
138   }
139 }
140 
hearing_aid_recv_ctrl_data()141 void hearing_aid_recv_ctrl_data() {
142   tHEARING_AID_CTRL_CMD cmd = HEARING_AID_CTRL_CMD_NONE;
143   int n;
144 
145   uint8_t read_cmd = 0; /* The read command size is one octet */
146   n = UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, NULL, &read_cmd, 1);
147   cmd = static_cast<tHEARING_AID_CTRL_CMD>(read_cmd);
148 
149   /* detach on ctrl channel means audioflinger process was terminated */
150   if (n == 0) {
151     LOG(WARNING) << __func__ << "CTRL CH DETACHED";
152     UIPC_Close(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL);
153     return;
154   }
155 
156   LOG(INFO) << __func__ << " " << audio_ha_hw_dump_ctrl_event(cmd);
157   //  a2dp_cmd_pending = cmd;
158 
159   tHEARING_AID_CTRL_ACK ctrl_ack_status;
160 
161   switch (cmd) {
162     case HEARING_AID_CTRL_CMD_CHECK_READY:
163       hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
164       break;
165 
166     case HEARING_AID_CTRL_CMD_START:
167       ctrl_ack_status = HEARING_AID_CTRL_ACK_SUCCESS;
168       // timer is restarted in UIPC_Open
169       if (!hearing_aid_on_resume_req(false)) {
170         ctrl_ack_status = HEARING_AID_CTRL_ACK_FAILURE;
171       } else {
172         UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, hearing_aid_data_cb,
173                   HEARING_AID_DATA_PATH);
174       }
175       hearing_aid_send_ack(ctrl_ack_status);
176       break;
177 
178     case HEARING_AID_CTRL_CMD_STOP:
179       if (!hearing_aid_on_suspend_req()) {
180         LOG(INFO) << __func__ << ":HEARING_AID_CTRL_CMD_STOP: hearing_aid_on_suspend_req() errs, but ignored.";
181       }
182       hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
183       break;
184 
185     case HEARING_AID_CTRL_CMD_SUSPEND:
186       ctrl_ack_status = HEARING_AID_CTRL_ACK_SUCCESS;
187       if (!hearing_aid_on_suspend_req()) {
188         ctrl_ack_status = HEARING_AID_CTRL_ACK_FAILURE;
189       }
190       hearing_aid_send_ack(ctrl_ack_status);
191       break;
192 
193     case HEARING_AID_CTRL_GET_OUTPUT_AUDIO_CONFIG: {
194       btav_a2dp_codec_config_t codec_config;
195       btav_a2dp_codec_config_t codec_capability;
196       if (sample_rate == 16000) {
197         codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_16000;
198         codec_capability.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_16000;
199       } else if (sample_rate == 24000) {
200         codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_24000;
201         codec_capability.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_24000;
202       } else {
203         LOG(FATAL) << "unsupported sample rate: " << sample_rate;
204       }
205 
206       codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16;
207       codec_capability.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16;
208 
209       codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
210       codec_capability.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
211 
212       hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
213       // Send the current codec config
214       UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
215                 reinterpret_cast<const uint8_t*>(&codec_config.sample_rate),
216                 sizeof(btav_a2dp_codec_sample_rate_t));
217       UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
218                 reinterpret_cast<const uint8_t*>(&codec_config.bits_per_sample),
219                 sizeof(btav_a2dp_codec_bits_per_sample_t));
220       UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
221                 reinterpret_cast<const uint8_t*>(&codec_config.channel_mode),
222                 sizeof(btav_a2dp_codec_channel_mode_t));
223       // Send the current codec capability
224       UIPC_Send(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
225                 reinterpret_cast<const uint8_t*>(&codec_capability.sample_rate),
226                 sizeof(btav_a2dp_codec_sample_rate_t));
227       UIPC_Send(
228           *uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
229           reinterpret_cast<const uint8_t*>(&codec_capability.bits_per_sample),
230           sizeof(btav_a2dp_codec_bits_per_sample_t));
231       UIPC_Send(
232           *uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
233           reinterpret_cast<const uint8_t*>(&codec_capability.channel_mode),
234           sizeof(btav_a2dp_codec_channel_mode_t));
235       break;
236     }
237 
238     case HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG: {
239       // TODO: we only support one config for now!
240       btav_a2dp_codec_config_t codec_config;
241       codec_config.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
242       codec_config.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
243       codec_config.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
244 
245       hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS);
246       // Send the current codec config
247       if (UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
248                     reinterpret_cast<uint8_t*>(&codec_config.sample_rate),
249                     sizeof(btav_a2dp_codec_sample_rate_t)) !=
250           sizeof(btav_a2dp_codec_sample_rate_t)) {
251         LOG(ERROR) << __func__ << "Error reading sample rate from audio HAL";
252         break;
253       }
254       if (UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
255                     reinterpret_cast<uint8_t*>(&codec_config.bits_per_sample),
256                     sizeof(btav_a2dp_codec_bits_per_sample_t)) !=
257           sizeof(btav_a2dp_codec_bits_per_sample_t)) {
258         LOG(ERROR) << __func__
259                    << "Error reading bits per sample from audio HAL";
260 
261         break;
262       }
263       if (UIPC_Read(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, 0,
264                     reinterpret_cast<uint8_t*>(&codec_config.channel_mode),
265                     sizeof(btav_a2dp_codec_channel_mode_t)) !=
266           sizeof(btav_a2dp_codec_channel_mode_t)) {
267         LOG(ERROR) << __func__ << "Error reading channel mode from audio HAL";
268 
269         break;
270       }
271       LOG(INFO) << __func__ << " HEARING_AID_CTRL_SET_OUTPUT_AUDIO_CONFIG: "
272                 << "sample_rate=" << codec_config.sample_rate
273                 << "bits_per_sample=" << codec_config.bits_per_sample
274                 << "channel_mode=" << codec_config.channel_mode;
275       break;
276     }
277 
278     default:
279       LOG(ERROR) << __func__ << "UNSUPPORTED CMD: " << cmd;
280       hearing_aid_send_ack(HEARING_AID_CTRL_ACK_FAILURE);
281       break;
282   }
283   LOG(INFO) << __func__
284             << " a2dp-ctrl-cmd : " << audio_ha_hw_dump_ctrl_event(cmd)
285             << " DONE";
286 }
287 
hearing_aid_ctrl_cb(tUIPC_CH_ID,tUIPC_EVENT event)288 void hearing_aid_ctrl_cb(tUIPC_CH_ID, tUIPC_EVENT event) {
289   VLOG(2) << "Hearing Aid audio ctrl event: " << event;
290   switch (event) {
291     case UIPC_OPEN_EVT:
292       break;
293     case UIPC_CLOSE_EVT:
294       /* restart ctrl server unless we are shutting down */
295       if (HearingAid::IsHearingAidRunning()) {
296         UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, hearing_aid_ctrl_cb,
297                   HEARING_AID_CTRL_PATH);
298       }
299       break;
300     case UIPC_RX_DATA_READY_EVT:
301       hearing_aid_recv_ctrl_data();
302       break;
303     default:
304       LOG(ERROR) << "Hearing Aid audio ctrl unrecognized event: " << event;
305   }
306 }
307 
hearing_aid_on_resume_req(bool start_media_task)308 bool hearing_aid_on_resume_req(bool start_media_task) {
309   // hearing_aid_recv_ctrl_data(HEARING_AID_CTRL_CMD_START)
310   if (localAudioReceiver != nullptr) {
311     // Call OnAudioResume and block till it returns.
312     std::promise<void> do_resume_promise;
313     std::future<void> do_resume_future = do_resume_promise.get_future();
314     bt_status_t status = do_in_main_thread(
315         FROM_HERE, base::BindOnce(&HearingAidAudioReceiver::OnAudioResume,
316                                   base::Unretained(localAudioReceiver),
317                                   std::move(do_resume_promise)));
318     if (status == BT_STATUS_SUCCESS) {
319       do_resume_future.wait();
320     } else {
321       LOG(ERROR) << __func__
322                  << ": HEARING_AID_CTRL_CMD_START: do_in_main_thread err="
323                  << status;
324       return false;
325     }
326   } else {
327     LOG(ERROR) << __func__
328                << ": HEARING_AID_CTRL_CMD_START: audio receiver not started";
329     return false;
330   }
331 
332   // hearing_aid_data_cb(UIPC_OPEN_EVT): start_media_task
333   if (start_media_task) {
334     if (data_interval_ms != HA_INTERVAL_10_MS &&
335         data_interval_ms != HA_INTERVAL_20_MS) {
336       LOG(FATAL) << " Unsupported data interval: " << data_interval_ms;
337       data_interval_ms = HA_INTERVAL_10_MS;
338     }
339     start_audio_ticks();
340   }
341   return true;
342 }
343 
hearing_aid_on_suspend_req()344 bool hearing_aid_on_suspend_req() {
345   // hearing_aid_recv_ctrl_data(HEARING_AID_CTRL_CMD_SUSPEND): stop_media_task
346   stop_audio_ticks();
347   if (localAudioReceiver != nullptr) {
348     // Call OnAudioSuspend and block till it returns.
349     std::promise<void> do_suspend_promise;
350     std::future<void> do_suspend_future = do_suspend_promise.get_future();
351     bt_status_t status = do_in_main_thread(
352         FROM_HERE, base::BindOnce(&HearingAidAudioReceiver::OnAudioSuspend,
353                                   base::Unretained(localAudioReceiver),
354                                   std::move(do_suspend_promise)));
355     if (status == BT_STATUS_SUCCESS) {
356       do_suspend_future.wait();
357       return true;
358     } else {
359       LOG(ERROR) << __func__
360                  << ": HEARING_AID_CTRL_CMD_SUSPEND: do_in_main_thread err="
361                  << status;
362     }
363   } else {
364     LOG(ERROR) << __func__
365                << ": HEARING_AID_CTRL_CMD_SUSPEND: audio receiver not started";
366   }
367   return false;
368 }
369 }  // namespace
370 
Start(const CodecConfiguration & codecConfiguration,HearingAidAudioReceiver * audioReceiver,uint16_t remote_delay_ms)371 void HearingAidAudioSource::Start(const CodecConfiguration& codecConfiguration,
372                                   HearingAidAudioReceiver* audioReceiver,
373                                   uint16_t remote_delay_ms) {
374   LOG(INFO) << __func__ << ": Hearing Aid Source Open";
375 
376   bit_rate = codecConfiguration.bit_rate;
377   sample_rate = codecConfiguration.sample_rate;
378   data_interval_ms = codecConfiguration.data_interval_ms;
379 
380   stats.Reset();
381 
382   if (bluetooth::audio::hearing_aid::is_hal_2_0_enabled()) {
383     bluetooth::audio::hearing_aid::start_session();
384     bluetooth::audio::hearing_aid::set_remote_delay(remote_delay_ms);
385   }
386   localAudioReceiver = audioReceiver;
387 }
388 
Stop()389 void HearingAidAudioSource::Stop() {
390   LOG(INFO) << __func__ << ": Hearing Aid Source Close";
391 
392   localAudioReceiver = nullptr;
393   if (bluetooth::audio::hearing_aid::is_hal_2_0_enabled()) {
394     bluetooth::audio::hearing_aid::end_session();
395   }
396 
397   stop_audio_ticks();
398 }
399 
Initialize()400 void HearingAidAudioSource::Initialize() {
401   auto stream_cb = bluetooth::audio::hearing_aid::StreamCallbacks{
402       .on_resume_ = hearing_aid_on_resume_req,
403       .on_suspend_ = hearing_aid_on_suspend_req,
404   };
405   if (!bluetooth::audio::hearing_aid::init(stream_cb, get_main_thread())) {
406     LOG(WARNING) << __func__ << ": Using legacy HAL";
407     uipc_hearing_aid = UIPC_Init();
408     UIPC_Open(*uipc_hearing_aid, UIPC_CH_ID_AV_CTRL, hearing_aid_ctrl_cb, HEARING_AID_CTRL_PATH);
409   }
410 }
411 
CleanUp()412 void HearingAidAudioSource::CleanUp() {
413   if (bluetooth::audio::hearing_aid::is_hal_2_0_enabled()) {
414     bluetooth::audio::hearing_aid::cleanup();
415   } else {
416     UIPC_Close(*uipc_hearing_aid, UIPC_CH_ID_ALL);
417     uipc_hearing_aid = nullptr;
418   }
419 }
420 
DebugDump(int fd)421 void HearingAidAudioSource::DebugDump(int fd) {
422   uint64_t now_us = bluetooth::common::time_get_os_boottime_us();
423   std::stringstream stream;
424   stream << "  Hearing Aid Audio HAL:"
425          << "\n    Counts (underflow)                                      : "
426          << stats.media_read_total_underflow_count
427          << "\n    Bytes (underflow)                                       : "
428          << stats.media_read_total_underflow_bytes
429          << "\n    Last update time ago in ms (underflow)                  : "
430          << (stats.media_read_last_underflow_us > 0
431                  ? (unsigned long long)(now_us -
432                                         stats.media_read_last_underflow_us) /
433                        1000
434                  : 0)
435          << std::endl;
436   dprintf(fd, "%s", stream.str().c_str());
437 }
438