system/bt
リビジョン | 4bf95a18453b01eb0075514249412c11c7a998bc (tree) |
---|---|
日時 | 2019-12-01 09:19:12 |
作者 | android-build-team Robot <android-build-team-robot@goog...> |
コミッター | android-build-team Robot |
Snap for 6041579 from fa6b70419dcdafca30611176df329f9feee07551 to qt-qpr2-release
Change-Id: I97dea43972bfa6991c4d058627dae718ffec3748
@@ -1012,13 +1012,16 @@ class HearingAidImpl : public HearingAid { | ||
1012 | 1012 | } |
1013 | 1013 | } |
1014 | 1014 | |
1015 | - void OnAudioSuspend() { | |
1015 | + void OnAudioSuspend(const std::function<void()>& stop_audio_ticks) { | |
1016 | + CHECK(stop_audio_ticks) << "stop_audio_ticks is empty"; | |
1017 | + | |
1016 | 1018 | if (!audio_running) { |
1017 | 1019 | LOG(WARNING) << __func__ << ": Unexpected audio suspend"; |
1018 | 1020 | } else { |
1019 | 1021 | LOG(INFO) << __func__ << ": audio_running=" << audio_running; |
1020 | 1022 | } |
1021 | 1023 | audio_running = false; |
1024 | + stop_audio_ticks(); | |
1022 | 1025 | |
1023 | 1026 | std::vector<uint8_t> stop({CONTROL_POINT_OP_STOP}); |
1024 | 1027 | for (auto& device : hearingDevices.devices) { |
@@ -1039,23 +1042,33 @@ class HearingAidImpl : public HearingAid { | ||
1039 | 1042 | } |
1040 | 1043 | } |
1041 | 1044 | |
1042 | - void OnAudioResume() { | |
1045 | + void OnAudioResume(const std::function<void()>& start_audio_ticks) { | |
1046 | + CHECK(start_audio_ticks) << "start_audio_ticks is empty"; | |
1047 | + | |
1043 | 1048 | if (audio_running) { |
1044 | 1049 | LOG(ERROR) << __func__ << ": Unexpected Audio Resume"; |
1045 | 1050 | } else { |
1046 | 1051 | LOG(INFO) << __func__ << ": audio_running=" << audio_running; |
1047 | 1052 | } |
1048 | - audio_running = true; | |
1053 | + | |
1054 | + for (auto& device : hearingDevices.devices) { | |
1055 | + if (!device.accepting_audio) continue; | |
1056 | + audio_running = true; | |
1057 | + SendStart(&device); | |
1058 | + } | |
1059 | + | |
1060 | + if (!audio_running) { | |
1061 | + LOG(INFO) << __func__ << ": No device (0/" << GetDeviceCount() | |
1062 | + << ") ready to start"; | |
1063 | + return; | |
1064 | + } | |
1049 | 1065 | |
1050 | 1066 | // TODO: shall we also reset the encoder ? |
1051 | 1067 | encoder_state_release(); |
1052 | 1068 | encoder_state_init(); |
1053 | 1069 | seq_counter = 0; |
1054 | 1070 | |
1055 | - for (auto& device : hearingDevices.devices) { | |
1056 | - if (!device.accepting_audio) continue; | |
1057 | - SendStart(&device); | |
1058 | - } | |
1071 | + start_audio_ticks(); | |
1059 | 1072 | } |
1060 | 1073 | |
1061 | 1074 | uint8_t GetOtherSideStreamStatus(HearingDevice* this_side_device) { |
@@ -1147,10 +1160,9 @@ class HearingAidImpl : public HearingAid { | ||
1147 | 1160 | } |
1148 | 1161 | |
1149 | 1162 | if (left == nullptr && right == nullptr) { |
1150 | - HearingAidAudioSource::Stop(); | |
1151 | - audio_running = false; | |
1152 | - encoder_state_release(); | |
1153 | - current_volume = VOLUME_UNKNOWN; | |
1163 | + LOG(WARNING) << __func__ << ": No more (0/" << GetDeviceCount() | |
1164 | + << ") devices ready"; | |
1165 | + DoDisconnectAudioStop(); | |
1154 | 1166 | return; |
1155 | 1167 | } |
1156 | 1168 |
@@ -1463,8 +1475,17 @@ class HearingAidImpl : public HearingAid { | ||
1463 | 1475 | |
1464 | 1476 | hearingDevices.Remove(address); |
1465 | 1477 | |
1466 | - if (connected) | |
1467 | - callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address); | |
1478 | + if (!connected) { | |
1479 | + return; | |
1480 | + } | |
1481 | + | |
1482 | + callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address); | |
1483 | + for (const auto& device : hearingDevices.devices) { | |
1484 | + if (device.accepting_audio) return; | |
1485 | + } | |
1486 | + LOG(INFO) << __func__ << ": No more (0/" << GetDeviceCount() | |
1487 | + << ") devices ready"; | |
1488 | + DoDisconnectAudioStop(); | |
1468 | 1489 | } |
1469 | 1490 | |
1470 | 1491 | void OnGattDisconnected(tGATT_STATUS status, uint16_t conn_id, |
@@ -1486,7 +1507,16 @@ class HearingAidImpl : public HearingAid { | ||
1486 | 1507 | |
1487 | 1508 | DoDisconnectCleanUp(hearingDevice); |
1488 | 1509 | |
1510 | + // Keep this hearing aid in the list, and allow to reconnect back. | |
1511 | + | |
1489 | 1512 | callbacks->OnConnectionState(ConnectionState::DISCONNECTED, remote_bda); |
1513 | + | |
1514 | + for (const auto& device : hearingDevices.devices) { | |
1515 | + if (device.accepting_audio) return; | |
1516 | + } | |
1517 | + LOG(INFO) << __func__ << ": No more (0/" << GetDeviceCount() | |
1518 | + << ") devices ready"; | |
1519 | + DoDisconnectAudioStop(); | |
1490 | 1520 | } |
1491 | 1521 | |
1492 | 1522 | void DoDisconnectCleanUp(HearingDevice* hearingDevice) { |
@@ -1519,6 +1549,13 @@ class HearingAidImpl : public HearingAid { | ||
1519 | 1549 | hearingDevice->command_acked = false; |
1520 | 1550 | } |
1521 | 1551 | |
1552 | + void DoDisconnectAudioStop() { | |
1553 | + HearingAidAudioSource::Stop(); | |
1554 | + audio_running = false; | |
1555 | + encoder_state_release(); | |
1556 | + current_volume = VOLUME_UNKNOWN; | |
1557 | + } | |
1558 | + | |
1522 | 1559 | void SetVolume(int8_t volume) override { |
1523 | 1560 | VLOG(2) << __func__ << ": " << +volume; |
1524 | 1561 | current_volume = volume; |
@@ -1730,14 +1767,11 @@ class HearingAidAudioReceiverImpl : public HearingAidAudioReceiver { | ||
1730 | 1767 | void OnAudioDataReady(const std::vector<uint8_t>& data) override { |
1731 | 1768 | if (instance) instance->OnAudioDataReady(data); |
1732 | 1769 | } |
1733 | - void OnAudioSuspend(std::promise<void> do_suspend_promise) override { | |
1734 | - if (instance) instance->OnAudioSuspend(); | |
1735 | - do_suspend_promise.set_value(); | |
1770 | + void OnAudioSuspend(const std::function<void()>& stop_audio_ticks) override { | |
1771 | + if (instance) instance->OnAudioSuspend(stop_audio_ticks); | |
1736 | 1772 | } |
1737 | - | |
1738 | - void OnAudioResume(std::promise<void> do_resume_promise) override { | |
1739 | - if (instance) instance->OnAudioResume(); | |
1740 | - do_resume_promise.set_value(); | |
1773 | + void OnAudioResume(const std::function<void()>& start_audio_ticks) override { | |
1774 | + if (instance) instance->OnAudioResume(start_audio_ticks); | |
1741 | 1775 | } |
1742 | 1776 | }; |
1743 | 1777 |
@@ -97,12 +97,20 @@ void hearing_aid_send_ack(tHEARING_AID_CTRL_ACK status) { | ||
97 | 97 | } |
98 | 98 | |
99 | 99 | void start_audio_ticks() { |
100 | + if (data_interval_ms != HA_INTERVAL_10_MS && | |
101 | + data_interval_ms != HA_INTERVAL_20_MS) { | |
102 | + LOG(FATAL) << " Unsupported data interval: " << data_interval_ms; | |
103 | + } | |
104 | + | |
100 | 105 | wakelock_acquire(); |
101 | - audio_timer.SchedulePeriodic(get_main_thread()->GetWeakPtr(), FROM_HERE, base::Bind(&send_audio_data), | |
102 | - base::TimeDelta::FromMilliseconds(data_interval_ms)); | |
106 | + audio_timer.SchedulePeriodic( | |
107 | + get_main_thread()->GetWeakPtr(), FROM_HERE, base::Bind(&send_audio_data), | |
108 | + base::TimeDelta::FromMilliseconds(data_interval_ms)); | |
109 | + LOG(INFO) << __func__ << ": running with data interval: " << data_interval_ms; | |
103 | 110 | } |
104 | 111 | |
105 | 112 | void stop_audio_ticks() { |
113 | + LOG(INFO) << __func__ << ": stopped"; | |
106 | 114 | audio_timer.CancelAndWait(); |
107 | 115 | wakelock_release(); |
108 | 116 | } |
@@ -121,17 +129,12 @@ void hearing_aid_data_cb(tUIPC_CH_ID, tUIPC_EVENT event) { | ||
121 | 129 | UIPC_Ioctl(*uipc_hearing_aid, UIPC_CH_ID_AV_AUDIO, UIPC_SET_READ_POLL_TMO, |
122 | 130 | reinterpret_cast<void*>(0)); |
123 | 131 | |
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(); | |
132 | + do_in_main_thread(FROM_HERE, base::BindOnce(start_audio_ticks)); | |
130 | 133 | break; |
131 | 134 | case UIPC_CLOSE_EVT: |
132 | 135 | LOG(INFO) << __func__ << ": UIPC_CLOSE_EVT"; |
133 | 136 | hearing_aid_send_ack(HEARING_AID_CTRL_ACK_SUCCESS); |
134 | - stop_audio_ticks(); | |
137 | + do_in_main_thread(FROM_HERE, base::BindOnce(stop_audio_ticks)); | |
135 | 138 | break; |
136 | 139 | default: |
137 | 140 | LOG(ERROR) << "Hearing Aid audio data event not recognized:" << event; |
@@ -306,65 +309,52 @@ void hearing_aid_ctrl_cb(tUIPC_CH_ID, tUIPC_EVENT event) { | ||
306 | 309 | } |
307 | 310 | |
308 | 311 | 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 { | |
312 | + if (localAudioReceiver == nullptr) { | |
327 | 313 | LOG(ERROR) << __func__ |
328 | 314 | << ": HEARING_AID_CTRL_CMD_START: audio receiver not started"; |
329 | 315 | return false; |
330 | 316 | } |
331 | - | |
332 | - // hearing_aid_data_cb(UIPC_OPEN_EVT): start_media_task | |
317 | + bt_status_t status; | |
333 | 318 | 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(); | |
319 | + status = do_in_main_thread( | |
320 | + FROM_HERE, base::BindOnce(&HearingAidAudioReceiver::OnAudioResume, | |
321 | + base::Unretained(localAudioReceiver), | |
322 | + start_audio_ticks)); | |
323 | + } else { | |
324 | + auto start_dummy_ticks = []() { | |
325 | + LOG(INFO) << "start_audio_ticks: waiting for data path opened"; | |
326 | + }; | |
327 | + status = do_in_main_thread( | |
328 | + FROM_HERE, base::BindOnce(&HearingAidAudioReceiver::OnAudioResume, | |
329 | + base::Unretained(localAudioReceiver), | |
330 | + start_dummy_ticks)); | |
331 | + } | |
332 | + if (status != BT_STATUS_SUCCESS) { | |
333 | + LOG(ERROR) << __func__ | |
334 | + << ": HEARING_AID_CTRL_CMD_START: do_in_main_thread err=" | |
335 | + << status; | |
336 | + return false; | |
340 | 337 | } |
341 | 338 | return true; |
342 | 339 | } |
343 | 340 | |
344 | 341 | 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 { | |
342 | + if (localAudioReceiver == nullptr) { | |
364 | 343 | LOG(ERROR) << __func__ |
365 | 344 | << ": HEARING_AID_CTRL_CMD_SUSPEND: audio receiver not started"; |
345 | + return false; | |
366 | 346 | } |
367 | - return false; | |
347 | + bt_status_t status = do_in_main_thread( | |
348 | + FROM_HERE, | |
349 | + base::BindOnce(&HearingAidAudioReceiver::OnAudioSuspend, | |
350 | + base::Unretained(localAudioReceiver), stop_audio_ticks)); | |
351 | + if (status != BT_STATUS_SUCCESS) { | |
352 | + LOG(ERROR) << __func__ | |
353 | + << ": HEARING_AID_CTRL_CMD_SUSPEND: do_in_main_thread err=" | |
354 | + << status; | |
355 | + return false; | |
356 | + } | |
357 | + return true; | |
368 | 358 | } |
369 | 359 | } // namespace |
370 | 360 |
@@ -21,7 +21,6 @@ | ||
21 | 21 | #include <base/callback_forward.h> |
22 | 22 | #include <hardware/bt_hearing_aid.h> |
23 | 23 | #include <deque> |
24 | -#include <future> | |
25 | 24 | #include <vector> |
26 | 25 | |
27 | 26 | constexpr uint16_t HEARINGAID_MAX_NUM_UUIDS = 1; |
@@ -39,8 +38,22 @@ class HearingAidAudioReceiver { | ||
39 | 38 | public: |
40 | 39 | virtual ~HearingAidAudioReceiver() = default; |
41 | 40 | virtual void OnAudioDataReady(const std::vector<uint8_t>& data) = 0; |
42 | - virtual void OnAudioSuspend(std::promise<void> do_suspend_promise) = 0; | |
43 | - virtual void OnAudioResume(std::promise<void> do_resume_promise) = 0; | |
41 | + | |
42 | + // API to stop our feeding timer, and notify hearing aid devices that the | |
43 | + // streaming would stop, too. | |
44 | + // | |
45 | + // @param stop_audio_ticks a callable function calls out to stop the media | |
46 | + // timer for reading data. | |
47 | + virtual void OnAudioSuspend( | |
48 | + const std::function<void()>& stop_audio_ticks) = 0; | |
49 | + | |
50 | + // To notify hearing aid devices to be ready for streaming, and start the | |
51 | + // media timer to feed the audio data. | |
52 | + // | |
53 | + // @param start_audio_ticks a callable function calls out to start a periodic | |
54 | + // timer for feeding data from the audio HAL. | |
55 | + virtual void OnAudioResume( | |
56 | + const std::function<void()>& start_audio_ticks) = 0; | |
44 | 57 | }; |
45 | 58 | |
46 | 59 | // Number of rssi reads to attempt when requested |
@@ -1085,7 +1085,7 @@ void btm_read_remote_features_complete(uint8_t* p) { | ||
1085 | 1085 | * Returns void |
1086 | 1086 | * |
1087 | 1087 | ******************************************************************************/ |
1088 | -void btm_read_remote_ext_features_complete(uint8_t* p) { | |
1088 | +void btm_read_remote_ext_features_complete(uint8_t* p, uint8_t evt_len) { | |
1089 | 1089 | tACL_CONN* p_acl_cb; |
1090 | 1090 | uint8_t page_num, max_page; |
1091 | 1091 | uint16_t handle; |
@@ -1093,6 +1093,14 @@ void btm_read_remote_ext_features_complete(uint8_t* p) { | ||
1093 | 1093 | |
1094 | 1094 | BTM_TRACE_DEBUG("btm_read_remote_ext_features_complete"); |
1095 | 1095 | |
1096 | + if (evt_len < HCI_EXT_FEATURES_SUCCESS_EVT_LEN) { | |
1097 | + android_errorWriteLog(0x534e4554, "141552859"); | |
1098 | + BTM_TRACE_ERROR( | |
1099 | + "btm_read_remote_ext_features_complete evt length too short. length=%d", | |
1100 | + evt_len); | |
1101 | + return; | |
1102 | + } | |
1103 | + | |
1096 | 1104 | ++p; |
1097 | 1105 | STREAM_TO_UINT16(handle, p); |
1098 | 1106 | STREAM_TO_UINT8(page_num, p); |
@@ -1112,6 +1120,19 @@ void btm_read_remote_ext_features_complete(uint8_t* p) { | ||
1112 | 1120 | return; |
1113 | 1121 | } |
1114 | 1122 | |
1123 | + if (page_num > HCI_EXT_FEATURES_PAGE_MAX) { | |
1124 | + android_errorWriteLog(0x534e4554, "141552859"); | |
1125 | + BTM_TRACE_ERROR("btm_read_remote_ext_features_complete num_page=%d invalid", | |
1126 | + page_num); | |
1127 | + return; | |
1128 | + } | |
1129 | + | |
1130 | + if (page_num > max_page) { | |
1131 | + BTM_TRACE_WARNING( | |
1132 | + "btm_read_remote_ext_features_complete num_page=%d, max_page=%d " | |
1133 | + "invalid", page_num, max_page); | |
1134 | + } | |
1135 | + | |
1115 | 1136 | p_acl_cb = &btm_cb.acl_db[acl_idx]; |
1116 | 1137 | |
1117 | 1138 | /* Copy the received features page */ |
@@ -119,7 +119,7 @@ extern uint16_t btm_get_acl_disc_reason_code(void); | ||
119 | 119 | extern tBTM_STATUS btm_remove_acl(const RawAddress& bd_addr, |
120 | 120 | tBT_TRANSPORT transport); |
121 | 121 | extern void btm_read_remote_features_complete(uint8_t* p); |
122 | -extern void btm_read_remote_ext_features_complete(uint8_t* p); | |
122 | +extern void btm_read_remote_ext_features_complete(uint8_t* p, uint8_t evt_len); | |
123 | 123 | extern void btm_read_remote_ext_features_failed(uint8_t status, |
124 | 124 | uint16_t handle); |
125 | 125 | extern void btm_read_remote_version_complete(uint8_t* p); |
@@ -75,7 +75,8 @@ static void btu_hcif_authentication_comp_evt(uint8_t* p); | ||
75 | 75 | static void btu_hcif_rmt_name_request_comp_evt(uint8_t* p, uint16_t evt_len); |
76 | 76 | static void btu_hcif_encryption_change_evt(uint8_t* p); |
77 | 77 | static void btu_hcif_read_rmt_features_comp_evt(uint8_t* p); |
78 | -static void btu_hcif_read_rmt_ext_features_comp_evt(uint8_t* p); | |
78 | +static void btu_hcif_read_rmt_ext_features_comp_evt(uint8_t* p, | |
79 | + uint8_t evt_len); | |
79 | 80 | static void btu_hcif_read_rmt_version_comp_evt(uint8_t* p); |
80 | 81 | static void btu_hcif_qos_setup_comp_evt(uint8_t* p); |
81 | 82 | static void btu_hcif_command_complete_evt(BT_HDR* response, void* context); |
@@ -295,7 +296,7 @@ void btu_hcif_process_event(UNUSED_ATTR uint8_t controller_id, BT_HDR* p_msg) { | ||
295 | 296 | btu_hcif_read_rmt_features_comp_evt(p); |
296 | 297 | break; |
297 | 298 | case HCI_READ_RMT_EXT_FEATURES_COMP_EVT: |
298 | - btu_hcif_read_rmt_ext_features_comp_evt(p); | |
299 | + btu_hcif_read_rmt_ext_features_comp_evt(p, hci_evt_len); | |
299 | 300 | break; |
300 | 301 | case HCI_READ_RMT_VERSION_COMP_EVT: |
301 | 302 | btu_hcif_read_rmt_version_comp_evt(p); |
@@ -1211,7 +1212,8 @@ static void btu_hcif_read_rmt_features_comp_evt(uint8_t* p) { | ||
1211 | 1212 | * Returns void |
1212 | 1213 | * |
1213 | 1214 | ******************************************************************************/ |
1214 | -static void btu_hcif_read_rmt_ext_features_comp_evt(uint8_t* p) { | |
1215 | +static void btu_hcif_read_rmt_ext_features_comp_evt(uint8_t* p, | |
1216 | + uint8_t evt_len) { | |
1215 | 1217 | uint8_t* p_cur = p; |
1216 | 1218 | uint8_t status; |
1217 | 1219 | uint16_t handle; |
@@ -1219,7 +1221,7 @@ static void btu_hcif_read_rmt_ext_features_comp_evt(uint8_t* p) { | ||
1219 | 1221 | STREAM_TO_UINT8(status, p_cur); |
1220 | 1222 | |
1221 | 1223 | if (status == HCI_SUCCESS) |
1222 | - btm_read_remote_ext_features_complete(p); | |
1224 | + btm_read_remote_ext_features_complete(p, evt_len); | |
1223 | 1225 | else { |
1224 | 1226 | STREAM_TO_UINT16(handle, p_cur); |
1225 | 1227 | btm_read_remote_ext_features_failed(status, handle); |
@@ -1323,6 +1323,8 @@ typedef struct { | ||
1323 | 1323 | |
1324 | 1324 | #define HCI_FEATURE_BYTES_PER_PAGE 8 |
1325 | 1325 | |
1326 | +#define HCI_EXT_FEATURES_SUCCESS_EVT_LEN 13 | |
1327 | + | |
1326 | 1328 | #define HCI_FEATURES_KNOWN(x) \ |
1327 | 1329 | (((x)[0] | (x)[1] | (x)[2] | (x)[3] | (x)[4] | (x)[5] | (x)[6] | (x)[7]) != 0) |
1328 | 1330 |