• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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