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