1 /*
2 * Copyright (C) 2021 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 #include <thread>
18
19 //#define LOG_NDEBUG 0
20 #define LOG_TAG "AudioTestUtils"
21
22 #include <android-base/file.h>
23 #include <android/content/pm/IPackageManagerNative.h>
24 #include <binder/IServiceManager.h>
25 #include <system/audio_config.h>
26 #include <utils/Log.h>
27 #include <utils/SystemClock.h>
28
29 #include "audio_test_utils.h"
30
31 #define WAIT_PERIOD_MS 10 // from AudioTrack.cpp
32 #define MAX_WAIT_TIME_MS 5000
33
34 static constexpr auto kShortCallbackTimeout = std::chrono::milliseconds(500);
35 static constexpr auto kLongCallbackTimeout = std::chrono::seconds(10);
36
onAudioDeviceUpdate(audio_io_handle_t audioIo,const DeviceIdVector & deviceIds)37 void OnAudioDeviceUpdateNotifier::onAudioDeviceUpdate(audio_io_handle_t audioIo,
38 const DeviceIdVector& deviceIds) {
39 ALOGI("%s: audioIo=%d deviceIds=%s", __func__, audioIo, toString(deviceIds).c_str());
40 {
41 std::lock_guard lock(mMutex);
42 mAudioIo = audioIo;
43 mDeviceIds = deviceIds;
44 }
45 mCondition.notify_all();
46 }
47
waitForAudioDeviceCb(audio_port_handle_t expDeviceId)48 status_t OnAudioDeviceUpdateNotifier::waitForAudioDeviceCb(audio_port_handle_t expDeviceId) {
49 std::unique_lock lock(mMutex);
50 base::ScopedLockAssertion lock_assertion(mMutex);
51 if (mAudioIo == AUDIO_IO_HANDLE_NONE ||
52 (expDeviceId != AUDIO_PORT_HANDLE_NONE &&
53 std::find(mDeviceIds.begin(), mDeviceIds.end(), expDeviceId) == mDeviceIds.end())) {
54 mCondition.wait_for(lock, std::chrono::milliseconds(500));
55 if (mAudioIo == AUDIO_IO_HANDLE_NONE ||
56 (expDeviceId != AUDIO_PORT_HANDLE_NONE &&
57 std::find(mDeviceIds.begin(), mDeviceIds.end(), expDeviceId) == mDeviceIds.end())) {
58 return TIMED_OUT;
59 }
60 }
61 return OK;
62 }
63
getLastPortAndDevices() const64 std::pair<audio_io_handle_t, DeviceIdVector> OnAudioDeviceUpdateNotifier::getLastPortAndDevices()
65 const {
66 std::lock_guard lock(mMutex);
67 ALOGI("%s: audioIo=%d deviceIds=%s", __func__, mAudioIo, toString(mDeviceIds).c_str());
68 return {mAudioIo, mDeviceIds};
69 }
70
AudioPlayback(uint32_t sampleRate,audio_format_t format,audio_channel_mask_t channelMask,audio_output_flags_t flags,audio_session_t sessionId,AudioTrack::transfer_type transferType,audio_attributes_t * attributes,audio_offload_info_t * info)71 AudioPlayback::AudioPlayback(uint32_t sampleRate, audio_format_t format,
72 audio_channel_mask_t channelMask, audio_output_flags_t flags,
73 audio_session_t sessionId, AudioTrack::transfer_type transferType,
74 audio_attributes_t* attributes, audio_offload_info_t* info)
75 : mSampleRate(sampleRate),
76 mFormat(format),
77 mChannelMask(channelMask),
78 mFlags(flags),
79 mSessionId(sessionId),
80 mTransferType(transferType),
81 mAttributes(attributes),
82 mOffloadInfo(info) {}
83
~AudioPlayback()84 AudioPlayback::~AudioPlayback() {
85 stop();
86 }
87
create()88 status_t AudioPlayback::create() {
89 if (mState != PLAY_NO_INIT) return INVALID_OPERATION;
90 std::string packageName{"AudioPlayback"};
91 AttributionSourceState attributionSource;
92 attributionSource.packageName = packageName;
93 attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(getuid()));
94 attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(getpid()));
95 attributionSource.token = sp<BBinder>::make();
96 if (mTransferType == AudioTrack::TRANSFER_OBTAIN) {
97 mTrack = sp<TestAudioTrack>::make(attributionSource);
98 mTrack->set(AUDIO_STREAM_MUSIC, mSampleRate, mFormat, mChannelMask, 0 /* frameCount */,
99 mFlags, wp<AudioTrack::IAudioTrackCallback>::fromExisting(this),
100 0 /* notificationFrames */, nullptr /* sharedBuffer */, false /*canCallJava */,
101 mSessionId, mTransferType, mOffloadInfo, attributionSource, mAttributes);
102 } else if (mTransferType == AudioTrack::TRANSFER_SHARED) {
103 mTrack = sp<TestAudioTrack>::make(
104 AUDIO_STREAM_MUSIC, mSampleRate, mFormat, mChannelMask, mMemory, mFlags,
105 wp<AudioTrack::IAudioTrackCallback>::fromExisting(this), 0, mSessionId,
106 mTransferType, nullptr, attributionSource, mAttributes);
107 } else {
108 ALOGE("Test application is not handling transfer type %s",
109 AudioTrack::convertTransferToText(mTransferType));
110 return INVALID_OPERATION;
111 }
112 mTrack->setCallerName(packageName);
113 status_t status = mTrack->initCheck();
114 if (NO_ERROR == status) mState = PLAY_READY;
115 return status;
116 }
117
loadResource(const char * name)118 status_t AudioPlayback::loadResource(const char* name) {
119 status_t status = OK;
120 FILE* fp = fopen(name, "rbe");
121 struct stat buf {};
122 if (fp && !fstat(fileno(fp), &buf)) {
123 mMemCapacity = buf.st_size;
124 mMemoryDealer = new MemoryDealer(mMemCapacity, "AudioPlayback");
125 if (nullptr == mMemoryDealer.get()) {
126 ALOGE("couldn't get MemoryDealer!");
127 fclose(fp);
128 return NO_MEMORY;
129 }
130 mMemory = mMemoryDealer->allocate(mMemCapacity);
131 if (nullptr == mMemory.get()) {
132 ALOGE("couldn't get IMemory!");
133 fclose(fp);
134 return NO_MEMORY;
135 }
136 uint8_t* ipBuffer = static_cast<uint8_t*>(static_cast<void*>(mMemory->unsecurePointer()));
137 fread(ipBuffer, sizeof(uint8_t), mMemCapacity, fp);
138 } else {
139 ALOGE("unable to open input file %s", name);
140 status = NAME_NOT_FOUND;
141 }
142 if (fp) fclose(fp);
143 return status;
144 }
145
getAudioTrackHandle()146 sp<AudioTrack> AudioPlayback::getAudioTrackHandle() {
147 return (PLAY_NO_INIT != mState) ? mTrack : nullptr;
148 }
149
start()150 status_t AudioPlayback::start() {
151 status_t status;
152 if (PLAY_READY != mState) {
153 return INVALID_OPERATION;
154 } else {
155 status = mTrack->start();
156 if (OK == status) {
157 mState = PLAY_STARTED;
158 LOG_FATAL_IF(false != mTrack->stopped());
159 std::lock_guard l(mMutex);
160 mStreamEndReceived = false;
161 }
162 }
163 return status;
164 }
165
onBufferEnd()166 void AudioPlayback::onBufferEnd() {
167 std::lock_guard lock(mMutex);
168 mStopPlaying = true;
169 }
170
onStreamEnd()171 void AudioPlayback::onStreamEnd() {
172 ALOGD("%s", __func__);
173 {
174 std::lock_guard lock(mMutex);
175 mStreamEndReceived = true;
176 }
177 mCondition.notify_all();
178 }
179
fillBuffer()180 status_t AudioPlayback::fillBuffer() {
181 if (PLAY_STARTED != mState) return INVALID_OPERATION;
182 const int maxTries = MAX_WAIT_TIME_MS / WAIT_PERIOD_MS;
183 int counter = 0;
184 uint8_t* ipBuffer = static_cast<uint8_t*>(static_cast<void*>(mMemory->unsecurePointer()));
185 size_t nonContig = 0;
186 size_t bytesAvailable = mMemCapacity - mBytesUsedSoFar;
187 while (bytesAvailable > 0) {
188 AudioTrack::Buffer trackBuffer;
189 trackBuffer.frameCount = mTrack->frameCount() * 2;
190 status_t status = mTrack->obtainBuffer(&trackBuffer, 1, &nonContig);
191 if (OK == status) {
192 size_t bytesToCopy = std::min(bytesAvailable, trackBuffer.size());
193 if (bytesToCopy > 0) {
194 memcpy(trackBuffer.data(), ipBuffer + mBytesUsedSoFar, bytesToCopy);
195 }
196 mTrack->releaseBuffer(&trackBuffer);
197 mBytesUsedSoFar += bytesToCopy;
198 bytesAvailable = mMemCapacity - mBytesUsedSoFar;
199 counter = 0;
200 } else if (WOULD_BLOCK == status) {
201 // if not received a buffer for MAX_WAIT_TIME_MS, something has gone wrong
202 if (counter == maxTries) return TIMED_OUT;
203 counter++;
204 }
205 }
206 mBytesUsedSoFar = 0;
207 return OK;
208 }
209
waitForConsumption(bool testSeek)210 status_t AudioPlayback::waitForConsumption(bool testSeek) {
211 if (PLAY_STARTED != mState) return INVALID_OPERATION;
212
213 const int maxTries = MAX_WAIT_TIME_MS / WAIT_PERIOD_MS;
214 int counter = 0;
215 size_t totalFrameCount = mMemCapacity / mTrack->frameSize();
216 bool stopPlaying;
217 {
218 std::lock_guard lock(mMutex);
219 stopPlaying = mStopPlaying;
220 }
221 while (!stopPlaying && counter < maxTries) {
222 uint32_t currPosition;
223 mTrack->getPosition(&currPosition);
224 if (currPosition >= totalFrameCount) counter++;
225
226 if (testSeek && (currPosition > totalFrameCount * 0.6)) {
227 testSeek = false;
228 if (!mTrack->hasStarted()) return BAD_VALUE;
229 mTrack->pauseAndWait(std::chrono::seconds(2));
230 if (mTrack->hasStarted()) return BAD_VALUE;
231 mTrack->reload();
232 mTrack->getPosition(&currPosition);
233 if (currPosition != 0) return BAD_VALUE;
234 mTrack->start();
235 while (currPosition < totalFrameCount * 0.3) {
236 mTrack->getPosition(&currPosition);
237 }
238 mTrack->pauseAndWait(std::chrono::seconds(2));
239 uint32_t setPosition = totalFrameCount * 0.9;
240 mTrack->setPosition(setPosition);
241 uint32_t bufferPosition;
242 mTrack->getBufferPosition(&bufferPosition);
243 if (bufferPosition != setPosition) return BAD_VALUE;
244 mTrack->start();
245 }
246 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_PERIOD_MS));
247 std::lock_guard lock(mMutex);
248 stopPlaying = mStopPlaying;
249 }
250 std::lock_guard lock(mMutex);
251 if (!mStopPlaying && counter == maxTries) return TIMED_OUT;
252 return OK;
253 }
254
onProcess(bool testSeek)255 status_t AudioPlayback::onProcess(bool testSeek) {
256 if (mTransferType == AudioTrack::TRANSFER_SHARED)
257 return waitForConsumption(testSeek);
258 else if (mTransferType == AudioTrack::TRANSFER_OBTAIN)
259 return fillBuffer();
260 else
261 return INVALID_OPERATION;
262 }
263
pause()264 void AudioPlayback::pause() {
265 mTrack->pause();
266 }
267
resume()268 void AudioPlayback::resume() {
269 mTrack->start();
270 }
271
stop()272 void AudioPlayback::stop() {
273 {
274 std::lock_guard lock(mMutex);
275 mStopPlaying = true;
276 }
277 if (mState != PLAY_STOPPED && mState != PLAY_NO_INIT) {
278 int32_t msec = 0;
279 (void)mTrack->pendingDuration(&msec);
280 mTrack->stop(); // Do not join the callback thread, drain may be ongoing.
281 LOG_FATAL_IF(true != mTrack->stopped());
282 mState = PLAY_STOPPED;
283 if (msec > 0) {
284 ALOGD("deleting recycled track, waiting for data drain (%d msec)", msec);
285 usleep(msec * 1000LL);
286 }
287 }
288 }
289
waitForStreamEnd()290 bool AudioPlayback::waitForStreamEnd() {
291 ALOGD("%s", __func__);
292 const int64_t endMs = uptimeMillis() + std::chrono::milliseconds(kLongCallbackTimeout).count();
293 while (uptimeMillis() < endMs) {
294 // Wake up the AudioPlaybackThread to get notifications.
295 mTrack->wakeCallbackThread();
296 std::unique_lock lock(mMutex);
297 base::ScopedLockAssertion lock_assertion(mMutex);
298 mCondition.wait_for(lock, kShortCallbackTimeout, [this]() {
299 base::ScopedLockAssertion lock_assertion(mMutex);
300 return mStreamEndReceived;
301 });
302 if (mStreamEndReceived) return true;
303 }
304 return false;
305 }
306
307 // hold pcm data sent by AudioRecord
RawBuffer(int64_t ptsPipeline,int64_t ptsManual,int32_t capacity)308 RawBuffer::RawBuffer(int64_t ptsPipeline, int64_t ptsManual, int32_t capacity)
309 : mData(capacity > 0 ? new uint8_t[capacity] : nullptr),
310 mPtsPipeline(ptsPipeline),
311 mPtsManual(ptsManual),
312 mCapacity(capacity) {}
313
314 // Simple AudioCapture
onMoreData(const AudioRecord::Buffer & buffer)315 size_t AudioCapture::onMoreData(const AudioRecord::Buffer& buffer) {
316 if (mState != REC_STARTED) {
317 ALOGE("Unexpected Callback from audiorecord, not reading data");
318 return 0;
319 }
320
321 {
322 std::lock_guard l(mMutex);
323 // no more frames to read
324 if (mNumFramesReceived >= mNumFramesToRecord || mStopRecording) {
325 mStopRecording = true;
326 return 0;
327 }
328 }
329
330 int64_t timeUs = 0, position = 0, timeNs = 0;
331 ExtendedTimestamp ts;
332 ExtendedTimestamp::Location location;
333 const int32_t usPerSec = 1000000;
334
335 if (mRecord->getTimestamp(&ts) == OK &&
336 ts.getBestTimestamp(&position, &timeNs, ExtendedTimestamp::TIMEBASE_MONOTONIC, &location) ==
337 OK) {
338 // Use audio timestamp.
339 std::lock_guard l(mMutex);
340 timeUs = timeNs / 1000 -
341 (position - mNumFramesReceived + mNumFramesLost) * usPerSec / mSampleRate;
342 } else {
343 // This should not happen in normal case.
344 ALOGW("Failed to get audio timestamp, fallback to use systemclock");
345 timeUs = systemTime() / 1000LL;
346 // Estimate the real sampling time of the 1st sample in this buffer
347 // from AudioRecord's latency. (Apply this adjustment first so that
348 // the start time logic is not affected.)
349 timeUs -= mRecord->latency() * 1000LL;
350 }
351
352 ALOGV("dataCallbackTimestamp: %" PRId64 " us", timeUs);
353
354 const size_t frameSize = mRecord->frameSize();
355 uint64_t numLostBytes = (uint64_t)mRecord->getInputFramesLost() * frameSize;
356 if (numLostBytes > 0) {
357 ALOGW("Lost audio record data: %" PRIu64 " bytes", numLostBytes);
358 }
359 std::deque<RawBuffer> tmpQueue;
360 while (numLostBytes > 0) {
361 uint64_t bufferSize = numLostBytes;
362 if (numLostBytes > mMaxBytesPerCallback) {
363 numLostBytes -= mMaxBytesPerCallback;
364 bufferSize = mMaxBytesPerCallback;
365 } else {
366 numLostBytes = 0;
367 }
368 std::lock_guard l(mMutex);
369 const int64_t timestampUs =
370 ((1000000LL * mNumFramesReceived) + (mRecord->getSampleRate() >> 1)) /
371 mRecord->getSampleRate();
372 RawBuffer emptyBuffer{timeUs, timestampUs, static_cast<int32_t>(bufferSize)};
373 memset(emptyBuffer.mData.get(), 0, bufferSize);
374 mNumFramesLost += bufferSize / frameSize;
375 mNumFramesReceived += bufferSize / frameSize;
376 tmpQueue.push_back(std::move(emptyBuffer));
377 }
378
379 if (buffer.size() == 0) {
380 ALOGW("Nothing is available from AudioRecord callback buffer");
381 } else {
382 std::lock_guard l(mMutex);
383 const size_t bufferSize = buffer.size();
384 const int64_t timestampUs =
385 ((1000000LL * mNumFramesReceived) + (mRecord->getSampleRate() >> 1)) /
386 mRecord->getSampleRate();
387 RawBuffer audioBuffer{timeUs, timestampUs, static_cast<int32_t>(bufferSize)};
388 memcpy(audioBuffer.mData.get(), buffer.data(), bufferSize);
389 mNumFramesReceived += bufferSize / frameSize;
390 tmpQueue.push_back(std::move(audioBuffer));
391 }
392
393 if (tmpQueue.size() > 0) {
394 {
395 std::lock_guard lock(mMutex);
396 mBuffersReceived.insert(mBuffersReceived.end(),
397 std::make_move_iterator(tmpQueue.begin()),
398 std::make_move_iterator(tmpQueue.end()));
399 }
400 mCondition.notify_all();
401 }
402 return buffer.size();
403 }
404
onOverrun()405 void AudioCapture::onOverrun() {
406 ALOGV("received event overrun");
407 }
408
onMarker(uint32_t markerPosition)409 void AudioCapture::onMarker(uint32_t markerPosition) {
410 ALOGV("received Callback at position %d", markerPosition);
411 {
412 std::lock_guard l(mMutex);
413 mReceivedCbMarkerAtPosition = markerPosition;
414 }
415 mMarkerCondition.notify_all();
416 }
417
onNewPos(uint32_t markerPosition)418 void AudioCapture::onNewPos(uint32_t markerPosition) {
419 ALOGV("received Callback at position %d", markerPosition);
420 {
421 std::lock_guard l(mMutex);
422 mReceivedCbMarkerCount = mReceivedCbMarkerCount.value_or(0) + 1;
423 }
424 mMarkerCondition.notify_all();
425 }
426
onNewIAudioRecord()427 void AudioCapture::onNewIAudioRecord() {
428 ALOGV("IAudioRecord is re-created");
429 }
430
AudioCapture(audio_source_t inputSource,uint32_t sampleRate,audio_format_t format,audio_channel_mask_t channelMask,audio_input_flags_t flags,audio_session_t sessionId,AudioRecord::transfer_type transferType,const audio_attributes_t * attributes)431 AudioCapture::AudioCapture(audio_source_t inputSource, uint32_t sampleRate, audio_format_t format,
432 audio_channel_mask_t channelMask, audio_input_flags_t flags,
433 audio_session_t sessionId, AudioRecord::transfer_type transferType,
434 const audio_attributes_t* attributes)
435 : mInputSource(inputSource),
436 mSampleRate(sampleRate),
437 mFormat(format),
438 mChannelMask(channelMask),
439 mFlags(flags),
440 mSessionId(sessionId),
441 mTransferType(transferType),
442 mAttributes(attributes) {}
443
~AudioCapture()444 AudioCapture::~AudioCapture() {
445 if (mOutFileFd > 0) close(mOutFileFd);
446 stop();
447 }
448
create()449 status_t AudioCapture::create() {
450 if (mState != REC_NO_INIT) return INVALID_OPERATION;
451 // get Min Frame Count
452 size_t minFrameCount;
453 status_t status =
454 AudioRecord::getMinFrameCount(&minFrameCount, mSampleRate, mFormat, mChannelMask);
455 if (NO_ERROR != status) return status;
456 // Limit notificationFrames basing on client bufferSize
457 const int samplesPerFrame = audio_channel_count_from_in_mask(mChannelMask);
458 const int bytesPerSample = audio_bytes_per_sample(mFormat);
459 mNotificationFrames = mMaxBytesPerCallback / (samplesPerFrame * bytesPerSample);
460 // select frameCount to be at least minFrameCount
461 mFrameCount = 2 * mNotificationFrames;
462 while (mFrameCount < minFrameCount) {
463 mFrameCount += mNotificationFrames;
464 }
465 if (mFlags & AUDIO_INPUT_FLAG_FAST) {
466 ALOGW("Overriding all previous computations");
467 mFrameCount = 0;
468 mNotificationFrames = 0;
469 }
470 mNumFramesToRecord = (mSampleRate * 0.25); // record .25 sec
471 std::string packageName{"AudioCapture"};
472 AttributionSourceState attributionSource;
473 attributionSource.packageName = packageName;
474 attributionSource.uid = VALUE_OR_FATAL(legacy2aidl_uid_t_int32_t(getuid()));
475 attributionSource.pid = VALUE_OR_FATAL(legacy2aidl_pid_t_int32_t(getpid()));
476 attributionSource.token = sp<BBinder>::make();
477 if (mTransferType == AudioRecord::TRANSFER_OBTAIN) {
478 if (mSampleRate == 48000) { // test all available constructors
479 mRecord = new AudioRecord(mInputSource, mSampleRate, mFormat, mChannelMask,
480 attributionSource, mFrameCount, nullptr /* callback */,
481 mNotificationFrames, mSessionId, mTransferType, mFlags,
482 mAttributes);
483 } else {
484 mRecord = new AudioRecord(attributionSource);
485 status = mRecord->set(mInputSource, mSampleRate, mFormat, mChannelMask, mFrameCount,
486 nullptr /* callback */, 0 /* notificationFrames */,
487 false /* canCallJava */, mSessionId, mTransferType, mFlags,
488 attributionSource.uid, attributionSource.pid, mAttributes);
489 }
490 if (NO_ERROR != status) return status;
491 } else if (mTransferType == AudioRecord::TRANSFER_CALLBACK) {
492 mRecord = new AudioRecord(mInputSource, mSampleRate, mFormat, mChannelMask,
493 attributionSource, mFrameCount, this, mNotificationFrames,
494 mSessionId, mTransferType, mFlags, mAttributes);
495 } else {
496 ALOGE("Test application is not handling transfer type %s",
497 AudioRecord::convertTransferToText(mTransferType));
498 return NO_INIT;
499 }
500 mRecord->setCallerName(packageName);
501 status = mRecord->initCheck();
502 if (NO_ERROR == status) mState = REC_READY;
503 if (mFlags & AUDIO_INPUT_FLAG_FAST) {
504 mFrameCount = mRecord->frameCount();
505 mNotificationFrames = mRecord->getNotificationPeriodInFrames();
506 mMaxBytesPerCallback = mNotificationFrames * samplesPerFrame * bytesPerSample;
507 }
508 return status;
509 }
510
setRecordDuration(float durationInSec)511 status_t AudioCapture::setRecordDuration(float durationInSec) {
512 if (REC_READY != mState) {
513 return INVALID_OPERATION;
514 }
515 uint32_t sampleRate = mSampleRate == 0 ? mRecord->getSampleRate() : mSampleRate;
516 mNumFramesToRecord = (sampleRate * durationInSec);
517 return OK;
518 }
519
enableRecordDump()520 status_t AudioCapture::enableRecordDump() {
521 if (mOutFileFd != -1) {
522 return INVALID_OPERATION;
523 }
524 TemporaryFile tf("/data/local/tmp");
525 tf.DoNotRemove();
526 mOutFileFd = tf.release();
527 mFileName = std::string{tf.path};
528 return OK;
529 }
530
getAudioRecordHandle()531 sp<AudioRecord> AudioCapture::getAudioRecordHandle() {
532 return (REC_NO_INIT == mState) ? nullptr : mRecord;
533 }
534
start(AudioSystem::sync_event_t event,audio_session_t triggerSession)535 status_t AudioCapture::start(AudioSystem::sync_event_t event, audio_session_t triggerSession) {
536 status_t status;
537 if (REC_READY != mState) {
538 return INVALID_OPERATION;
539 } else {
540 status = mRecord->start(event, triggerSession);
541 if (OK == status) {
542 mState = REC_STARTED;
543 LOG_FATAL_IF(false != mRecord->stopped());
544 }
545 }
546 return status;
547 }
548
stop()549 status_t AudioCapture::stop() {
550 status_t status = OK;
551 {
552 std::lock_guard l(mMutex);
553 mStopRecording = true;
554 }
555 if (mState != REC_STOPPED && mState != REC_NO_INIT) {
556 if (mInputSource != AUDIO_SOURCE_DEFAULT) {
557 bool state = false;
558 status = AudioSystem::isSourceActive(mInputSource, &state);
559 if (status == OK && !state) status = BAD_VALUE;
560 }
561 mRecord->stopAndJoinCallbacks();
562 mState = REC_STOPPED;
563 LOG_FATAL_IF(true != mRecord->stopped());
564 }
565 return status;
566 }
567
obtainBuffer(RawBuffer & buffer)568 status_t AudioCapture::obtainBuffer(RawBuffer& buffer) {
569 if (REC_STARTED != mState) return INVALID_OPERATION;
570 const int maxTries = MAX_WAIT_TIME_MS / WAIT_PERIOD_MS;
571 int counter = 0;
572 size_t nonContig = 0;
573 int64_t numFramesReceived;
574 {
575 std::lock_guard l(mMutex);
576 numFramesReceived = mNumFramesReceived;
577 }
578 while (numFramesReceived < mNumFramesToRecord) {
579 AudioRecord::Buffer recordBuffer;
580 recordBuffer.frameCount = mNotificationFrames;
581 status_t status = mRecord->obtainBuffer(&recordBuffer, 1, &nonContig);
582 if (OK == status) {
583 const int64_t timestampUs =
584 ((1000000LL * numFramesReceived) + (mRecord->getSampleRate() >> 1)) /
585 mRecord->getSampleRate();
586 RawBuffer buff{-1, timestampUs, static_cast<int32_t>(recordBuffer.size())};
587 memcpy(buff.mData.get(), recordBuffer.data(), recordBuffer.size());
588 buffer = std::move(buff);
589 numFramesReceived += recordBuffer.size() / mRecord->frameSize();
590 mRecord->releaseBuffer(&recordBuffer);
591 counter = 0;
592 } else if (WOULD_BLOCK == status) {
593 // if not received a buffer for MAX_WAIT_TIME_MS, something has gone wrong
594 if (counter++ == maxTries) status = TIMED_OUT;
595 }
596 std::lock_guard l(mMutex);
597 mNumFramesReceived = numFramesReceived;
598 if (TIMED_OUT == status) return status;
599 }
600 return OK;
601 }
602
obtainBufferCb(RawBuffer & buffer)603 status_t AudioCapture::obtainBufferCb(RawBuffer& buffer) {
604 if (REC_STARTED != mState) return INVALID_OPERATION;
605 const int maxTries = MAX_WAIT_TIME_MS / WAIT_PERIOD_MS;
606 int counter = 0;
607 std::unique_lock lock(mMutex);
608 base::ScopedLockAssertion lock_assertion(mMutex);
609 while (mBuffersReceived.empty() && !mStopRecording && counter < maxTries) {
610 mCondition.wait_for(lock, std::chrono::milliseconds(WAIT_PERIOD_MS));
611 counter++;
612 }
613 if (!mBuffersReceived.empty()) {
614 auto it = mBuffersReceived.begin();
615 buffer = std::move(*it);
616 mBuffersReceived.erase(it);
617 } else {
618 if (!mStopRecording && counter == maxTries) return TIMED_OUT;
619 }
620 return OK;
621 }
622
audioProcess()623 status_t AudioCapture::audioProcess() {
624 RawBuffer buffer;
625 status_t status = OK;
626 int64_t numFramesReceived;
627 {
628 std::lock_guard l(mMutex);
629 numFramesReceived = mNumFramesReceived;
630 }
631 while (numFramesReceived < mNumFramesToRecord && status == OK) {
632 if (mTransferType == AudioRecord::TRANSFER_CALLBACK)
633 status = obtainBufferCb(buffer);
634 else
635 status = obtainBuffer(buffer);
636 if (OK == status && mOutFileFd > 0) {
637 const char* ptr = static_cast<const char*>(static_cast<void*>(buffer.mData.get()));
638 write(mOutFileFd, ptr, buffer.mCapacity);
639 }
640 std::lock_guard l(mMutex);
641 numFramesReceived = mNumFramesReceived;
642 }
643 return OK;
644 }
645
getMarkerPeriod() const646 uint32_t AudioCapture::getMarkerPeriod() const {
647 std::lock_guard l(mMutex);
648 return mMarkerPeriod;
649 }
650
getMarkerPosition() const651 uint32_t AudioCapture::getMarkerPosition() const {
652 std::lock_guard l(mMutex);
653 return mMarkerPosition;
654 }
655
setMarkerPeriod(uint32_t markerPeriod)656 void AudioCapture::setMarkerPeriod(uint32_t markerPeriod) {
657 std::lock_guard l(mMutex);
658 mMarkerPeriod = markerPeriod;
659 }
660
setMarkerPosition(uint32_t markerPosition)661 void AudioCapture::setMarkerPosition(uint32_t markerPosition) {
662 std::lock_guard l(mMutex);
663 mMarkerPosition = markerPosition;
664 }
665
waitAndGetReceivedCbMarkerAtPosition() const666 uint32_t AudioCapture::waitAndGetReceivedCbMarkerAtPosition() const {
667 std::unique_lock lock(mMutex);
668 base::ScopedLockAssertion lock_assertion(mMutex);
669 mMarkerCondition.wait_for(lock, std::chrono::seconds(3), [this]() {
670 base::ScopedLockAssertion lock_assertion(mMutex);
671 return mReceivedCbMarkerAtPosition.has_value();
672 });
673 return mReceivedCbMarkerAtPosition.value_or(~0);
674 }
675
waitAndGetReceivedCbMarkerCount() const676 uint32_t AudioCapture::waitAndGetReceivedCbMarkerCount() const {
677 std::unique_lock lock(mMutex);
678 base::ScopedLockAssertion lock_assertion(mMutex);
679 mMarkerCondition.wait_for(lock, std::chrono::seconds(3), [this]() {
680 base::ScopedLockAssertion lock_assertion(mMutex);
681 return mReceivedCbMarkerCount.has_value();
682 });
683 return mReceivedCbMarkerCount.value_or(0);
684 }
685
isAutomotivePlatform(bool * isAutomotive)686 status_t isAutomotivePlatform(bool* isAutomotive) {
687 const sp<IServiceManager> sm = defaultServiceManager();
688 if (sm == nullptr) {
689 ALOGE("%s: failed to retrieve defaultServiceManager", __func__);
690 return NO_INIT;
691 }
692 sp<IBinder> binder = sm->checkService(String16{"package_native"});
693 if (binder == nullptr) {
694 ALOGE("%s: failed to retrieve native package manager", __func__);
695 return NO_INIT;
696 }
697 *isAutomotive = false;
698 const auto pm = interface_cast<content::pm::IPackageManagerNative>(binder);
699 if (pm != nullptr) {
700 const auto status =
701 pm->hasSystemFeature(String16("android.hardware.type.automotive"), 0, isAutomotive);
702 return status.isOk() ? OK : status.transactionError();
703 }
704 ALOGE("%s: failed to cast to IPackageManagerNative", __func__);
705 return NO_INIT;
706 }
707
listAudioPorts(std::vector<audio_port_v7> & portsVec)708 status_t listAudioPorts(std::vector<audio_port_v7>& portsVec) {
709 int attempts = 5;
710 status_t status;
711 unsigned int generation1, generation;
712 unsigned int numPorts;
713 do {
714 if (attempts-- < 0) {
715 status = TIMED_OUT;
716 break;
717 }
718 // query for number of ports.
719 numPorts = 0;
720 status = AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE, AUDIO_PORT_TYPE_NONE, &numPorts,
721 nullptr, &generation1);
722 if (status != NO_ERROR) {
723 ALOGE("AudioSystem::listAudioPorts returned error %d", status);
724 break;
725 }
726 portsVec.resize(numPorts);
727 status = AudioSystem::listAudioPorts(AUDIO_PORT_ROLE_NONE, AUDIO_PORT_TYPE_NONE, &numPorts,
728 portsVec.data(), &generation);
729 } while (generation1 != generation && status == NO_ERROR);
730 if (status != NO_ERROR) {
731 numPorts = 0;
732 portsVec.clear();
733 }
734 return status;
735 }
736
737 namespace {
738
739 using PortPredicate = std::function<bool(const struct audio_port_v7& port)>;
getPort(PortPredicate pred,audio_port_v7 & port)740 status_t getPort(PortPredicate pred, audio_port_v7& port) {
741 std::vector<struct audio_port_v7> ports;
742 status_t status = listAudioPorts(ports);
743 if (status != OK) return status;
744 for (const auto& p : ports) {
745 if (pred(p)) {
746 port = p;
747 return OK;
748 }
749 }
750 return BAD_VALUE;
751 }
752
753 } // namespace
754
getAnyPort(audio_port_role_t role,audio_port_type_t type,audio_port_v7 & port)755 status_t getAnyPort(audio_port_role_t role, audio_port_type_t type, audio_port_v7& port) {
756 return getPort([&](const struct audio_port_v7& p) { return p.role == role && p.type == type; },
757 port);
758 }
759
getPortById(const audio_port_handle_t portId,audio_port_v7 & port)760 status_t getPortById(const audio_port_handle_t portId, audio_port_v7& port) {
761 return getPort([&](const struct audio_port_v7& p) { return p.id == portId; }, port);
762 }
763
getPortByAttributes(audio_port_role_t role,audio_port_type_t type,audio_devices_t deviceType,const std::string & address,audio_port_v7 & port)764 status_t getPortByAttributes(audio_port_role_t role, audio_port_type_t type,
765 audio_devices_t deviceType, const std::string& address,
766 audio_port_v7& port) {
767 return getPort(
768 [&](const struct audio_port_v7& p) {
769 return p.role == role && p.type == type && p.ext.device.type == deviceType &&
770 !strncmp(p.ext.device.address, address.c_str(),
771 AUDIO_DEVICE_MAX_ADDRESS_LEN);
772 },
773 port);
774 }
775
listAudioPatches(std::vector<struct audio_patch> & patchesVec)776 status_t listAudioPatches(std::vector<struct audio_patch>& patchesVec) {
777 int attempts = 5;
778 status_t status;
779 unsigned int generation1, generation;
780 unsigned int numPatches;
781 do {
782 if (attempts-- < 0) {
783 status = TIMED_OUT;
784 break;
785 }
786 // query for number of patches.
787 numPatches = 0;
788 status = AudioSystem::listAudioPatches(&numPatches, nullptr, &generation1);
789 if (status != NO_ERROR) {
790 ALOGE("AudioSystem::listAudioPatches returned error %d", status);
791 break;
792 }
793 patchesVec.resize(numPatches);
794 status = AudioSystem::listAudioPatches(&numPatches, patchesVec.data(), &generation);
795 } while (generation1 != generation && status == NO_ERROR);
796 if (status != NO_ERROR) {
797 numPatches = 0;
798 patchesVec.clear();
799 }
800 return status;
801 }
802
getPatchForOutputMix(audio_io_handle_t audioIo,audio_patch & patch)803 status_t getPatchForOutputMix(audio_io_handle_t audioIo, audio_patch& patch) {
804 std::vector<struct audio_patch> patches;
805 status_t status = listAudioPatches(patches);
806 if (status != OK) return status;
807
808 for (auto i = 0; i < patches.size(); i++) {
809 for (auto j = 0; j < patches[i].num_sources; j++) {
810 if (patches[i].sources[j].type == AUDIO_PORT_TYPE_MIX &&
811 patches[i].sources[j].ext.mix.handle == audioIo) {
812 patch = patches[i];
813 return OK;
814 }
815 }
816 }
817 return BAD_VALUE;
818 }
819
getPatchForInputMix(audio_io_handle_t audioIo,audio_patch & patch)820 status_t getPatchForInputMix(audio_io_handle_t audioIo, audio_patch& patch) {
821 std::vector<struct audio_patch> patches;
822 status_t status = listAudioPatches(patches);
823 if (status != OK) return status;
824
825 for (auto i = 0; i < patches.size(); i++) {
826 for (auto j = 0; j < patches[i].num_sinks; j++) {
827 if (patches[i].sinks[j].type == AUDIO_PORT_TYPE_MIX &&
828 patches[i].sinks[j].ext.mix.handle == audioIo) {
829 patch = patches[i];
830 return OK;
831 }
832 }
833 }
834 return BAD_VALUE;
835 }
836
837 // Check if the patch matches all the output devices in the deviceIds vector.
patchMatchesOutputDevices(const DeviceIdVector & deviceIds,audio_patch patch)838 bool patchMatchesOutputDevices(const DeviceIdVector& deviceIds, audio_patch patch) {
839 DeviceIdVector patchDeviceIds;
840 for (auto j = 0; j < patch.num_sinks; j++) {
841 if (patch.sinks[j].type == AUDIO_PORT_TYPE_DEVICE) {
842 patchDeviceIds.push_back(patch.sinks[j].id);
843 }
844 }
845 return areDeviceIdsEqual(deviceIds, patchDeviceIds);
846 }
847
patchContainsInputDevice(audio_port_handle_t deviceId,audio_patch patch)848 bool patchContainsInputDevice(audio_port_handle_t deviceId, audio_patch patch) {
849 for (auto j = 0; j < patch.num_sources; j++) {
850 if (patch.sources[j].type == AUDIO_PORT_TYPE_DEVICE && patch.sources[j].id == deviceId) {
851 return true;
852 }
853 }
854 return false;
855 }
856
checkPatchPlayback(audio_io_handle_t audioIo,const DeviceIdVector & deviceIds)857 bool checkPatchPlayback(audio_io_handle_t audioIo, const DeviceIdVector& deviceIds) {
858 struct audio_patch patch;
859 if (getPatchForOutputMix(audioIo, patch) == OK) {
860 return patchMatchesOutputDevices(deviceIds, patch);
861 }
862 return false;
863 }
864
checkPatchCapture(audio_io_handle_t audioIo,audio_port_handle_t deviceId)865 bool checkPatchCapture(audio_io_handle_t audioIo, audio_port_handle_t deviceId) {
866 struct audio_patch patch;
867 if (getPatchForInputMix(audioIo, patch) == OK) {
868 return patchContainsInputDevice(deviceId, patch);
869 }
870 return false;
871 }
872
dumpPortConfig(const audio_port_config & port)873 std::string dumpPortConfig(const audio_port_config& port) {
874 auto aidlPortConfig = legacy2aidl_audio_port_config_AudioPortConfigFw(port);
875 return aidlPortConfig.ok() ? aidlPortConfig.value().toString()
876 : "Error while converting audio port config to AIDL";
877 }
878
dumpPatch(const audio_patch & patch)879 std::string dumpPatch(const audio_patch& patch) {
880 auto aidlPatch = legacy2aidl_audio_patch_AudioPatchFw(patch);
881 return aidlPatch.ok() ? aidlPatch.value().toString() : "Error while converting patch to AIDL";
882 }
883
dumpPort(const audio_port_v7 & port)884 std::string dumpPort(const audio_port_v7& port) {
885 auto aidlPort = legacy2aidl_audio_port_v7_AudioPortFw(port);
886 return aidlPort.ok() ? aidlPort.value().toString() : "Error while converting port to AIDL";
887 }
888