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