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