1 /*
2 **
3 ** Copyright 2008, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 //#define LOG_NDEBUG 0
19 #define LOG_TAG "AudioRecord"
20
21 #include <inttypes.h>
22 #include <android-base/macros.h>
23 #include <android-base/stringprintf.h>
24 #include <sys/resource.h>
25
26 #include <audio_utils/format.h>
27 #include <audiomanager/AudioManager.h>
28 #include <audiomanager/IAudioManager.h>
29 #include <binder/Binder.h>
30 #include <binder/IPCThreadState.h>
31 #include <binder/IServiceManager.h>
32 #include <media/AudioRecord.h>
33 #include <utils/Log.h>
34 #include <private/media/AudioTrackShared.h>
35 #include <processgroup/sched_policy.h>
36 #include <media/IAudioFlinger.h>
37 #include <media/MediaMetricsItem.h>
38 #include <media/TypeConverter.h>
39
40 #define WAIT_PERIOD_MS 10
41
42 namespace android {
43
44 using ::android::base::StringPrintf;
45 using android::content::AttributionSourceState;
46 using aidl_utils::statusTFromBinderStatus;
47
48 // ---------------------------------------------------------------------------
49
50 // static
getMinFrameCount(size_t * frameCount,uint32_t sampleRate,audio_format_t format,audio_channel_mask_t channelMask)51 status_t AudioRecord::getMinFrameCount(
52 size_t* frameCount,
53 uint32_t sampleRate,
54 audio_format_t format,
55 audio_channel_mask_t channelMask)
56 {
57 if (frameCount == NULL) {
58 return BAD_VALUE;
59 }
60
61 size_t size;
62 status_t status = AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &size);
63 if (status != NO_ERROR) {
64 ALOGE("%s(): AudioSystem could not query the input buffer size for"
65 " sampleRate %u, format %#x, channelMask %#x; status %d",
66 __func__, sampleRate, format, channelMask, status);
67 return status;
68 }
69
70 // We double the size of input buffer for ping pong use of record buffer.
71 const auto frameSize = audio_bytes_per_frame(
72 audio_channel_count_from_in_mask(channelMask), format);
73 if (frameSize == 0 || ((*frameCount = (size * 2) / frameSize) == 0)) {
74 ALOGE("%s(): Unsupported configuration: sampleRate %u, format %#x, channelMask %#x",
75 __func__, sampleRate, format, channelMask);
76 return BAD_VALUE;
77 }
78
79 return NO_ERROR;
80 }
81
logIfErrorAndReturnStatus(status_t status,const std::string & errorMessage,const std::string & func)82 status_t AudioRecord::logIfErrorAndReturnStatus(status_t status, const std::string& errorMessage,
83 const std::string& func) {
84 if (status != NO_ERROR) {
85 if (!func.empty()) mMediaMetrics.markError(status, func.c_str());
86 ALOGE_IF(!errorMessage.empty(), "%s", errorMessage.c_str());
87 reportError(status, AMEDIAMETRICS_PROP_EVENT_VALUE_CREATE, errorMessage.c_str());
88 }
89 mStatus = status;
90 return mStatus;
91 }
92
93 // ---------------------------------------------------------------------------
94
gather(const AudioRecord * record)95 void AudioRecord::MediaMetrics::gather(const AudioRecord *record)
96 {
97 #define MM_PREFIX "android.media.audiorecord." // avoid cut-n-paste errors.
98
99 // Java API 28 entries, do not change.
100 mMetricsItem->setCString(MM_PREFIX "encoding", toString(record->mFormat).c_str());
101 mMetricsItem->setCString(MM_PREFIX "source", toString(record->mAttributes.source).c_str());
102 mMetricsItem->setInt32(MM_PREFIX "latency", (int32_t)record->mLatency); // bad estimate.
103 mMetricsItem->setInt32(MM_PREFIX "samplerate", (int32_t)record->mSampleRate);
104 mMetricsItem->setInt32(MM_PREFIX "channels", (int32_t)record->mChannelCount);
105
106 // Non-API entries, these can change.
107 mMetricsItem->setInt32(MM_PREFIX "portId", (int32_t)record->mPortId);
108 mMetricsItem->setInt32(MM_PREFIX "frameCount", (int32_t)record->mFrameCount);
109 mMetricsItem->setCString(MM_PREFIX "attributes", toString(record->mAttributes).c_str());
110 mMetricsItem->setInt64(MM_PREFIX "channelMask", (int64_t)record->mChannelMask);
111
112 // log total duration recording, including anything currently running.
113 int64_t activeNs = 0;
114 if (mStartedNs != 0) {
115 activeNs = systemTime() - mStartedNs;
116 }
117 mMetricsItem->setDouble(MM_PREFIX "durationMs", (mDurationNs + activeNs) * 1e-6);
118 mMetricsItem->setInt64(MM_PREFIX "startCount", (int64_t)mCount);
119
120 if (mLastError != NO_ERROR) {
121 mMetricsItem->setInt32(MM_PREFIX "lastError.code", (int32_t)mLastError);
122 mMetricsItem->setCString(MM_PREFIX "lastError.at", mLastErrorFunc.c_str());
123 }
124 mMetricsItem->setCString(MM_PREFIX "logSessionId", record->mLogSessionId.c_str());
125 }
126
stateToString(bool active)127 static const char *stateToString(bool active) {
128 return active ? "ACTIVE" : "STOPPED";
129 }
130
131 // hand the user a snapshot of the metrics.
getMetrics(mediametrics::Item * & item)132 status_t AudioRecord::getMetrics(mediametrics::Item * &item)
133 {
134 mMediaMetrics.gather(this);
135 mediametrics::Item *tmp = mMediaMetrics.dup();
136 if (tmp == nullptr) {
137 return BAD_VALUE;
138 }
139 item = tmp;
140 return NO_ERROR;
141 }
142
AudioRecord(const AttributionSourceState & client)143 AudioRecord::AudioRecord(const AttributionSourceState &client)
144 : mClientAttributionSource(client)
145 {
146 }
147
AudioRecord(audio_source_t inputSource,uint32_t sampleRate,audio_format_t format,audio_channel_mask_t channelMask,const AttributionSourceState & client,size_t frameCount,const wp<IAudioRecordCallback> & callback,uint32_t notificationFrames,audio_session_t sessionId,transfer_type transferType,audio_input_flags_t flags,const audio_attributes_t * pAttributes,audio_port_handle_t selectedDeviceId,audio_microphone_direction_t selectedMicDirection,float microphoneFieldDimension)148 AudioRecord::AudioRecord(
149 audio_source_t inputSource,
150 uint32_t sampleRate,
151 audio_format_t format,
152 audio_channel_mask_t channelMask,
153 const AttributionSourceState& client,
154 size_t frameCount,
155 const wp<IAudioRecordCallback>& callback,
156 uint32_t notificationFrames,
157 audio_session_t sessionId,
158 transfer_type transferType,
159 audio_input_flags_t flags,
160 const audio_attributes_t* pAttributes,
161 audio_port_handle_t selectedDeviceId,
162 audio_microphone_direction_t selectedMicDirection,
163 float microphoneFieldDimension)
164 : mClientAttributionSource(client)
165 {
166 uid_t uid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(mClientAttributionSource.uid));
167 pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(mClientAttributionSource.pid));
168 (void)set(inputSource, sampleRate, format, channelMask, frameCount, callback,
169 notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags,
170 uid, pid, pAttributes, selectedDeviceId, selectedMicDirection,
171 microphoneFieldDimension);
172 }
173
~AudioRecord()174 AudioRecord::~AudioRecord()
175 {
176 mMediaMetrics.gather(this);
177
178 mediametrics::LogItem(mMetricsId)
179 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_DTOR)
180 .set(AMEDIAMETRICS_PROP_CALLERNAME,
181 mCallerName.empty()
182 ? AMEDIAMETRICS_PROP_CALLERNAME_VALUE_UNKNOWN
183 : mCallerName.c_str())
184 .set(AMEDIAMETRICS_PROP_STATUS, (int32_t)mStatus)
185 .record();
186
187 stopAndJoinCallbacks(); // checks mStatus
188
189 if (mStatus == NO_ERROR) {
190 IInterface::asBinder(mAudioRecord)->unlinkToDeath(mDeathNotifier, this);
191 mAudioRecord.clear();
192 mCblkMemory.clear();
193 mBufferMemory.clear();
194 IPCThreadState::self()->flushCommands();
195 ALOGV("%s(%d): releasing session id %d",
196 __func__, mPortId, mSessionId);
197 pid_t pid = VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(mClientAttributionSource.pid));
198 AudioSystem::releaseAudioSessionId(mSessionId, pid);
199 }
200 }
201
stopAndJoinCallbacks()202 void AudioRecord::stopAndJoinCallbacks() {
203 // Make sure that callback function exits in the case where
204 // it is looping on buffer empty condition in obtainBuffer().
205 // Otherwise the callback thread will never exit.
206 stop();
207 if (mAudioRecordThread != 0) {
208 mAudioRecordThread->requestExit(); // see comment in AudioRecord.h
209 mProxy->interrupt();
210 mAudioRecordThread->requestExitAndWait();
211 mAudioRecordThread.clear();
212 }
213
214 AutoMutex lock(mLock);
215 if (mDeviceCallback != 0 && mInput != AUDIO_IO_HANDLE_NONE) {
216 // This may not stop all of these device callbacks!
217 // TODO: Add some sort of protection.
218 AudioSystem::removeAudioDeviceCallback(this, mInput, mPortId);
219 mDeviceCallback.clear();
220 }
221 }
set(audio_source_t inputSource,uint32_t sampleRate,audio_format_t format,audio_channel_mask_t channelMask,size_t frameCount,const wp<IAudioRecordCallback> & callback,uint32_t notificationFrames,bool threadCanCallJava,audio_session_t sessionId,transfer_type transferType,audio_input_flags_t flags,uid_t uid,pid_t pid,const audio_attributes_t * pAttributes,audio_port_handle_t selectedDeviceId,audio_microphone_direction_t selectedMicDirection,float microphoneFieldDimension,int32_t maxSharedAudioHistoryMs)222 status_t AudioRecord::set(
223 audio_source_t inputSource,
224 uint32_t sampleRate,
225 audio_format_t format,
226 audio_channel_mask_t channelMask,
227 size_t frameCount,
228 const wp<IAudioRecordCallback>& callback,
229 uint32_t notificationFrames,
230 bool threadCanCallJava,
231 audio_session_t sessionId,
232 transfer_type transferType,
233 audio_input_flags_t flags,
234 uid_t uid,
235 pid_t pid,
236 const audio_attributes_t* pAttributes,
237 audio_port_handle_t selectedDeviceId,
238 audio_microphone_direction_t selectedMicDirection,
239 float microphoneFieldDimension,
240 int32_t maxSharedAudioHistoryMs)
241 {
242 status_t status = NO_ERROR;
243 LOG_ALWAYS_FATAL_IF(mInitialized, "%s: should not be called twice", __func__);
244 mInitialized = true;
245 // Note mPortId is not valid until the track is created, so omit mPortId in ALOG for set.
246 ALOGV("%s(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
247 "notificationFrames %u, sessionId %d, transferType %d, flags %#x, attributionSource %s"
248 "uid %d, pid %d",
249 __func__,
250 inputSource, sampleRate, format, channelMask, frameCount, notificationFrames,
251 sessionId, transferType, flags, mClientAttributionSource.toString().c_str(), uid, pid);
252
253 // TODO b/182392553: refactor or remove
254 pid_t callingPid = IPCThreadState::self()->getCallingPid();
255 pid_t myPid = getpid();
256 pid_t adjPid = pid;
257 if (pid == -1 || (callingPid != myPid)) {
258 adjPid = callingPid;
259 }
260 auto clientAttributionSourcePid = legacy2aidl_pid_t_int32_t(adjPid);
261 if (!clientAttributionSourcePid.ok()) {
262 return logIfErrorAndReturnStatus(BAD_VALUE,
263 StringPrintf("%s: received invalid client attribution "
264 "source pid, pid: %d, sessionId: %d",
265 __func__, pid, sessionId),
266 __func__);
267 }
268 mClientAttributionSource.pid = clientAttributionSourcePid.value();
269 uid_t adjUid = uid;
270 if (uid == -1 || (callingPid != myPid)) {
271 adjUid = IPCThreadState::self()->getCallingUid();
272 }
273 auto clientAttributionSourceUid = legacy2aidl_uid_t_int32_t(adjUid);
274 if (!clientAttributionSourceUid.ok()) {
275 return logIfErrorAndReturnStatus(BAD_VALUE,
276 StringPrintf("%s: received invalid client attribution "
277 "source uid, pid: %d, session id: %d",
278 __func__, pid, sessionId),
279 __func__);
280 }
281 mClientAttributionSource.uid = clientAttributionSourceUid.value();
282
283 mTracker.reset(new RecordingActivityTracker());
284
285 sp<IBinder> binder = defaultServiceManager()->checkService(String16("audio"));
286 if (binder != nullptr) {
287 // Barrier to ensure runtime permission update propagates to audioflinger
288 // Must be client-side
289 interface_cast<IAudioManager>(binder)->permissionUpdateBarrier();
290 }
291
292 mSelectedDeviceId = selectedDeviceId;
293 mSelectedMicDirection = selectedMicDirection;
294 mSelectedMicFieldDimension = microphoneFieldDimension;
295 mMaxSharedAudioHistoryMs = maxSharedAudioHistoryMs;
296
297 // Copy the state variables early so they are available for error reporting.
298 if (pAttributes == nullptr) {
299 mAttributes = AUDIO_ATTRIBUTES_INITIALIZER;
300 mAttributes.source = inputSource;
301 if (inputSource == AUDIO_SOURCE_VOICE_COMMUNICATION
302 || inputSource == AUDIO_SOURCE_CAMCORDER) {
303 mAttributes.flags = static_cast<audio_flags_mask_t>(
304 mAttributes.flags | AUDIO_FLAG_CAPTURE_PRIVATE);
305 }
306 } else {
307 // stream type shouldn't be looked at, this track has audio attributes
308 memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t));
309 ALOGV("%s: Building AudioRecord with attributes: source=%d flags=0x%x tags=[%s]",
310 __func__, mAttributes.source, mAttributes.flags, mAttributes.tags);
311 }
312 mSampleRate = sampleRate;
313 if (format == AUDIO_FORMAT_DEFAULT) {
314 format = AUDIO_FORMAT_PCM_16_BIT;
315 }
316 if (!audio_is_linear_pcm(format)) {
317 // Compressed capture requires direct
318 flags = (audio_input_flags_t) (flags | AUDIO_INPUT_FLAG_DIRECT);
319 ALOGI("%s(): Format %#x is not linear pcm. Setting DIRECT, using flags %#x", __func__,
320 format, flags);
321 }
322 mFormat = format;
323 mChannelMask = channelMask;
324 mSessionId = sessionId;
325 ALOGV("%s: mSessionId %d", __func__, mSessionId);
326 mOrigFlags = mFlags = flags;
327
328 mTransfer = transferType;
329 switch (mTransfer) {
330 case TRANSFER_DEFAULT:
331 if (callback == nullptr || threadCanCallJava) {
332 mTransfer = TRANSFER_SYNC;
333 } else {
334 mTransfer = TRANSFER_CALLBACK;
335 }
336 break;
337 case TRANSFER_CALLBACK:
338 if (callback == nullptr) {
339 return logIfErrorAndReturnStatus(
340 BAD_VALUE,
341 StringPrintf("%s: Transfer type TRANSFER_CALLBACK but callback == nullptr, "
342 "pid: %d, session id: %d",
343 __func__, pid, sessionId),
344 __func__);
345 }
346 break;
347 case TRANSFER_OBTAIN:
348 case TRANSFER_SYNC:
349 break;
350 default:
351 return logIfErrorAndReturnStatus(
352 BAD_VALUE,
353 StringPrintf("%s: Invalid transfer type %d, pid: %d, session id: %d", __func__,
354 mTransfer, pid, sessionId),
355 __func__);
356 }
357
358 // invariant that mAudioRecord != 0 is true only after set() returns successfully
359 if (mAudioRecord != 0) {
360 return logIfErrorAndReturnStatus(
361 INVALID_OPERATION,
362 StringPrintf("%s: Track already in use, pid: %d, session id: %d", __func__, pid,
363 sessionId),
364 __func__);
365 }
366
367 if (!audio_is_valid_format(mFormat)) {
368 return logIfErrorAndReturnStatus(
369 BAD_VALUE,
370 StringPrintf("%s: Format %#x is not valid, pid: %d, session id: %d", __func__,
371 mFormat, pid, sessionId),
372 __func__);
373 }
374
375 if (!audio_is_input_channel(mChannelMask)) {
376 return logIfErrorAndReturnStatus(
377 BAD_VALUE,
378 StringPrintf("%s: Invalid channel mask %#x, pid: %d, session id: %d", __func__,
379 mChannelMask, pid, sessionId),
380 __func__);
381 }
382
383 mChannelCount = audio_channel_count_from_in_mask(mChannelMask);
384 mFrameSize = audio_bytes_per_frame(mChannelCount, mFormat);
385
386 // mFrameCount is initialized in createRecord_l
387 mReqFrameCount = frameCount;
388
389 mNotificationFramesReq = notificationFrames;
390 // mNotificationFramesAct is initialized in createRecord_l
391
392 mCallback = callback;
393 if (mCallback != nullptr) {
394 mAudioRecordThread = new AudioRecordThread(*this);
395 mAudioRecordThread->run("AudioRecord", ANDROID_PRIORITY_AUDIO);
396 // thread begins in paused state, and will not reference us until start()
397 }
398
399 // create the IAudioRecord
400 {
401 AutoMutex lock(mLock);
402 status = createRecord_l(0 /*epoch*/);
403 }
404
405 ALOGV("%s(%d): status %d", __func__, mPortId, status);
406
407 if (status != NO_ERROR) {
408 if (mAudioRecordThread != 0) {
409 mAudioRecordThread->requestExit(); // see comment in AudioRecord.h
410 mAudioRecordThread->requestExitAndWait();
411 mAudioRecordThread.clear();
412 }
413 // bypass error message to avoid logging twice (createRecord_l logs the error).
414 mStatus = status;
415 return mStatus;
416 }
417
418 // TODO: add audio hardware input latency here
419 mLatency = (1000LL * mFrameCount) / mSampleRate;
420 mMarkerPosition = 0;
421 mMarkerReached = false;
422 mNewPosition = 0;
423 mUpdatePeriod = 0;
424 AudioSystem::acquireAudioSessionId(mSessionId, adjPid, adjUid);
425 mSequence = 1;
426 mObservedSequence = mSequence;
427 mInOverrun = false;
428 mFramesRead = 0;
429 mFramesReadServerOffset = 0;
430
431 return logIfErrorAndReturnStatus(status, "", __func__);
432 }
433
434 // -------------------------------------------------------------------------
435
start(AudioSystem::sync_event_t event,audio_session_t triggerSession)436 status_t AudioRecord::start(AudioSystem::sync_event_t event, audio_session_t triggerSession)
437 {
438 const int64_t beginNs = systemTime();
439 ALOGV("%s(%d): sync event %d trigger session %d", __func__, mPortId, event, triggerSession);
440 AutoMutex lock(mLock);
441
442 status_t status = NO_ERROR;
443 mediametrics::Defer defer([&] {
444 mediametrics::LogItem(mMetricsId)
445 .set(AMEDIAMETRICS_PROP_CALLERNAME,
446 mCallerName.empty()
447 ? AMEDIAMETRICS_PROP_CALLERNAME_VALUE_UNKNOWN
448 : mCallerName.c_str())
449 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_START)
450 .set(AMEDIAMETRICS_PROP_EXECUTIONTIMENS, (int64_t)(systemTime() - beginNs))
451 .set(AMEDIAMETRICS_PROP_STATE, stateToString(mActive))
452 .set(AMEDIAMETRICS_PROP_STATUS, (int32_t)status)
453 .record(); });
454
455 if (mActive) {
456 return status;
457 }
458
459 // discard data in buffer
460 const uint32_t framesFlushed = mProxy->flush();
461 mFramesReadServerOffset -= mFramesRead + framesFlushed;
462 mFramesRead = 0;
463 mProxy->clearTimestamp(); // timestamp is invalid until next server push
464 mPreviousTimestamp.clear();
465 mTimestampRetrogradePositionReported = false;
466 mTimestampRetrogradeTimeReported = false;
467
468 // reset current position as seen by client to 0
469 mProxy->setEpoch(mProxy->getEpoch() - mProxy->getPosition());
470 // force refresh of remaining frames by processAudioBuffer() as last
471 // read before stop could be partial.
472 mRefreshRemaining = true;
473
474 mNewPosition = mProxy->getPosition() + mUpdatePeriod;
475 int32_t flags = android_atomic_acquire_load(&mCblk->mFlags);
476
477 // we reactivate markers (mMarkerPosition != 0) as the position is reset to 0.
478 // This is legacy behavior. This is not done in stop() to avoid a race condition
479 // where the last marker event is issued twice.
480 mMarkerReached = false;
481 // mActive is checked by restoreRecord_l
482 mActive = true;
483
484 if (!(flags & CBLK_INVALID)) {
485 status = statusTFromBinderStatus(mAudioRecord->start(event, triggerSession));
486 if (status == DEAD_OBJECT) {
487 flags |= CBLK_INVALID;
488 }
489 }
490 if (flags & CBLK_INVALID) {
491 status = restoreRecord_l("start");
492 }
493
494 // Call these directly because we are already holding the lock.
495 mAudioRecord->setPreferredMicrophoneDirection(mSelectedMicDirection);
496 mAudioRecord->setPreferredMicrophoneFieldDimension(mSelectedMicFieldDimension);
497
498 if (status != NO_ERROR) {
499 mActive = false;
500 ALOGE("%s(%d): status %d", __func__, mPortId, status);
501 mMediaMetrics.markError(status, __FUNCTION__);
502 } else {
503 mTracker->recordingStarted();
504 sp<AudioRecordThread> t = mAudioRecordThread;
505 if (t != 0) {
506 t->resume();
507 } else {
508 mPreviousPriority = getpriority(PRIO_PROCESS, 0);
509 get_sched_policy(0, &mPreviousSchedulingGroup);
510 androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO);
511 }
512
513 // we've successfully started, log that time
514 mMediaMetrics.logStart(systemTime());
515 }
516 return status;
517 }
518
stop()519 void AudioRecord::stop()
520 {
521 const int64_t beginNs = systemTime();
522 AutoMutex lock(mLock);
523 mediametrics::Defer defer([&] {
524 mediametrics::LogItem(mMetricsId)
525 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_STOP)
526 .set(AMEDIAMETRICS_PROP_EXECUTIONTIMENS, (int64_t)(systemTime() - beginNs))
527 .set(AMEDIAMETRICS_PROP_STATE, stateToString(mActive))
528 .record(); });
529
530 ALOGV("%s(%d): mActive:%d\n", __func__, mPortId, mActive);
531 if (!mActive) {
532 return;
533 }
534
535 mActive = false;
536 mProxy->interrupt();
537 mAudioRecord->stop();
538 mTracker->recordingStopped();
539
540 // Note: legacy handling - stop does not clear record marker and
541 // periodic update position; we update those on start().
542
543 sp<AudioRecordThread> t = mAudioRecordThread;
544 if (t != 0) {
545 t->pause();
546 } else {
547 setpriority(PRIO_PROCESS, 0, mPreviousPriority);
548 set_sched_policy(0, mPreviousSchedulingGroup);
549 }
550
551 // we've successfully started, log that time
552 mMediaMetrics.logStop(systemTime());
553 }
554
stopped() const555 bool AudioRecord::stopped() const
556 {
557 AutoMutex lock(mLock);
558 return !mActive;
559 }
560
setMarkerPosition(uint32_t marker)561 status_t AudioRecord::setMarkerPosition(uint32_t marker)
562 {
563 AutoMutex lock(mLock);
564 // The only purpose of setting marker position is to get a callback
565 if (mCallback == nullptr) {
566 return INVALID_OPERATION;
567 }
568
569 mMarkerPosition = marker;
570 mMarkerReached = false;
571
572 sp<AudioRecordThread> t = mAudioRecordThread;
573 if (t != 0) {
574 t->wake();
575 }
576 return NO_ERROR;
577 }
578
getHalSampleRate() const579 uint32_t AudioRecord::getHalSampleRate() const
580 {
581 return mHalSampleRate;
582 }
583
getHalChannelCount() const584 uint32_t AudioRecord::getHalChannelCount() const
585 {
586 return mHalChannelCount;
587 }
588
getHalFormat() const589 audio_format_t AudioRecord::getHalFormat() const
590 {
591 return mHalFormat;
592 }
593
getMarkerPosition(uint32_t * marker) const594 status_t AudioRecord::getMarkerPosition(uint32_t *marker) const
595 {
596 if (marker == NULL) {
597 return BAD_VALUE;
598 }
599
600 AutoMutex lock(mLock);
601 mMarkerPosition.getValue(marker);
602
603 return NO_ERROR;
604 }
605
setPositionUpdatePeriod(uint32_t updatePeriod)606 status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod)
607 {
608 AutoMutex lock(mLock);
609 // The only purpose of setting position update period is to get a callback
610 if (mCallback == nullptr) {
611 return INVALID_OPERATION;
612 }
613
614 mNewPosition = mProxy->getPosition() + updatePeriod;
615 mUpdatePeriod = updatePeriod;
616
617 sp<AudioRecordThread> t = mAudioRecordThread;
618 if (t != 0) {
619 t->wake();
620 }
621 return NO_ERROR;
622 }
623
getPositionUpdatePeriod(uint32_t * updatePeriod) const624 status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const
625 {
626 if (updatePeriod == NULL) {
627 return BAD_VALUE;
628 }
629
630 AutoMutex lock(mLock);
631 *updatePeriod = mUpdatePeriod;
632
633 return NO_ERROR;
634 }
635
getPosition(uint32_t * position) const636 status_t AudioRecord::getPosition(uint32_t *position) const
637 {
638 if (position == NULL) {
639 return BAD_VALUE;
640 }
641
642 AutoMutex lock(mLock);
643 mProxy->getPosition().getValue(position);
644
645 return NO_ERROR;
646 }
647
getInputFramesLost() const648 uint32_t AudioRecord::getInputFramesLost() const
649 {
650 // no need to check mActive, because if inactive this will return 0, which is what we want
651 return AudioSystem::getInputFramesLost(getInputPrivate());
652 }
653
getTimestamp(ExtendedTimestamp * timestamp)654 status_t AudioRecord::getTimestamp(ExtendedTimestamp *timestamp)
655 {
656 if (timestamp == nullptr) {
657 return BAD_VALUE;
658 }
659 AutoMutex lock(mLock);
660 status_t status = mProxy->getTimestamp(timestamp);
661 if (status == OK) {
662 timestamp->mPosition[ExtendedTimestamp::LOCATION_CLIENT] = mFramesRead;
663 timestamp->mTimeNs[ExtendedTimestamp::LOCATION_CLIENT] = 0;
664 if (!audio_is_linear_pcm(mFormat)) {
665 // Don't do retrograde corrections or server offset if track is
666 // compressed
667 return OK;
668 }
669 // server side frame offset in case AudioRecord has been restored.
670 for (int i = ExtendedTimestamp::LOCATION_SERVER;
671 i < ExtendedTimestamp::LOCATION_MAX; ++i) {
672 if (timestamp->mTimeNs[i] >= 0) {
673 timestamp->mPosition[i] += mFramesReadServerOffset;
674 }
675 }
676
677 bool timestampRetrogradeTimeReported = false;
678 bool timestampRetrogradePositionReported = false;
679 for (int i = 0; i < ExtendedTimestamp::LOCATION_MAX; ++i) {
680 if (timestamp->mTimeNs[i] >= 0 && mPreviousTimestamp.mTimeNs[i] >= 0) {
681 if (timestamp->mTimeNs[i] < mPreviousTimestamp.mTimeNs[i]) {
682 if (!mTimestampRetrogradeTimeReported) {
683 ALOGD("%s: retrograde time adjusting [%d] current:%lld to previous:%lld",
684 __func__, i, (long long)timestamp->mTimeNs[i],
685 (long long)mPreviousTimestamp.mTimeNs[i]);
686 timestampRetrogradeTimeReported = true;
687 }
688 timestamp->mTimeNs[i] = mPreviousTimestamp.mTimeNs[i];
689 }
690 if (timestamp->mPosition[i] < mPreviousTimestamp.mPosition[i]) {
691 if (!mTimestampRetrogradePositionReported) {
692 ALOGD("%s: retrograde position"
693 " adjusting [%d] current:%lld to previous:%lld",
694 __func__, i, (long long)timestamp->mPosition[i],
695 (long long)mPreviousTimestamp.mPosition[i]);
696 timestampRetrogradePositionReported = true;
697 }
698 timestamp->mPosition[i] = mPreviousTimestamp.mPosition[i];
699 }
700 }
701 }
702 mPreviousTimestamp = *timestamp;
703 if (timestampRetrogradeTimeReported) {
704 mTimestampRetrogradeTimeReported = true;
705 }
706 if (timestampRetrogradePositionReported) {
707 mTimestampRetrogradePositionReported = true;
708 }
709 }
710 return status;
711 }
712
713 // ---- Explicit Routing ---------------------------------------------------
setInputDevice(audio_port_handle_t deviceId)714 status_t AudioRecord::setInputDevice(audio_port_handle_t deviceId) {
715 AutoMutex lock(mLock);
716 ALOGV("%s(%d): deviceId=%d mSelectedDeviceId=%d",
717 __func__, mPortId, deviceId, mSelectedDeviceId);
718 const int64_t beginNs = systemTime();
719 mediametrics::Defer defer([&] {
720 mediametrics::LogItem(mMetricsId)
721 .set(AMEDIAMETRICS_PROP_CALLERNAME,
722 mCallerName.empty()
723 ? AMEDIAMETRICS_PROP_CALLERNAME_VALUE_UNKNOWN
724 : mCallerName.c_str())
725 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_SETPREFERREDDEVICE)
726 .set(AMEDIAMETRICS_PROP_EXECUTIONTIMENS, (int64_t)(systemTime() - beginNs))
727 .set(AMEDIAMETRICS_PROP_SELECTEDDEVICEID, (int32_t)deviceId)
728 .record(); });
729
730 if (mSelectedDeviceId != deviceId) {
731 mSelectedDeviceId = deviceId;
732 if (mStatus == NO_ERROR) {
733 if (mActive) {
734 if (getFirstDeviceId(mRoutedDeviceIds) != mSelectedDeviceId) {
735 // stop capture so that audio policy manager does not reject the new instance
736 // start request as only one capture can be active at a time.
737 if (mAudioRecord != 0) {
738 mAudioRecord->stop();
739 }
740 android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
741 mProxy->interrupt();
742 }
743 } else {
744 // if the track is idle, try to restore now and
745 // defer to next start if not possible
746 if (restoreRecord_l("setInputDevice") != OK) {
747 android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
748 }
749 }
750 }
751 }
752 return NO_ERROR;
753 }
754
getInputDevice()755 audio_port_handle_t AudioRecord::getInputDevice() {
756 AutoMutex lock(mLock);
757 return mSelectedDeviceId;
758 }
759
760 // must be called with mLock held
updateRoutedDeviceIds_l()761 void AudioRecord::updateRoutedDeviceIds_l()
762 {
763 // if the record is inactive, do not update actual device as the input stream maybe routed
764 // from a device not relevant to this client because of other active use cases.
765 if (!mActive) {
766 return;
767 }
768 if (mInput != AUDIO_IO_HANDLE_NONE) {
769 DeviceIdVector deviceIds;
770 status_t result = AudioSystem::getDeviceIdsForIo(mInput, deviceIds);
771 if (result != OK) {
772 ALOGW("%s: getDeviceIdsForIo returned: %d", __func__, result);
773 }
774 if (!deviceIds.empty()) {
775 mRoutedDeviceIds = deviceIds;
776 }
777 }
778 }
779
getRoutedDeviceIds()780 DeviceIdVector AudioRecord::getRoutedDeviceIds() {
781 AutoMutex lock(mLock);
782 updateRoutedDeviceIds_l();
783 return mRoutedDeviceIds;
784 }
785
dump(int fd,const Vector<String16> & args __unused) const786 status_t AudioRecord::dump(int fd, const Vector<String16>& args __unused) const
787 {
788 String8 result;
789
790 result.append(" AudioRecord::dump\n");
791 result.appendFormat(" id(%d) status(%d), active(%d), session Id(%d)\n",
792 mPortId, mStatus, mActive, mSessionId);
793 result.appendFormat(" flags(%#x), req. flags(%#x), audio source(%d)\n",
794 mFlags, mOrigFlags, mAttributes.source);
795 result.appendFormat(" format(%#x), channel mask(%#x), channel count(%u), sample rate(%u)\n",
796 mFormat, mChannelMask, mChannelCount, mSampleRate);
797 result.appendFormat(" frame count(%zu), req. frame count(%zu)\n",
798 mFrameCount, mReqFrameCount);
799 result.appendFormat(" notif. frame count(%u), req. notif. frame count(%u)\n",
800 mNotificationFramesAct, mNotificationFramesReq);
801 result.appendFormat(" input(%d), latency(%u), selected device Id(%d)\n",
802 mInput, mLatency, mSelectedDeviceId);
803 result.appendFormat(" routed device Ids(%s), mic direction(%d) mic field dimension(%f)",
804 toString(mRoutedDeviceIds).c_str(), mSelectedMicDirection,
805 mSelectedMicFieldDimension);
806 ::write(fd, result.c_str(), result.size());
807 return NO_ERROR;
808 }
809
810 // -------------------------------------------------------------------------
811 // TODO Move this macro to a common header file for enum to string conversion in audio framework.
812 #define MEDIA_CASE_ENUM(name) case name: return #name
convertTransferToText(transfer_type transferType)813 const char * AudioRecord::convertTransferToText(transfer_type transferType) {
814 switch (transferType) {
815 MEDIA_CASE_ENUM(TRANSFER_DEFAULT);
816 MEDIA_CASE_ENUM(TRANSFER_CALLBACK);
817 MEDIA_CASE_ENUM(TRANSFER_OBTAIN);
818 MEDIA_CASE_ENUM(TRANSFER_SYNC);
819 default:
820 return "UNRECOGNIZED";
821 }
822 }
823
824 // must be called with mLock held
createRecord_l(const Modulo<uint32_t> & epoch)825 status_t AudioRecord::createRecord_l(const Modulo<uint32_t> &epoch)
826 {
827 const int64_t beginNs = systemTime();
828 const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
829 IAudioFlinger::CreateRecordInput input;
830 IAudioFlinger::CreateRecordOutput output;
831 [[maybe_unused]] audio_session_t originalSessionId;
832 void *iMemPointer;
833 audio_track_cblk_t* cblk;
834 status_t status;
835 static const int32_t kMaxCreateAttempts = 3;
836 int32_t remainingAttempts = kMaxCreateAttempts;
837
838 if (audioFlinger == 0) {
839 return logIfErrorAndReturnStatus(
840 NO_INIT, StringPrintf("%s(%d): Could not get audioflinger", __func__, mPortId), "");
841 }
842
843 // mFlags (not mOrigFlags) is modified depending on whether fast request is accepted.
844 // After fast request is denied, we will request again if IAudioRecord is re-created.
845
846 // Now that we have a reference to an I/O handle and have not yet handed it off to AudioFlinger,
847 // we must release it ourselves if anything goes wrong.
848
849 // Client can only express a preference for FAST. Server will perform additional tests.
850 if (mFlags & AUDIO_INPUT_FLAG_FAST) {
851 bool useCaseAllowed =
852 // any of these use cases:
853 // use case 1: callback transfer mode
854 (mTransfer == TRANSFER_CALLBACK) ||
855 // use case 2: blocking read mode
856 // The default buffer capacity at 48 kHz is 2048 frames, or ~42.6 ms.
857 // That's enough for double-buffering with our standard 20 ms rule of thumb for
858 // the minimum period of a non-SCHED_FIFO thread.
859 // This is needed so that AAudio apps can do a low latency non-blocking read from a
860 // callback running with SCHED_FIFO.
861 (mTransfer == TRANSFER_SYNC) ||
862 // use case 3: obtain/release mode
863 (mTransfer == TRANSFER_OBTAIN);
864 if (!useCaseAllowed) {
865 ALOGD("%s(%d): AUDIO_INPUT_FLAG_FAST denied, incompatible transfer = %s",
866 __func__, mPortId,
867 convertTransferToText(mTransfer));
868 mFlags = (audio_input_flags_t) (mFlags & ~(AUDIO_INPUT_FLAG_FAST |
869 AUDIO_INPUT_FLAG_RAW));
870 }
871 }
872
873 input.attr = mAttributes;
874 input.config.sample_rate = mSampleRate;
875 input.config.channel_mask = mChannelMask;
876 input.config.format = mFormat;
877 input.clientInfo.attributionSource = mClientAttributionSource;
878 input.clientInfo.clientTid = -1;
879 if (mFlags & AUDIO_INPUT_FLAG_FAST) {
880 if (mAudioRecordThread != 0) {
881 input.clientInfo.clientTid = mAudioRecordThread->getTid();
882 }
883 }
884 input.riid = mTracker->getRiid();
885
886 input.flags = mFlags;
887 // The notification frame count is the period between callbacks, as suggested by the client
888 // but moderated by the server. For record, the calculations are done entirely on server side.
889 input.frameCount = mReqFrameCount;
890 input.notificationFrameCount = mNotificationFramesReq;
891 input.selectedDeviceId = mSelectedDeviceId;
892 input.sessionId = mSessionId;
893 originalSessionId = mSessionId;
894 input.maxSharedAudioHistoryMs = mMaxSharedAudioHistoryMs;
895
896 do {
897 media::CreateRecordResponse response;
898 auto aidlInput = input.toAidl();
899 if (!aidlInput.ok()) {
900 return logIfErrorAndReturnStatus(
901 BAD_VALUE,
902 StringPrintf("%s(%d): Could not create record due to invalid input", __func__,
903 mPortId),
904 "");
905 }
906 status = audioFlinger->createRecord(aidlInput.value(), response);
907
908 auto recordOutput = IAudioFlinger::CreateRecordOutput::fromAidl(response);
909 if (!recordOutput.ok()) {
910 return logIfErrorAndReturnStatus(
911 BAD_VALUE,
912 StringPrintf("%s(%d): Could not create record output due to invalid response",
913 __func__, mPortId),
914 "");
915 }
916 output = recordOutput.value();
917 if (status == NO_ERROR) {
918 break;
919 }
920 if (status != FAILED_TRANSACTION || --remainingAttempts <= 0) {
921 return logIfErrorAndReturnStatus(
922 status,
923 StringPrintf("%s(%d): AudioFlinger could not create record track, status: %d",
924 __func__, mPortId, status),
925 "");
926 }
927 // FAILED_TRANSACTION happens under very specific conditions causing a state mismatch
928 // between audio policy manager and audio flinger during the input stream open sequence
929 // and can be recovered by retrying.
930 // Leave time for race condition to clear before retrying and randomize delay
931 // to reduce the probability of concurrent retries in locked steps.
932 usleep((20 + rand() % 30) * 10000);
933 } while (1);
934
935 ALOG_ASSERT(output.audioRecord != 0);
936
937 // AudioFlinger now owns the reference to the I/O handle,
938 // so we are no longer responsible for releasing it.
939
940 mAwaitBoost = false;
941 if (output.flags & AUDIO_INPUT_FLAG_FAST) {
942 ALOGI("%s(%d): AUDIO_INPUT_FLAG_FAST successful; frameCount %zu -> %zu",
943 __func__, mPortId,
944 mReqFrameCount, output.frameCount);
945 mAwaitBoost = true;
946 }
947 mFlags = output.flags;
948 mRoutedDeviceIds = { output.selectedDeviceId };
949 mSessionId = output.sessionId;
950 mSampleRate = output.sampleRate;
951 mServerConfig = output.serverConfig;
952 mServerFrameSize = audio_bytes_per_frame(
953 audio_channel_count_from_in_mask(mServerConfig.channel_mask), mServerConfig.format);
954 mServerSampleSize = audio_bytes_per_sample(mServerConfig.format);
955 mHalSampleRate = output.halConfig.sample_rate;
956 mHalChannelCount = audio_channel_count_from_in_mask(output.halConfig.channel_mask);
957 mHalFormat = output.halConfig.format;
958
959 if (output.cblk == 0) {
960 return logIfErrorAndReturnStatus(
961 NO_INIT, StringPrintf("%s(%d): Could not get control block", __func__, mPortId),
962 "");
963 }
964 // TODO: Using unsecurePointer() has some associated security pitfalls
965 // (see declaration for details).
966 // Either document why it is safe in this case or address the
967 // issue (e.g. by copying).
968 iMemPointer = output.cblk ->unsecurePointer();
969 if (iMemPointer == NULL) {
970 return logIfErrorAndReturnStatus(
971 NO_INIT,
972 StringPrintf("%s(%d): Could not get control block pointer", __func__, mPortId), "");
973 }
974 cblk = static_cast<audio_track_cblk_t*>(iMemPointer);
975
976 // Starting address of buffers in shared memory.
977 // The buffers are either immediately after the control block,
978 // or in a separate area at discretion of server.
979 void *buffers;
980 if (output.buffers == 0) {
981 buffers = cblk + 1;
982 } else {
983 // TODO: Using unsecurePointer() has some associated security pitfalls
984 // (see declaration for details).
985 // Either document why it is safe in this case or address the
986 // issue (e.g. by copying).
987 buffers = output.buffers->unsecurePointer();
988 if (buffers == NULL) {
989 return logIfErrorAndReturnStatus(
990 NO_INIT,
991 StringPrintf("%s(%d): Could not get buffer pointer", __func__, mPortId), "");
992 }
993 }
994
995 // invariant that mAudioRecord != 0 is true only after set() returns successfully
996 if (mAudioRecord != 0) {
997 IInterface::asBinder(mAudioRecord)->unlinkToDeath(mDeathNotifier, this);
998 mDeathNotifier.clear();
999 }
1000 mAudioRecord = output.audioRecord;
1001 mCblkMemory = output.cblk;
1002 mBufferMemory = output.buffers;
1003 IPCThreadState::self()->flushCommands();
1004
1005 mCblk = cblk;
1006 // note that output.frameCount is the (possibly revised) value of mReqFrameCount
1007 if (output.frameCount < mReqFrameCount || (mReqFrameCount == 0 && output.frameCount == 0)) {
1008 ALOGW("%s(%d): Requested frameCount %zu but received frameCount %zu",
1009 __func__, output.portId,
1010 mReqFrameCount, output.frameCount);
1011 }
1012
1013 // Make sure that application is notified with sufficient margin before overrun.
1014 // The computation is done on server side.
1015 if (mNotificationFramesReq > 0 && output.notificationFrameCount != mNotificationFramesReq) {
1016 ALOGW("%s(%d): Server adjusted notificationFrames from %u to %zu for frameCount %zu",
1017 __func__, output.portId,
1018 mNotificationFramesReq, output.notificationFrameCount, output.frameCount);
1019 }
1020 mNotificationFramesAct = (uint32_t)output.notificationFrameCount;
1021 if (mServerConfig.format != mFormat && mCallback != nullptr) {
1022 mFormatConversionBufRaw = std::make_unique<uint8_t[]>(mNotificationFramesAct * mFrameSize);
1023 mFormatConversionBuffer.raw = mFormatConversionBufRaw.get();
1024 }
1025
1026 //mInput != input includes the case where mInput == AUDIO_IO_HANDLE_NONE for first creation
1027 if (mDeviceCallback != 0) {
1028 if (mInput != AUDIO_IO_HANDLE_NONE) {
1029 AudioSystem::removeAudioDeviceCallback(this, mInput, mPortId);
1030 }
1031 AudioSystem::addAudioDeviceCallback(this, output.inputId, output.portId);
1032 }
1033
1034 if (!mSharedAudioPackageName.empty()) {
1035 mAudioRecord->shareAudioHistory(mSharedAudioPackageName, mSharedAudioStartMs);
1036 }
1037
1038 mPortId = output.portId;
1039 // We retain a copy of the I/O handle, but don't own the reference
1040 mInput = output.inputId;
1041 mRefreshRemaining = true;
1042
1043 mFrameCount = output.frameCount;
1044 // If IAudioRecord is re-created, don't let the requested frameCount
1045 // decrease. This can confuse clients that cache frameCount().
1046 if (mFrameCount > mReqFrameCount) {
1047 mReqFrameCount = mFrameCount;
1048 }
1049
1050 // update proxy
1051 mProxy = new AudioRecordClientProxy(cblk, buffers, mFrameCount, mServerFrameSize);
1052 mProxy->setEpoch(epoch);
1053 mProxy->setMinimum(mNotificationFramesAct);
1054
1055 mDeathNotifier = new DeathNotifier(this);
1056 IInterface::asBinder(mAudioRecord)->linkToDeath(mDeathNotifier, this);
1057
1058 mMetricsId = std::string(AMEDIAMETRICS_KEY_PREFIX_AUDIO_RECORD) + std::to_string(mPortId);
1059 mediametrics::LogItem(mMetricsId)
1060 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_CREATE)
1061 .set(AMEDIAMETRICS_PROP_EXECUTIONTIMENS, (int64_t)(systemTime() - beginNs))
1062 // the following are immutable (at least until restore)
1063 .set(AMEDIAMETRICS_PROP_FLAGS, toString(mFlags).c_str())
1064 .set(AMEDIAMETRICS_PROP_ORIGINALFLAGS, toString(mOrigFlags).c_str())
1065 .set(AMEDIAMETRICS_PROP_SESSIONID, (int32_t)mSessionId)
1066 .set(AMEDIAMETRICS_PROP_TRACKID, mPortId)
1067 .set(AMEDIAMETRICS_PROP_LOGSESSIONID, mLogSessionId)
1068 .set(AMEDIAMETRICS_PROP_SOURCE, toString(mAttributes.source).c_str())
1069 .set(AMEDIAMETRICS_PROP_THREADID, (int32_t)output.inputId)
1070 .set(AMEDIAMETRICS_PROP_SELECTEDDEVICEID, (int32_t)mSelectedDeviceId)
1071 .set(AMEDIAMETRICS_PROP_ROUTEDDEVICEID, (int32_t)(getFirstDeviceId(mRoutedDeviceIds)))
1072 .set(AMEDIAMETRICS_PROP_ROUTEDDEVICEIDS, toString(mRoutedDeviceIds).c_str())
1073 .set(AMEDIAMETRICS_PROP_ENCODING, toString(mFormat).c_str())
1074 .set(AMEDIAMETRICS_PROP_CHANNELMASK, (int32_t)mChannelMask)
1075 .set(AMEDIAMETRICS_PROP_FRAMECOUNT, (int32_t)mFrameCount)
1076 .set(AMEDIAMETRICS_PROP_SAMPLERATE, (int32_t)mSampleRate)
1077 // the following are NOT immutable
1078 .set(AMEDIAMETRICS_PROP_STATE, stateToString(mActive))
1079 .set(AMEDIAMETRICS_PROP_STATUS, (int32_t)status)
1080 .set(AMEDIAMETRICS_PROP_SELECTEDMICDIRECTION, (int32_t)mSelectedMicDirection)
1081 .set(AMEDIAMETRICS_PROP_SELECTEDMICFIELDDIRECTION, (double)mSelectedMicFieldDimension)
1082 .record();
1083
1084 // sp<IAudioTrack> track destructor will cause releaseOutput() to be called by AudioFlinger
1085 return logIfErrorAndReturnStatus(status, "", "");
1086 }
1087
1088 // Report error associated with the event and some configuration details.
reportError(status_t status,const char * event,const char * message) const1089 void AudioRecord::reportError(status_t status, const char *event, const char *message) const
1090 {
1091 if (status == NO_ERROR) return;
1092 // We report error on the native side because some callers do not come
1093 // from Java.
1094 // Ensure these variables are initialized in set().
1095 mediametrics::LogItem(AMEDIAMETRICS_KEY_AUDIO_RECORD_ERROR)
1096 .set(AMEDIAMETRICS_PROP_EVENT, event)
1097 .set(AMEDIAMETRICS_PROP_STATUS, (int32_t)status)
1098 .set(AMEDIAMETRICS_PROP_STATUSMESSAGE, message)
1099 .set(AMEDIAMETRICS_PROP_ORIGINALFLAGS, toString(mOrigFlags).c_str())
1100 .set(AMEDIAMETRICS_PROP_SESSIONID, (int32_t)mSessionId)
1101 .set(AMEDIAMETRICS_PROP_SOURCE, toString(mAttributes.source).c_str())
1102 .set(AMEDIAMETRICS_PROP_SELECTEDDEVICEID, (int32_t)mSelectedDeviceId)
1103 .set(AMEDIAMETRICS_PROP_ENCODING, toString(mFormat).c_str())
1104 .set(AMEDIAMETRICS_PROP_CHANNELMASK, (int32_t)mChannelMask)
1105 .set(AMEDIAMETRICS_PROP_FRAMECOUNT, (int32_t)mFrameCount)
1106 .set(AMEDIAMETRICS_PROP_SAMPLERATE, (int32_t)mSampleRate)
1107 .record();
1108 }
1109
obtainBuffer(Buffer * audioBuffer,int32_t waitCount,size_t * nonContig)1110 status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount, size_t *nonContig)
1111 {
1112 if (audioBuffer == NULL) {
1113 if (nonContig != NULL) {
1114 *nonContig = 0;
1115 }
1116 return BAD_VALUE;
1117 }
1118 if (mTransfer != TRANSFER_OBTAIN) {
1119 audioBuffer->frameCount = 0;
1120 audioBuffer->mSize = 0;
1121 audioBuffer->raw = NULL;
1122 if (nonContig != NULL) {
1123 *nonContig = 0;
1124 }
1125 return INVALID_OPERATION;
1126 }
1127
1128 const struct timespec *requested;
1129 struct timespec timeout;
1130 if (waitCount == -1) {
1131 requested = &ClientProxy::kForever;
1132 } else if (waitCount == 0) {
1133 requested = &ClientProxy::kNonBlocking;
1134 } else if (waitCount > 0) {
1135 time_t ms = WAIT_PERIOD_MS * (time_t) waitCount;
1136 timeout.tv_sec = ms / 1000;
1137 timeout.tv_nsec = (long) (ms % 1000) * 1000000;
1138 requested = &timeout;
1139 } else {
1140 ALOGE("%s(%d): invalid waitCount %d", __func__, mPortId, waitCount);
1141 requested = NULL;
1142 }
1143 return obtainBuffer(audioBuffer, requested, NULL /*elapsed*/, nonContig);
1144 }
1145
obtainBuffer(Buffer * audioBuffer,const struct timespec * requested,struct timespec * elapsed,size_t * nonContig)1146 status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, const struct timespec *requested,
1147 struct timespec *elapsed, size_t *nonContig)
1148 {
1149 // previous and new IAudioRecord sequence numbers are used to detect track re-creation
1150 uint32_t oldSequence = 0;
1151
1152 Proxy::Buffer buffer;
1153 status_t status = NO_ERROR;
1154
1155 static const int32_t kMaxTries = 5;
1156 int32_t tryCounter = kMaxTries;
1157
1158 do {
1159 // obtainBuffer() is called with mutex unlocked, so keep extra references to these fields to
1160 // keep them from going away if another thread re-creates the track during obtainBuffer()
1161 sp<AudioRecordClientProxy> proxy;
1162 sp<IMemory> iMem;
1163 sp<IMemory> bufferMem;
1164 {
1165 // start of lock scope
1166 AutoMutex lock(mLock);
1167
1168 // did previous obtainBuffer() fail due to media server death or voluntary invalidation?
1169 if (status == DEAD_OBJECT) {
1170 // re-create track, unless someone else has already done so
1171 if (mSequence == oldSequence) {
1172 if (!audio_is_linear_pcm(mFormat)) {
1173 // If compressed capture, don't attempt to restore the track.
1174 // Return a DEAD_OBJECT error and let the caller recreate.
1175 tryCounter = 0;
1176 } else {
1177 status = restoreRecord_l("obtainBuffer");
1178 }
1179 if (status != NO_ERROR) {
1180 buffer.mFrameCount = 0;
1181 buffer.mRaw = NULL;
1182 buffer.mNonContig = 0;
1183 break;
1184 }
1185 }
1186 }
1187 oldSequence = mSequence;
1188
1189 // Keep the extra references
1190 proxy = mProxy;
1191 iMem = mCblkMemory;
1192 bufferMem = mBufferMemory;
1193
1194 // Non-blocking if track is stopped
1195 if (!mActive) {
1196 requested = &ClientProxy::kNonBlocking;
1197 }
1198
1199 } // end of lock scope
1200
1201 buffer.mFrameCount = audioBuffer->frameCount;
1202 // FIXME starts the requested timeout and elapsed over from scratch
1203 status = proxy->obtainBuffer(&buffer, requested, elapsed);
1204
1205 } while ((status == DEAD_OBJECT) && (tryCounter-- > 0));
1206
1207 audioBuffer->frameCount = buffer.mFrameCount;
1208 audioBuffer->mSize = buffer.mFrameCount * mServerFrameSize;
1209 audioBuffer->raw = buffer.mRaw;
1210 audioBuffer->sequence = oldSequence;
1211 if (nonContig != NULL) {
1212 *nonContig = buffer.mNonContig;
1213 }
1214 return status;
1215 }
1216
releaseBuffer(const Buffer * audioBuffer)1217 void AudioRecord::releaseBuffer(const Buffer* audioBuffer)
1218 {
1219 // FIXME add error checking on mode, by adding an internal version
1220
1221 size_t stepCount = audioBuffer->frameCount;
1222 if (stepCount == 0) {
1223 return;
1224 }
1225
1226 Proxy::Buffer buffer;
1227 buffer.mFrameCount = stepCount;
1228 buffer.mRaw = audioBuffer->raw;
1229
1230 AutoMutex lock(mLock);
1231 if (audioBuffer->sequence != mSequence) {
1232 // This Buffer came from a different IAudioRecord instance, so ignore the releaseBuffer
1233 ALOGD("%s is no-op due to IAudioRecord sequence mismatch %u != %u",
1234 __func__, audioBuffer->sequence, mSequence);
1235 return;
1236 }
1237 mInOverrun = false;
1238 mProxy->releaseBuffer(&buffer);
1239
1240 // the server does not automatically disable recorder on overrun, so no need to restart
1241 }
1242
getInputPrivate() const1243 audio_io_handle_t AudioRecord::getInputPrivate() const
1244 {
1245 AutoMutex lock(mLock);
1246 return mInput;
1247 }
1248
1249 // -------------------------------------------------------------------------
1250
read(void * buffer,size_t userSize,bool blocking)1251 ssize_t AudioRecord::read(void* buffer, size_t userSize, bool blocking)
1252 {
1253 if (mTransfer != TRANSFER_SYNC) {
1254 return INVALID_OPERATION;
1255 }
1256
1257 if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) {
1258 // Validation. user is most-likely passing an error code, and it would
1259 // make the return value ambiguous (actualSize vs error).
1260 ALOGE("%s(%d) (buffer=%p, size=%zu (%zu)",
1261 __func__, mPortId, buffer, userSize, userSize);
1262 return BAD_VALUE;
1263 }
1264
1265 ssize_t read = 0;
1266 Buffer audioBuffer;
1267
1268 while (userSize >= mFrameSize) {
1269 audioBuffer.frameCount = userSize / mFrameSize;
1270
1271 status_t err = obtainBuffer(&audioBuffer,
1272 blocking ? &ClientProxy::kForever : &ClientProxy::kNonBlocking);
1273 if (err < 0) {
1274 if (read > 0) {
1275 break;
1276 }
1277 if (err == TIMED_OUT || err == -EINTR) {
1278 err = WOULD_BLOCK;
1279 }
1280 return ssize_t(err);
1281 }
1282
1283 size_t bytesRead = audioBuffer.frameCount * mFrameSize;
1284 if (audio_is_linear_pcm(mFormat)) {
1285 memcpy_by_audio_format(buffer, mFormat, audioBuffer.raw, mServerConfig.format,
1286 audioBuffer.mSize / mServerSampleSize);
1287 } else {
1288 memcpy(buffer, audioBuffer.raw, audioBuffer.mSize);
1289 }
1290 buffer = ((char *) buffer) + bytesRead;
1291 userSize -= bytesRead;
1292 read += bytesRead;
1293
1294 releaseBuffer(&audioBuffer);
1295 }
1296 if (read > 0) {
1297 mFramesRead += read / mFrameSize;
1298 // mFramesReadTime = systemTime(SYSTEM_TIME_MONOTONIC); // not provided at this time.
1299 }
1300 return read;
1301 }
1302
1303 // -------------------------------------------------------------------------
1304
processAudioBuffer()1305 nsecs_t AudioRecord::processAudioBuffer()
1306 {
1307 mLock.lock();
1308 const sp<IAudioRecordCallback> callback = mCallback.promote();
1309 if (!callback) {
1310 mCallback = nullptr;
1311 mLock.unlock();
1312 return NS_NEVER;
1313 }
1314 if (mAwaitBoost) {
1315 mAwaitBoost = false;
1316 mLock.unlock();
1317 static const int32_t kMaxTries = 5;
1318 int32_t tryCounter = kMaxTries;
1319 uint32_t pollUs = 10000;
1320 do {
1321 int policy = sched_getscheduler(0) & ~SCHED_RESET_ON_FORK;
1322 if (policy == SCHED_FIFO || policy == SCHED_RR) {
1323 break;
1324 }
1325 usleep(pollUs);
1326 pollUs <<= 1;
1327 } while (tryCounter-- > 0);
1328 if (tryCounter < 0) {
1329 ALOGE("%s(%d): did not receive expected priority boost on time", __func__, mPortId);
1330 }
1331 // Run again immediately
1332 return 0;
1333 }
1334
1335 // Can only reference mCblk while locked
1336 int32_t flags = android_atomic_and(~CBLK_OVERRUN, &mCblk->mFlags);
1337
1338 // Check for track invalidation
1339 if (flags & CBLK_INVALID) {
1340 (void) restoreRecord_l("processAudioBuffer");
1341 mLock.unlock();
1342 // Run again immediately, but with a new IAudioRecord
1343 return 0;
1344 }
1345
1346 bool active = mActive;
1347
1348 // Manage overrun callback, must be done under lock to avoid race with releaseBuffer()
1349 bool newOverrun = false;
1350 if (flags & CBLK_OVERRUN) {
1351 if (!mInOverrun) {
1352 mInOverrun = true;
1353 newOverrun = true;
1354 }
1355 }
1356
1357 // Get current position of server
1358 Modulo<uint32_t> position(mProxy->getPosition());
1359
1360 // Manage marker callback
1361 bool markerReached = false;
1362 Modulo<uint32_t> markerPosition(mMarkerPosition);
1363 // FIXME fails for wraparound, need 64 bits
1364 if (!mMarkerReached && markerPosition.value() > 0 && position >= markerPosition) {
1365 mMarkerReached = markerReached = true;
1366 }
1367
1368 // Determine the number of new position callback(s) that will be needed, while locked
1369 size_t newPosCount = 0;
1370 Modulo<uint32_t> newPosition(mNewPosition);
1371 uint32_t updatePeriod = mUpdatePeriod;
1372 // FIXME fails for wraparound, need 64 bits
1373 if (updatePeriod > 0 && position >= newPosition) {
1374 newPosCount = ((position - newPosition).value() / updatePeriod) + 1;
1375 mNewPosition += updatePeriod * newPosCount;
1376 }
1377
1378 // Cache other fields that will be needed soon
1379 uint32_t notificationFrames = mNotificationFramesAct;
1380 if (mRefreshRemaining) {
1381 mRefreshRemaining = false;
1382 mRemainingFrames = notificationFrames;
1383 mRetryOnPartialBuffer = false;
1384 }
1385 size_t misalignment = mProxy->getMisalignment();
1386 uint32_t sequence = mSequence;
1387
1388 // These fields don't need to be cached, because they are assigned only by set():
1389 // mTransfer, mCallback, mUserData, mSampleRate, mFrameSize
1390
1391 mLock.unlock();
1392
1393 // perform callbacks while unlocked
1394 if (newOverrun) {
1395 callback->onOverrun();
1396
1397 }
1398 if (markerReached) {
1399 callback->onMarker(markerPosition.value());
1400 }
1401 while (newPosCount > 0) {
1402 callback->onNewPos(newPosition.value());
1403 newPosition += updatePeriod;
1404 newPosCount--;
1405 }
1406 if (mObservedSequence != sequence) {
1407 mObservedSequence = sequence;
1408 callback->onNewIAudioRecord();
1409 }
1410
1411 // if inactive, then don't run me again until re-started
1412 if (!active) {
1413 return NS_INACTIVE;
1414 }
1415
1416 // Compute the estimated time until the next timed event (position, markers)
1417 uint32_t minFrames = ~0;
1418 if (!markerReached && position < markerPosition) {
1419 minFrames = (markerPosition - position).value();
1420 }
1421 if (updatePeriod > 0) {
1422 uint32_t remaining = (newPosition - position).value();
1423 if (remaining < minFrames) {
1424 minFrames = remaining;
1425 }
1426 }
1427
1428 // If > 0, poll periodically to recover from a stuck server. A good value is 2.
1429 static const uint32_t kPoll = 0;
1430 if (kPoll > 0 && mTransfer == TRANSFER_CALLBACK && kPoll * notificationFrames < minFrames) {
1431 minFrames = kPoll * notificationFrames;
1432 }
1433
1434 // Convert frame units to time units
1435 nsecs_t ns = NS_WHENEVER;
1436 if (minFrames != (uint32_t) ~0) {
1437 // This "fudge factor" avoids soaking CPU, and compensates for late progress by server
1438 static const nsecs_t kFudgeNs = 10000000LL; // 10 ms
1439 ns = ((minFrames * 1000000000LL) / mSampleRate) + kFudgeNs;
1440 }
1441
1442 // If not supplying data by EVENT_MORE_DATA, then we're done
1443 if (mTransfer != TRANSFER_CALLBACK) {
1444 return ns;
1445 }
1446
1447 struct timespec timeout;
1448 const struct timespec *requested = &ClientProxy::kForever;
1449 if (ns != NS_WHENEVER) {
1450 timeout.tv_sec = ns / 1000000000LL;
1451 timeout.tv_nsec = ns % 1000000000LL;
1452 ALOGV("%s(%d): timeout %ld.%03d",
1453 __func__, mPortId, timeout.tv_sec, (int) timeout.tv_nsec / 1000000);
1454 requested = &timeout;
1455 }
1456
1457 size_t readFrames = 0;
1458 while (mRemainingFrames > 0) {
1459
1460 Buffer audioBuffer;
1461 audioBuffer.frameCount = mRemainingFrames;
1462 size_t nonContig;
1463 status_t err = obtainBuffer(&audioBuffer, requested, NULL, &nonContig);
1464 LOG_ALWAYS_FATAL_IF((err != NO_ERROR) != (audioBuffer.frameCount == 0),
1465 "%s(%d): obtainBuffer() err=%d frameCount=%zu",
1466 __func__, mPortId, err, audioBuffer.frameCount);
1467 requested = &ClientProxy::kNonBlocking;
1468 size_t avail = audioBuffer.frameCount + nonContig;
1469 ALOGV("%s(%d): obtainBuffer(%u) returned %zu = %zu + %zu err %d",
1470 __func__, mPortId, mRemainingFrames, avail, audioBuffer.frameCount, nonContig, err);
1471 if (err != NO_ERROR) {
1472 if (err == TIMED_OUT || err == WOULD_BLOCK || err == -EINTR) {
1473 break;
1474 }
1475 ALOGE("%s(%d): Error %d obtaining an audio buffer, giving up.",
1476 __func__, mPortId, err);
1477 return NS_NEVER;
1478 }
1479
1480 if (mRetryOnPartialBuffer) {
1481 mRetryOnPartialBuffer = false;
1482 if (avail < mRemainingFrames) {
1483 int64_t myns = ((mRemainingFrames - avail) *
1484 1100000000LL) / mSampleRate;
1485 if (ns < 0 || myns < ns) {
1486 ns = myns;
1487 }
1488 return ns;
1489 }
1490 }
1491
1492 Buffer* buffer = &audioBuffer;
1493 if (mServerConfig.format != mFormat) {
1494 buffer = &mFormatConversionBuffer;
1495 buffer->frameCount = audioBuffer.frameCount;
1496 buffer->mSize = buffer->frameCount * mFrameSize;
1497 buffer->sequence = audioBuffer.sequence;
1498 memcpy_by_audio_format(buffer->raw, mFormat, audioBuffer.raw,
1499 mServerConfig.format, audioBuffer.size() / mServerSampleSize);
1500 }
1501
1502 const size_t reqSize = buffer->size();
1503 const size_t readSize = callback->onMoreData(*buffer);
1504 buffer->mSize = readSize;
1505
1506 // Validate on returned size
1507 if (ssize_t(readSize) < 0 || readSize > reqSize) {
1508 ALOGE("%s(%d): EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes",
1509 __func__, mPortId, reqSize, ssize_t(readSize));
1510 return NS_NEVER;
1511 }
1512
1513 if (readSize == 0) {
1514 // The callback is done consuming buffers
1515 // Keep this thread going to handle timed events and
1516 // still try to provide more data in intervals of WAIT_PERIOD_MS
1517 // but don't just loop and block the CPU, so wait
1518 return WAIT_PERIOD_MS * 1000000LL;
1519 }
1520
1521 size_t releasedFrames = readSize / mFrameSize;
1522 audioBuffer.frameCount = releasedFrames;
1523 mRemainingFrames -= releasedFrames;
1524 if (misalignment >= releasedFrames) {
1525 misalignment -= releasedFrames;
1526 } else {
1527 misalignment = 0;
1528 }
1529
1530 releaseBuffer(&audioBuffer);
1531 readFrames += releasedFrames;
1532
1533 // FIXME here is where we would repeat EVENT_MORE_DATA again on same advanced buffer
1534 // if callback doesn't like to accept the full chunk
1535 if (readSize < reqSize) {
1536 continue;
1537 }
1538
1539 // There could be enough non-contiguous frames available to satisfy the remaining request
1540 if (mRemainingFrames <= nonContig) {
1541 continue;
1542 }
1543
1544 #if 0
1545 // This heuristic tries to collapse a series of EVENT_MORE_DATA that would total to a
1546 // sum <= notificationFrames. It replaces that series by at most two EVENT_MORE_DATA
1547 // that total to a sum == notificationFrames.
1548 if (0 < misalignment && misalignment <= mRemainingFrames) {
1549 mRemainingFrames = misalignment;
1550 return (mRemainingFrames * 1100000000LL) / mSampleRate;
1551 }
1552 #endif
1553
1554 }
1555 if (readFrames > 0) {
1556 AutoMutex lock(mLock);
1557 mFramesRead += readFrames;
1558 // mFramesReadTime = systemTime(SYSTEM_TIME_MONOTONIC); // not provided at this time.
1559 }
1560 mRemainingFrames = notificationFrames;
1561 mRetryOnPartialBuffer = true;
1562
1563 // A lot has transpired since ns was calculated, so run again immediately and re-calculate
1564 return 0;
1565 }
1566
restoreRecord_l(const char * from)1567 status_t AudioRecord::restoreRecord_l(const char *from)
1568 {
1569 status_t result = NO_ERROR; // logged: make sure to set this before returning.
1570 const int64_t beginNs = systemTime();
1571 mediametrics::Defer defer([&] {
1572 mediametrics::LogItem(mMetricsId)
1573 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_RESTORE)
1574 .set(AMEDIAMETRICS_PROP_EXECUTIONTIMENS, (int64_t)(systemTime() - beginNs))
1575 .set(AMEDIAMETRICS_PROP_STATE, stateToString(mActive))
1576 .set(AMEDIAMETRICS_PROP_STATUS, (int32_t)result)
1577 .set(AMEDIAMETRICS_PROP_WHERE, from)
1578 .record(); });
1579
1580 ALOGW("%s(%d) called from %s()", __func__, mPortId, from);
1581 ++mSequence;
1582
1583 const int INITIAL_RETRIES = 3;
1584 int retries = INITIAL_RETRIES;
1585 retry:
1586 mFlags = mOrigFlags;
1587
1588 // if the new IAudioRecord is created, createRecord_l() will modify the
1589 // following member variables: mAudioRecord, mCblkMemory, mCblk, mBufferMemory.
1590 // It will also delete the strong references on previous IAudioRecord and IMemory
1591 Modulo<uint32_t> position(mProxy->getPosition());
1592 mNewPosition = position + mUpdatePeriod;
1593 result = createRecord_l(position);
1594
1595 if (result == NO_ERROR) {
1596 if (mActive) {
1597 // callback thread or sync event hasn't changed
1598 // FIXME this fails if we have a new AudioFlinger instance
1599 result = statusTFromBinderStatus(mAudioRecord->start(
1600 AudioSystem::SYNC_EVENT_SAME, AUDIO_SESSION_NONE));
1601 }
1602 mFramesReadServerOffset = mFramesRead; // server resets to zero so we need an offset.
1603 }
1604
1605 if (result != NO_ERROR) {
1606 ALOGW("%s(%d): failed status %d, retries %d", __func__, mPortId, result, retries);
1607 if (--retries > 0) {
1608 // leave time for an eventual race condition to clear before retrying
1609 usleep(500000);
1610 goto retry;
1611 }
1612 // if no retries left, set invalid bit to force restoring at next occasion
1613 // and avoid inconsistent active state on client and server sides
1614 if (mCblk != nullptr) {
1615 android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
1616 }
1617 }
1618
1619 return result;
1620 }
1621
addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback> & callback)1622 status_t AudioRecord::addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback)
1623 {
1624 if (callback == 0) {
1625 ALOGW("%s(%d): adding NULL callback!", __func__, mPortId);
1626 return BAD_VALUE;
1627 }
1628 AutoMutex lock(mLock);
1629 if (mDeviceCallback.unsafe_get() == callback.get()) {
1630 ALOGW("%s(%d): adding same callback!", __func__, mPortId);
1631 return INVALID_OPERATION;
1632 }
1633 status_t status = NO_ERROR;
1634 if (mInput != AUDIO_IO_HANDLE_NONE) {
1635 if (mDeviceCallback != 0) {
1636 ALOGW("%s(%d): callback already present!", __func__, mPortId);
1637 AudioSystem::removeAudioDeviceCallback(this, mInput, mPortId);
1638 }
1639 status = AudioSystem::addAudioDeviceCallback(this, mInput, mPortId);
1640 }
1641 mDeviceCallback = callback;
1642 return status;
1643 }
1644
removeAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback> & callback)1645 status_t AudioRecord::removeAudioDeviceCallback(
1646 const sp<AudioSystem::AudioDeviceCallback>& callback)
1647 {
1648 if (callback == 0) {
1649 ALOGW("%s(%d): removing NULL callback!", __func__, mPortId);
1650 return BAD_VALUE;
1651 }
1652 AutoMutex lock(mLock);
1653 if (mDeviceCallback.unsafe_get() != callback.get()) {
1654 ALOGW("%s(%d): removing different callback!", __func__, mPortId);
1655 return INVALID_OPERATION;
1656 }
1657 mDeviceCallback.clear();
1658 if (mInput != AUDIO_IO_HANDLE_NONE) {
1659 AudioSystem::removeAudioDeviceCallback(this, mInput, mPortId);
1660 }
1661 return NO_ERROR;
1662 }
1663
onAudioDeviceUpdate(audio_io_handle_t audioIo,const DeviceIdVector & deviceIds)1664 void AudioRecord::onAudioDeviceUpdate(audio_io_handle_t audioIo,
1665 const DeviceIdVector& deviceIds)
1666 {
1667 sp<AudioSystem::AudioDeviceCallback> callback;
1668 {
1669 AutoMutex lock(mLock);
1670 if (audioIo != mInput) {
1671 return;
1672 }
1673 callback = mDeviceCallback.promote();
1674 // only update device if the record is active as route changes due to other use cases are
1675 // irrelevant for this client
1676 if (mActive) {
1677 mRoutedDeviceIds = deviceIds;
1678 }
1679 }
1680 if (callback.get() != nullptr) {
1681 callback->onAudioDeviceUpdate(mInput, mRoutedDeviceIds);
1682 }
1683 }
1684
1685 // -------------------------------------------------------------------------
1686
getActiveMicrophones(std::vector<media::MicrophoneInfoFw> * activeMicrophones)1687 status_t AudioRecord::getActiveMicrophones(std::vector<media::MicrophoneInfoFw>* activeMicrophones)
1688 {
1689 AutoMutex lock(mLock);
1690 return statusTFromBinderStatus(mAudioRecord->getActiveMicrophones(activeMicrophones));
1691 }
1692
setPreferredMicrophoneDirection(audio_microphone_direction_t direction)1693 status_t AudioRecord::setPreferredMicrophoneDirection(audio_microphone_direction_t direction)
1694 {
1695 AutoMutex lock(mLock);
1696 if (mSelectedMicDirection == direction) {
1697 // NOP
1698 return OK;
1699 }
1700
1701 mSelectedMicDirection = direction;
1702 if (mAudioRecord == 0) {
1703 // the internal AudioRecord hasn't be created yet, so just stash the attribute.
1704 return OK;
1705 } else {
1706 return statusTFromBinderStatus(mAudioRecord->setPreferredMicrophoneDirection(direction));
1707 }
1708 }
1709
setPreferredMicrophoneFieldDimension(float zoom)1710 status_t AudioRecord::setPreferredMicrophoneFieldDimension(float zoom) {
1711 AutoMutex lock(mLock);
1712 if (mSelectedMicFieldDimension == zoom) {
1713 // NOP
1714 return OK;
1715 }
1716
1717 mSelectedMicFieldDimension = zoom;
1718 if (mAudioRecord == 0) {
1719 // the internal AudioRecord hasn't be created yet, so just stash the attribute.
1720 return OK;
1721 } else {
1722 return statusTFromBinderStatus(mAudioRecord->setPreferredMicrophoneFieldDimension(zoom));
1723 }
1724 }
1725
setLogSessionId(const char * logSessionId)1726 void AudioRecord::setLogSessionId(const char *logSessionId)
1727 {
1728 AutoMutex lock(mLock);
1729 if (logSessionId == nullptr) logSessionId = ""; // an empty string is an unset session id.
1730 if (mLogSessionId == logSessionId) return;
1731
1732 mLogSessionId = logSessionId;
1733 mediametrics::LogItem(mMetricsId)
1734 .set(AMEDIAMETRICS_PROP_EVENT, AMEDIAMETRICS_PROP_EVENT_VALUE_SETLOGSESSIONID)
1735 .set(AMEDIAMETRICS_PROP_LOGSESSIONID, logSessionId)
1736 .record();
1737 }
1738
shareAudioHistory(const std::string & sharedPackageName,int64_t sharedStartMs)1739 status_t AudioRecord::shareAudioHistory(const std::string& sharedPackageName,
1740 int64_t sharedStartMs)
1741 {
1742 AutoMutex lock(mLock);
1743 if (mAudioRecord == 0) {
1744 return NO_INIT;
1745 }
1746 status_t status = statusTFromBinderStatus(
1747 mAudioRecord->shareAudioHistory(sharedPackageName, sharedStartMs));
1748 if (status == NO_ERROR) {
1749 mSharedAudioPackageName = sharedPackageName;
1750 mSharedAudioStartMs = sharedStartMs;
1751 }
1752 return status;
1753 }
1754
1755 // =========================================================================
1756
binderDied(const wp<IBinder> & who __unused)1757 void AudioRecord::DeathNotifier::binderDied(const wp<IBinder>& who __unused)
1758 {
1759 sp<AudioRecord> audioRecord = mAudioRecord.promote();
1760 if (audioRecord != 0) {
1761 AutoMutex lock(audioRecord->mLock);
1762 audioRecord->mProxy->binderDied();
1763 }
1764 }
1765
1766 // =========================================================================
1767
AudioRecordThread(AudioRecord & receiver)1768 AudioRecord::AudioRecordThread::AudioRecordThread(AudioRecord& receiver)
1769 : Thread(true /* bCanCallJava */) // binder recursion on restoreRecord_l() may call Java.
1770 , mReceiver(receiver), mPaused(true), mPausedInt(false), mPausedNs(0LL),
1771 mIgnoreNextPausedInt(false)
1772 {
1773 }
1774
~AudioRecordThread()1775 AudioRecord::AudioRecordThread::~AudioRecordThread()
1776 {
1777 }
1778
threadLoop()1779 bool AudioRecord::AudioRecordThread::threadLoop()
1780 {
1781 {
1782 AutoMutex _l(mMyLock);
1783 if (mPaused) {
1784 // TODO check return value and handle or log
1785 mMyCond.wait(mMyLock);
1786 // caller will check for exitPending()
1787 return true;
1788 }
1789 if (mIgnoreNextPausedInt) {
1790 mIgnoreNextPausedInt = false;
1791 mPausedInt = false;
1792 }
1793 if (mPausedInt) {
1794 if (mPausedNs > 0) {
1795 // TODO check return value and handle or log
1796 (void) mMyCond.waitRelative(mMyLock, mPausedNs);
1797 } else {
1798 // TODO check return value and handle or log
1799 mMyCond.wait(mMyLock);
1800 }
1801 mPausedInt = false;
1802 return true;
1803 }
1804 }
1805 if (exitPending()) {
1806 return false;
1807 }
1808 nsecs_t ns = mReceiver.processAudioBuffer();
1809 switch (ns) {
1810 case 0:
1811 return true;
1812 case NS_INACTIVE:
1813 pauseInternal();
1814 return true;
1815 case NS_NEVER:
1816 return false;
1817 case NS_WHENEVER:
1818 // Event driven: call wake() when callback notifications conditions change.
1819 ns = INT64_MAX;
1820 FALLTHROUGH_INTENDED;
1821 default:
1822 LOG_ALWAYS_FATAL_IF(ns < 0, "%s() returned %lld", __func__, (long long)ns);
1823 pauseInternal(ns);
1824 return true;
1825 }
1826 }
1827
requestExit()1828 void AudioRecord::AudioRecordThread::requestExit()
1829 {
1830 // must be in this order to avoid a race condition
1831 Thread::requestExit();
1832 resume();
1833 }
1834
pause()1835 void AudioRecord::AudioRecordThread::pause()
1836 {
1837 AutoMutex _l(mMyLock);
1838 mPaused = true;
1839 }
1840
resume()1841 void AudioRecord::AudioRecordThread::resume()
1842 {
1843 AutoMutex _l(mMyLock);
1844 mIgnoreNextPausedInt = true;
1845 if (mPaused || mPausedInt) {
1846 mPaused = false;
1847 mPausedInt = false;
1848 mMyCond.signal();
1849 }
1850 }
1851
wake()1852 void AudioRecord::AudioRecordThread::wake()
1853 {
1854 AutoMutex _l(mMyLock);
1855 if (!mPaused) {
1856 // wake() might be called while servicing a callback - ignore the next
1857 // pause time and call processAudioBuffer.
1858 mIgnoreNextPausedInt = true;
1859 if (mPausedInt && mPausedNs > 0) {
1860 // audio record is active and internally paused with timeout.
1861 mPausedInt = false;
1862 mMyCond.signal();
1863 }
1864 }
1865 }
1866
pauseInternal(nsecs_t ns)1867 void AudioRecord::AudioRecordThread::pauseInternal(nsecs_t ns)
1868 {
1869 AutoMutex _l(mMyLock);
1870 mPausedInt = true;
1871 mPausedNs = ns;
1872 }
1873
1874 // -------------------------------------------------------------------------
1875
1876 } // namespace android
1877