device_port_proxy.cc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. /*
  2. * Copyright 2019 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. #define LOG_TAG "BTAudioHalDeviceProxy"
  17. #include <android-base/logging.h>
  18. #include <android-base/stringprintf.h>
  19. #include <audio_utils/primitives.h>
  20. #include <inttypes.h>
  21. #include <log/log.h>
  22. #include <stdlib.h>
  23. #include "BluetoothAudioSessionControl.h"
  24. #include "device_port_proxy.h"
  25. #include "stream_apis.h"
  26. #include "utils.h"
  27. namespace android {
  28. namespace bluetooth {
  29. namespace audio {
  30. using ::android::base::StringPrintf;
  31. using ::android::bluetooth::audio::BluetoothAudioSessionControl;
  32. using ::android::hardware::bluetooth::audio::V2_0::BitsPerSample;
  33. using ::android::hardware::bluetooth::audio::V2_0::ChannelMode;
  34. using ::android::hardware::bluetooth::audio::V2_0::PcmParameters;
  35. using ::android::hardware::bluetooth::audio::V2_0::SampleRate;
  36. using ::android::hardware::bluetooth::audio::V2_0::SessionType;
  37. using BluetoothAudioStatus =
  38. ::android::hardware::bluetooth::audio::V2_0::Status;
  39. using ControlResultCallback = std::function<void(
  40. uint16_t cookie, bool start_resp, const BluetoothAudioStatus& status)>;
  41. using SessionChangedCallback = std::function<void(uint16_t cookie)>;
  42. namespace {
  43. unsigned int SampleRateToAudioFormat(SampleRate sample_rate) {
  44. switch (sample_rate) {
  45. case SampleRate::RATE_16000:
  46. return 16000;
  47. case SampleRate::RATE_24000:
  48. return 24000;
  49. case SampleRate::RATE_44100:
  50. return 44100;
  51. case SampleRate::RATE_48000:
  52. return 48000;
  53. case SampleRate::RATE_88200:
  54. return 88200;
  55. case SampleRate::RATE_96000:
  56. return 96000;
  57. case SampleRate::RATE_176400:
  58. return 176400;
  59. case SampleRate::RATE_192000:
  60. return 192000;
  61. default:
  62. return kBluetoothDefaultSampleRate;
  63. }
  64. }
  65. audio_channel_mask_t ChannelModeToAudioFormat(ChannelMode channel_mode) {
  66. switch (channel_mode) {
  67. case ChannelMode::MONO:
  68. return AUDIO_CHANNEL_OUT_MONO;
  69. case ChannelMode::STEREO:
  70. return AUDIO_CHANNEL_OUT_STEREO;
  71. default:
  72. return kBluetoothDefaultOutputChannelModeMask;
  73. }
  74. }
  75. audio_format_t BitsPerSampleToAudioFormat(BitsPerSample bits_per_sample) {
  76. switch (bits_per_sample) {
  77. case BitsPerSample::BITS_16:
  78. return AUDIO_FORMAT_PCM_16_BIT;
  79. case BitsPerSample::BITS_24:
  80. return AUDIO_FORMAT_PCM_24_BIT_PACKED;
  81. case BitsPerSample::BITS_32:
  82. return AUDIO_FORMAT_PCM_32_BIT;
  83. default:
  84. return kBluetoothDefaultAudioFormatBitsPerSample;
  85. }
  86. }
  87. // The maximum time to wait in std::condition_variable::wait_for()
  88. constexpr unsigned int kMaxWaitingTimeMs = 4500;
  89. } // namespace
  90. BluetoothAudioPortOut::BluetoothAudioPortOut()
  91. : state_(BluetoothStreamState::DISABLED),
  92. session_type_(SessionType::UNKNOWN),
  93. cookie_(android::bluetooth::audio::kObserversCookieUndefined) {}
  94. bool BluetoothAudioPortOut::SetUp(audio_devices_t devices) {
  95. if (!init_session_type(devices)) return false;
  96. state_ = BluetoothStreamState::STANDBY;
  97. auto control_result_cb = [port = this](uint16_t cookie, bool start_resp,
  98. const BluetoothAudioStatus& status) {
  99. if (!port->in_use()) {
  100. LOG(ERROR) << "control_result_cb: BluetoothAudioPortOut is not in use";
  101. return;
  102. }
  103. if (port->cookie_ != cookie) {
  104. LOG(ERROR) << "control_result_cb: proxy of device port (cookie=" << StringPrintf("%#hx", cookie)
  105. << ") is corrupted";
  106. return;
  107. }
  108. port->ControlResultHandler(status);
  109. };
  110. auto session_changed_cb = [port = this](uint16_t cookie) {
  111. if (!port->in_use()) {
  112. LOG(ERROR) << "session_changed_cb: BluetoothAudioPortOut is not in use";
  113. return;
  114. }
  115. if (port->cookie_ != cookie) {
  116. LOG(ERROR) << "session_changed_cb: proxy of device port (cookie=" << StringPrintf("%#hx", cookie)
  117. << ") is corrupted";
  118. return;
  119. }
  120. port->SessionChangedHandler();
  121. };
  122. ::android::bluetooth::audio::PortStatusCallbacks cbacks = {
  123. .control_result_cb_ = control_result_cb,
  124. .session_changed_cb_ = session_changed_cb};
  125. cookie_ = BluetoothAudioSessionControl::RegisterControlResultCback(
  126. session_type_, cbacks);
  127. LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_);
  128. return (cookie_ != android::bluetooth::audio::kObserversCookieUndefined);
  129. }
  130. bool BluetoothAudioPortOut::init_session_type(audio_devices_t device) {
  131. switch (device) {
  132. case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
  133. case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
  134. case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
  135. LOG(VERBOSE) << __func__ << ": device=AUDIO_DEVICE_OUT_BLUETOOTH_A2DP (HEADPHONES/SPEAKER) ("
  136. << StringPrintf("%#x", device) << ")";
  137. session_type_ = SessionType::A2DP_SOFTWARE_ENCODING_DATAPATH;
  138. break;
  139. case AUDIO_DEVICE_OUT_HEARING_AID:
  140. LOG(VERBOSE) << __func__ << ": device=AUDIO_DEVICE_OUT_HEARING_AID (MEDIA/VOICE) (" << StringPrintf("%#x", device)
  141. << ")";
  142. session_type_ = SessionType::HEARING_AID_SOFTWARE_ENCODING_DATAPATH;
  143. break;
  144. default:
  145. LOG(ERROR) << __func__ << ": unknown device=" << StringPrintf("%#x", device);
  146. return false;
  147. }
  148. if (!BluetoothAudioSessionControl::IsSessionReady(session_type_)) {
  149. LOG(ERROR) << __func__ << ": device=" << StringPrintf("%#x", device) << ", session_type=" << toString(session_type_)
  150. << " is not ready";
  151. return false;
  152. }
  153. return true;
  154. }
  155. void BluetoothAudioPortOut::TearDown() {
  156. if (!in_use()) {
  157. LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
  158. << ", cookie=" << StringPrintf("%#hx", cookie_) << " unknown monitor";
  159. return;
  160. }
  161. LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_);
  162. BluetoothAudioSessionControl::UnregisterControlResultCback(session_type_,
  163. cookie_);
  164. cookie_ = android::bluetooth::audio::kObserversCookieUndefined;
  165. }
  166. void BluetoothAudioPortOut::ControlResultHandler(
  167. const BluetoothAudioStatus& status) {
  168. if (!in_use()) {
  169. LOG(ERROR) << __func__ << ": BluetoothAudioPortOut is not in use";
  170. return;
  171. }
  172. std::unique_lock<std::mutex> port_lock(cv_mutex_);
  173. BluetoothStreamState previous_state = state_;
  174. LOG(INFO) << "control_result_cb: session_type=" << toString(session_type_)
  175. << ", cookie=" << StringPrintf("%#hx", cookie_) << ", previous_state=" << previous_state
  176. << ", status=" << toString(status);
  177. switch (previous_state) {
  178. case BluetoothStreamState::STARTING:
  179. if (status == BluetoothAudioStatus::SUCCESS) {
  180. state_ = BluetoothStreamState::STARTED;
  181. } else {
  182. // Set to standby since the stack may be busy switching between outputs
  183. LOG(WARNING) << "control_result_cb: status=" << toString(status)
  184. << " failure for session_type=" << toString(session_type_)
  185. << ", cookie=" << StringPrintf("%#hx", cookie_) << ", previous_state=" << previous_state;
  186. state_ = BluetoothStreamState::STANDBY;
  187. }
  188. break;
  189. case BluetoothStreamState::SUSPENDING:
  190. if (status == BluetoothAudioStatus::SUCCESS) {
  191. state_ = BluetoothStreamState::STANDBY;
  192. } else {
  193. // It will be failed if the headset is disconnecting, and set to disable
  194. // to wait for re-init again
  195. LOG(WARNING) << "control_result_cb: status=" << toString(status)
  196. << " failure for session_type=" << toString(session_type_)
  197. << ", cookie=" << StringPrintf("%#hx", cookie_) << ", previous_state=" << previous_state;
  198. state_ = BluetoothStreamState::DISABLED;
  199. }
  200. break;
  201. default:
  202. LOG(ERROR) << "control_result_cb: unexpected status=" << toString(status)
  203. << " for session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
  204. << ", previous_state=" << previous_state;
  205. return;
  206. }
  207. port_lock.unlock();
  208. internal_cv_.notify_all();
  209. }
  210. void BluetoothAudioPortOut::SessionChangedHandler() {
  211. if (!in_use()) {
  212. LOG(ERROR) << __func__ << ": BluetoothAudioPortOut is not in use";
  213. return;
  214. }
  215. std::unique_lock<std::mutex> port_lock(cv_mutex_);
  216. BluetoothStreamState previous_state = state_;
  217. LOG(INFO) << "session_changed_cb: session_type=" << toString(session_type_)
  218. << ", cookie=" << StringPrintf("%#hx", cookie_) << ", previous_state=" << previous_state;
  219. if (previous_state != BluetoothStreamState::DISABLED) {
  220. state_ = BluetoothStreamState::DISABLED;
  221. } else {
  222. state_ = BluetoothStreamState::STANDBY;
  223. }
  224. port_lock.unlock();
  225. internal_cv_.notify_all();
  226. }
  227. bool BluetoothAudioPortOut::in_use() const {
  228. return (cookie_ != android::bluetooth::audio::kObserversCookieUndefined);
  229. }
  230. bool BluetoothAudioPortOut::LoadAudioConfig(audio_config_t* audio_cfg) const {
  231. if (!in_use()) {
  232. LOG(ERROR) << __func__ << ": BluetoothAudioPortOut is not in use";
  233. audio_cfg->sample_rate = kBluetoothDefaultSampleRate;
  234. audio_cfg->channel_mask = kBluetoothDefaultOutputChannelModeMask;
  235. audio_cfg->format = kBluetoothDefaultAudioFormatBitsPerSample;
  236. return false;
  237. }
  238. const AudioConfiguration& hal_audio_cfg =
  239. BluetoothAudioSessionControl::GetAudioConfig(session_type_);
  240. if (hal_audio_cfg.getDiscriminator() !=
  241. AudioConfiguration::hidl_discriminator::pcmConfig) {
  242. audio_cfg->sample_rate = kBluetoothDefaultSampleRate;
  243. audio_cfg->channel_mask = kBluetoothDefaultOutputChannelModeMask;
  244. audio_cfg->format = kBluetoothDefaultAudioFormatBitsPerSample;
  245. return false;
  246. }
  247. const PcmParameters& pcm_cfg = hal_audio_cfg.pcmConfig();
  248. LOG(VERBOSE) << __func__ << ": session_type=" << toString(session_type_)
  249. << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << ", PcmConfig=["
  250. << toString(pcm_cfg) << "]";
  251. if (pcm_cfg.sampleRate == SampleRate::RATE_UNKNOWN ||
  252. pcm_cfg.channelMode == ChannelMode::UNKNOWN ||
  253. pcm_cfg.bitsPerSample == BitsPerSample::BITS_UNKNOWN) {
  254. return false;
  255. }
  256. audio_cfg->sample_rate = SampleRateToAudioFormat(pcm_cfg.sampleRate);
  257. audio_cfg->channel_mask =
  258. (is_stereo_to_mono_ ? AUDIO_CHANNEL_OUT_STEREO : ChannelModeToAudioFormat(pcm_cfg.channelMode));
  259. audio_cfg->format = BitsPerSampleToAudioFormat(pcm_cfg.bitsPerSample);
  260. return true;
  261. }
  262. bool BluetoothAudioPortOut::CondwaitState(BluetoothStreamState state) {
  263. bool retval;
  264. std::unique_lock<std::mutex> port_lock(cv_mutex_);
  265. switch (state) {
  266. case BluetoothStreamState::STARTING:
  267. LOG(VERBOSE) << __func__ << ": session_type=" << toString(session_type_)
  268. << ", cookie=" << StringPrintf("%#hx", cookie_) << " waiting for STARTED";
  269. retval = internal_cv_.wait_for(
  270. port_lock, std::chrono::milliseconds(kMaxWaitingTimeMs),
  271. [this] { return this->state_ != BluetoothStreamState::STARTING; });
  272. retval = retval && state_ == BluetoothStreamState::STARTED;
  273. break;
  274. case BluetoothStreamState::SUSPENDING:
  275. LOG(VERBOSE) << __func__ << ": session_type=" << toString(session_type_)
  276. << ", cookie=" << StringPrintf("%#hx", cookie_) << " waiting for SUSPENDED";
  277. retval = internal_cv_.wait_for(
  278. port_lock, std::chrono::milliseconds(kMaxWaitingTimeMs),
  279. [this] { return this->state_ != BluetoothStreamState::SUSPENDING; });
  280. retval = retval && state_ == BluetoothStreamState::STANDBY;
  281. break;
  282. default:
  283. LOG(WARNING) << __func__ << ": session_type=" << toString(session_type_)
  284. << ", cookie=" << StringPrintf("%#hx", cookie_) << " waiting for KNOWN";
  285. return false;
  286. }
  287. return retval; // false if any failure like timeout
  288. }
  289. bool BluetoothAudioPortOut::Start() {
  290. if (!in_use()) {
  291. LOG(ERROR) << __func__ << ": BluetoothAudioPortOut is not in use";
  292. return false;
  293. }
  294. LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
  295. << ", state=" << state_ << ", mono=" << (is_stereo_to_mono_ ? "true" : "false") << " request";
  296. bool retval = false;
  297. if (state_ == BluetoothStreamState::STANDBY) {
  298. state_ = BluetoothStreamState::STARTING;
  299. if (BluetoothAudioSessionControl::StartStream(session_type_)) {
  300. retval = CondwaitState(BluetoothStreamState::STARTING);
  301. } else {
  302. LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
  303. << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << " Hal fails";
  304. }
  305. }
  306. if (retval) {
  307. LOG(INFO) << __func__ << ": session_type=" << toString(session_type_)
  308. << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_
  309. << ", mono=" << (is_stereo_to_mono_ ? "true" : "false") << " done";
  310. } else {
  311. LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
  312. << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << " failure";
  313. }
  314. return retval; // false if any failure like timeout
  315. }
  316. bool BluetoothAudioPortOut::Suspend() {
  317. if (!in_use()) {
  318. LOG(ERROR) << __func__ << ": BluetoothAudioPortOut is not in use";
  319. return false;
  320. }
  321. LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
  322. << ", state=" << state_ << " request";
  323. bool retval = false;
  324. if (state_ == BluetoothStreamState::STARTED) {
  325. state_ = BluetoothStreamState::SUSPENDING;
  326. if (BluetoothAudioSessionControl::SuspendStream(session_type_)) {
  327. retval = CondwaitState(BluetoothStreamState::SUSPENDING);
  328. } else {
  329. LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
  330. << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << " Hal fails";
  331. }
  332. }
  333. if (retval) {
  334. LOG(INFO) << __func__ << ": session_type=" << toString(session_type_)
  335. << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << " done";
  336. } else {
  337. LOG(ERROR) << __func__ << ": session_type=" << toString(session_type_)
  338. << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << " failure";
  339. }
  340. return retval; // false if any failure like timeout
  341. }
  342. void BluetoothAudioPortOut::Stop() {
  343. if (!in_use()) {
  344. LOG(ERROR) << __func__ << ": BluetoothAudioPortOut is not in use";
  345. return;
  346. }
  347. LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
  348. << ", state=" << state_ << " request";
  349. state_ = BluetoothStreamState::DISABLED;
  350. BluetoothAudioSessionControl::StopStream(session_type_);
  351. LOG(INFO) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
  352. << ", state=" << state_ << " done";
  353. }
  354. size_t BluetoothAudioPortOut::WriteData(const void* buffer, size_t bytes) const {
  355. if (!in_use()) return 0;
  356. if (!is_stereo_to_mono_) {
  357. return BluetoothAudioSessionControl::OutWritePcmData(session_type_, buffer, bytes);
  358. }
  359. // WAR to mix the stereo into Mono (16 bits per sample)
  360. const size_t write_frames = bytes >> 2;
  361. if (write_frames == 0) return 0;
  362. auto src = static_cast<const int16_t*>(buffer);
  363. std::unique_ptr<int16_t[]> dst{new int16_t[write_frames]};
  364. downmix_to_mono_i16_from_stereo_i16(dst.get(), src, write_frames);
  365. // a frame is 16 bits, and the size of a mono frame is equal to half a stereo.
  366. return BluetoothAudioSessionControl::OutWritePcmData(session_type_, dst.get(), write_frames * 2) * 2;
  367. }
  368. bool BluetoothAudioPortOut::GetPresentationPosition(uint64_t* delay_ns,
  369. uint64_t* bytes,
  370. timespec* timestamp) const {
  371. if (!in_use()) {
  372. LOG(ERROR) << __func__ << ": BluetoothAudioPortOut is not in use";
  373. return false;
  374. }
  375. bool retval = BluetoothAudioSessionControl::GetPresentationPosition(
  376. session_type_, delay_ns, bytes, timestamp);
  377. LOG(VERBOSE) << __func__ << ": session_type=" << StringPrintf("%#hhx", session_type_)
  378. << ", cookie=" << StringPrintf("%#hx", cookie_) << ", state=" << state_ << ", delay=" << *delay_ns
  379. << "ns, data=" << *bytes << " bytes, timestamp=" << timestamp->tv_sec << "."
  380. << StringPrintf("%09ld", timestamp->tv_nsec) << "s";
  381. return retval;
  382. }
  383. void BluetoothAudioPortOut::UpdateMetadata(
  384. const source_metadata* source_metadata) const {
  385. if (!in_use()) {
  386. LOG(ERROR) << __func__ << ": BluetoothAudioPortOut is not in use";
  387. return;
  388. }
  389. LOG(DEBUG) << __func__ << ": session_type=" << toString(session_type_) << ", cookie=" << StringPrintf("%#hx", cookie_)
  390. << ", state=" << state_ << ", " << source_metadata->track_count << " track(s)";
  391. if (source_metadata->track_count == 0) return;
  392. BluetoothAudioSessionControl::UpdateTracksMetadata(session_type_,
  393. source_metadata);
  394. }
  395. BluetoothStreamState BluetoothAudioPortOut::GetState() const { return state_; }
  396. void BluetoothAudioPortOut::SetState(BluetoothStreamState state) {
  397. state_ = state;
  398. }
  399. } // namespace audio
  400. } // namespace bluetooth
  401. } // namespace android