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 <sys/resource.h>
23
24 #include <binder/IPCThreadState.h>
25 #include <media/AudioRecord.h>
26 #include <utils/Log.h>
27 #include <private/media/AudioTrackShared.h>
28 #include <media/IAudioFlinger.h>
29
30 #define WAIT_PERIOD_MS 10
31
32 namespace android {
33 // ---------------------------------------------------------------------------
34
35 // static
getMinFrameCount(size_t * frameCount,uint32_t sampleRate,audio_format_t format,audio_channel_mask_t channelMask)36 status_t AudioRecord::getMinFrameCount(
37 size_t* frameCount,
38 uint32_t sampleRate,
39 audio_format_t format,
40 audio_channel_mask_t channelMask)
41 {
42 if (frameCount == NULL) {
43 return BAD_VALUE;
44 }
45
46 size_t size;
47 status_t status = AudioSystem::getInputBufferSize(sampleRate, format, channelMask, &size);
48 if (status != NO_ERROR) {
49 ALOGE("AudioSystem could not query the input buffer size for sampleRate %u, format %#x, "
50 "channelMask %#x; status %d", sampleRate, format, channelMask, status);
51 return status;
52 }
53
54 // We double the size of input buffer for ping pong use of record buffer.
55 // Assumes audio_is_linear_pcm(format)
56 if ((*frameCount = (size * 2) / (audio_channel_count_from_in_mask(channelMask) *
57 audio_bytes_per_sample(format))) == 0) {
58 ALOGE("Unsupported configuration: sampleRate %u, format %#x, channelMask %#x",
59 sampleRate, format, channelMask);
60 return BAD_VALUE;
61 }
62
63 return NO_ERROR;
64 }
65
66 // ---------------------------------------------------------------------------
67
AudioRecord(const String16 & opPackageName)68 AudioRecord::AudioRecord(const String16 &opPackageName)
69 : mActive(false), mStatus(NO_INIT), mOpPackageName(opPackageName), mSessionId(AUDIO_SESSION_ALLOCATE),
70 mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT),
71 mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE)
72 {
73 }
74
AudioRecord(audio_source_t inputSource,uint32_t sampleRate,audio_format_t format,audio_channel_mask_t channelMask,const String16 & opPackageName,size_t frameCount,callback_t cbf,void * user,uint32_t notificationFrames,audio_session_t sessionId,transfer_type transferType,audio_input_flags_t flags,int uid,pid_t pid,const audio_attributes_t * pAttributes)75 AudioRecord::AudioRecord(
76 audio_source_t inputSource,
77 uint32_t sampleRate,
78 audio_format_t format,
79 audio_channel_mask_t channelMask,
80 const String16& opPackageName,
81 size_t frameCount,
82 callback_t cbf,
83 void* user,
84 uint32_t notificationFrames,
85 audio_session_t sessionId,
86 transfer_type transferType,
87 audio_input_flags_t flags,
88 int uid,
89 pid_t pid,
90 const audio_attributes_t* pAttributes)
91 : mActive(false),
92 mStatus(NO_INIT),
93 mOpPackageName(opPackageName),
94 mSessionId(AUDIO_SESSION_ALLOCATE),
95 mPreviousPriority(ANDROID_PRIORITY_NORMAL),
96 mPreviousSchedulingGroup(SP_DEFAULT),
97 mProxy(NULL),
98 mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE)
99 {
100 mStatus = set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user,
101 notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags,
102 uid, pid, pAttributes);
103 }
104
~AudioRecord()105 AudioRecord::~AudioRecord()
106 {
107 if (mStatus == NO_ERROR) {
108 // Make sure that callback function exits in the case where
109 // it is looping on buffer empty condition in obtainBuffer().
110 // Otherwise the callback thread will never exit.
111 stop();
112 if (mAudioRecordThread != 0) {
113 mProxy->interrupt();
114 mAudioRecordThread->requestExit(); // see comment in AudioRecord.h
115 mAudioRecordThread->requestExitAndWait();
116 mAudioRecordThread.clear();
117 }
118 // No lock here: worst case we remove a NULL callback which will be a nop
119 if (mDeviceCallback != 0 && mInput != AUDIO_IO_HANDLE_NONE) {
120 AudioSystem::removeAudioDeviceCallback(mDeviceCallback, mInput);
121 }
122 IInterface::asBinder(mAudioRecord)->unlinkToDeath(mDeathNotifier, this);
123 mAudioRecord.clear();
124 mCblkMemory.clear();
125 mBufferMemory.clear();
126 IPCThreadState::self()->flushCommands();
127 ALOGV("~AudioRecord, releasing session id %d",
128 mSessionId);
129 AudioSystem::releaseAudioSessionId(mSessionId, -1 /*pid*/);
130 }
131 }
132
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,int uid,pid_t pid,const audio_attributes_t * pAttributes)133 status_t AudioRecord::set(
134 audio_source_t inputSource,
135 uint32_t sampleRate,
136 audio_format_t format,
137 audio_channel_mask_t channelMask,
138 size_t frameCount,
139 callback_t cbf,
140 void* user,
141 uint32_t notificationFrames,
142 bool threadCanCallJava,
143 audio_session_t sessionId,
144 transfer_type transferType,
145 audio_input_flags_t flags,
146 int uid,
147 pid_t pid,
148 const audio_attributes_t* pAttributes)
149 {
150 ALOGV("set(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
151 "notificationFrames %u, sessionId %d, transferType %d, flags %#x, opPackageName %s "
152 "uid %d, pid %d",
153 inputSource, sampleRate, format, channelMask, frameCount, notificationFrames,
154 sessionId, transferType, flags, String8(mOpPackageName).string(), uid, pid);
155
156 switch (transferType) {
157 case TRANSFER_DEFAULT:
158 if (cbf == NULL || threadCanCallJava) {
159 transferType = TRANSFER_SYNC;
160 } else {
161 transferType = TRANSFER_CALLBACK;
162 }
163 break;
164 case TRANSFER_CALLBACK:
165 if (cbf == NULL) {
166 ALOGE("Transfer type TRANSFER_CALLBACK but cbf == NULL");
167 return BAD_VALUE;
168 }
169 break;
170 case TRANSFER_OBTAIN:
171 case TRANSFER_SYNC:
172 break;
173 default:
174 ALOGE("Invalid transfer type %d", transferType);
175 return BAD_VALUE;
176 }
177 mTransfer = transferType;
178
179 // invariant that mAudioRecord != 0 is true only after set() returns successfully
180 if (mAudioRecord != 0) {
181 ALOGE("Track already in use");
182 return INVALID_OPERATION;
183 }
184
185 if (pAttributes == NULL) {
186 memset(&mAttributes, 0, sizeof(audio_attributes_t));
187 mAttributes.source = inputSource;
188 } else {
189 // stream type shouldn't be looked at, this track has audio attributes
190 memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t));
191 ALOGV("Building AudioRecord with attributes: source=%d flags=0x%x tags=[%s]",
192 mAttributes.source, mAttributes.flags, mAttributes.tags);
193 }
194
195 mSampleRate = sampleRate;
196
197 // these below should probably come from the audioFlinger too...
198 if (format == AUDIO_FORMAT_DEFAULT) {
199 format = AUDIO_FORMAT_PCM_16_BIT;
200 }
201
202 // validate parameters
203 // AudioFlinger capture only supports linear PCM
204 if (!audio_is_valid_format(format) || !audio_is_linear_pcm(format)) {
205 ALOGE("Format %#x is not linear pcm", format);
206 return BAD_VALUE;
207 }
208 mFormat = format;
209
210 if (!audio_is_input_channel(channelMask)) {
211 ALOGE("Invalid channel mask %#x", channelMask);
212 return BAD_VALUE;
213 }
214 mChannelMask = channelMask;
215 uint32_t channelCount = audio_channel_count_from_in_mask(channelMask);
216 mChannelCount = channelCount;
217
218 if (audio_is_linear_pcm(format)) {
219 mFrameSize = channelCount * audio_bytes_per_sample(format);
220 } else {
221 mFrameSize = sizeof(uint8_t);
222 }
223
224 // mFrameCount is initialized in openRecord_l
225 mReqFrameCount = frameCount;
226
227 mNotificationFramesReq = notificationFrames;
228 // mNotificationFramesAct is initialized in openRecord_l
229
230 if (sessionId == AUDIO_SESSION_ALLOCATE) {
231 mSessionId = (audio_session_t) AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
232 } else {
233 mSessionId = sessionId;
234 }
235 ALOGV("set(): mSessionId %d", mSessionId);
236
237 int callingpid = IPCThreadState::self()->getCallingPid();
238 int mypid = getpid();
239 if (uid == -1 || (callingpid != mypid)) {
240 mClientUid = IPCThreadState::self()->getCallingUid();
241 } else {
242 mClientUid = uid;
243 }
244 if (pid == -1 || (callingpid != mypid)) {
245 mClientPid = callingpid;
246 } else {
247 mClientPid = pid;
248 }
249
250 mOrigFlags = mFlags = flags;
251 mCbf = cbf;
252
253 if (cbf != NULL) {
254 mAudioRecordThread = new AudioRecordThread(*this, threadCanCallJava);
255 mAudioRecordThread->run("AudioRecord", ANDROID_PRIORITY_AUDIO);
256 // thread begins in paused state, and will not reference us until start()
257 }
258
259 // create the IAudioRecord
260 status_t status = openRecord_l(0 /*epoch*/, mOpPackageName);
261
262 if (status != NO_ERROR) {
263 if (mAudioRecordThread != 0) {
264 mAudioRecordThread->requestExit(); // see comment in AudioRecord.h
265 mAudioRecordThread->requestExitAndWait();
266 mAudioRecordThread.clear();
267 }
268 return status;
269 }
270
271 mStatus = NO_ERROR;
272 mUserData = user;
273 // TODO: add audio hardware input latency here
274 mLatency = (1000 * mFrameCount) / mSampleRate;
275 mMarkerPosition = 0;
276 mMarkerReached = false;
277 mNewPosition = 0;
278 mUpdatePeriod = 0;
279 AudioSystem::acquireAudioSessionId(mSessionId, -1);
280 mSequence = 1;
281 mObservedSequence = mSequence;
282 mInOverrun = false;
283 mFramesRead = 0;
284 mFramesReadServerOffset = 0;
285
286 return NO_ERROR;
287 }
288
289 // -------------------------------------------------------------------------
290
start(AudioSystem::sync_event_t event,audio_session_t triggerSession)291 status_t AudioRecord::start(AudioSystem::sync_event_t event, audio_session_t triggerSession)
292 {
293 ALOGV("start, sync event %d trigger session %d", event, triggerSession);
294
295 AutoMutex lock(mLock);
296 if (mActive) {
297 return NO_ERROR;
298 }
299
300 // discard data in buffer
301 const uint32_t framesFlushed = mProxy->flush();
302 mFramesReadServerOffset -= mFramesRead + framesFlushed;
303 mFramesRead = 0;
304 mProxy->clearTimestamp(); // timestamp is invalid until next server push
305
306 // reset current position as seen by client to 0
307 mProxy->setEpoch(mProxy->getEpoch() - mProxy->getPosition());
308 // force refresh of remaining frames by processAudioBuffer() as last
309 // read before stop could be partial.
310 mRefreshRemaining = true;
311
312 mNewPosition = mProxy->getPosition() + mUpdatePeriod;
313 int32_t flags = android_atomic_acquire_load(&mCblk->mFlags);
314
315 // we reactivate markers (mMarkerPosition != 0) as the position is reset to 0.
316 // This is legacy behavior. This is not done in stop() to avoid a race condition
317 // where the last marker event is issued twice.
318 mMarkerReached = false;
319 mActive = true;
320
321 status_t status = NO_ERROR;
322 if (!(flags & CBLK_INVALID)) {
323 status = mAudioRecord->start(event, triggerSession);
324 if (status == DEAD_OBJECT) {
325 flags |= CBLK_INVALID;
326 }
327 }
328 if (flags & CBLK_INVALID) {
329 status = restoreRecord_l("start");
330 }
331
332 if (status != NO_ERROR) {
333 mActive = false;
334 ALOGE("start() status %d", status);
335 } else {
336 sp<AudioRecordThread> t = mAudioRecordThread;
337 if (t != 0) {
338 t->resume();
339 } else {
340 mPreviousPriority = getpriority(PRIO_PROCESS, 0);
341 get_sched_policy(0, &mPreviousSchedulingGroup);
342 androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO);
343 }
344 }
345
346 return status;
347 }
348
stop()349 void AudioRecord::stop()
350 {
351 AutoMutex lock(mLock);
352 if (!mActive) {
353 return;
354 }
355
356 mActive = false;
357 mProxy->interrupt();
358 mAudioRecord->stop();
359
360 // Note: legacy handling - stop does not clear record marker and
361 // periodic update position; we update those on start().
362
363 sp<AudioRecordThread> t = mAudioRecordThread;
364 if (t != 0) {
365 t->pause();
366 } else {
367 setpriority(PRIO_PROCESS, 0, mPreviousPriority);
368 set_sched_policy(0, mPreviousSchedulingGroup);
369 }
370 }
371
stopped() const372 bool AudioRecord::stopped() const
373 {
374 AutoMutex lock(mLock);
375 return !mActive;
376 }
377
setMarkerPosition(uint32_t marker)378 status_t AudioRecord::setMarkerPosition(uint32_t marker)
379 {
380 // The only purpose of setting marker position is to get a callback
381 if (mCbf == NULL) {
382 return INVALID_OPERATION;
383 }
384
385 AutoMutex lock(mLock);
386 mMarkerPosition = marker;
387 mMarkerReached = false;
388
389 sp<AudioRecordThread> t = mAudioRecordThread;
390 if (t != 0) {
391 t->wake();
392 }
393 return NO_ERROR;
394 }
395
getMarkerPosition(uint32_t * marker) const396 status_t AudioRecord::getMarkerPosition(uint32_t *marker) const
397 {
398 if (marker == NULL) {
399 return BAD_VALUE;
400 }
401
402 AutoMutex lock(mLock);
403 mMarkerPosition.getValue(marker);
404
405 return NO_ERROR;
406 }
407
setPositionUpdatePeriod(uint32_t updatePeriod)408 status_t AudioRecord::setPositionUpdatePeriod(uint32_t updatePeriod)
409 {
410 // The only purpose of setting position update period is to get a callback
411 if (mCbf == NULL) {
412 return INVALID_OPERATION;
413 }
414
415 AutoMutex lock(mLock);
416 mNewPosition = mProxy->getPosition() + updatePeriod;
417 mUpdatePeriod = updatePeriod;
418
419 sp<AudioRecordThread> t = mAudioRecordThread;
420 if (t != 0) {
421 t->wake();
422 }
423 return NO_ERROR;
424 }
425
getPositionUpdatePeriod(uint32_t * updatePeriod) const426 status_t AudioRecord::getPositionUpdatePeriod(uint32_t *updatePeriod) const
427 {
428 if (updatePeriod == NULL) {
429 return BAD_VALUE;
430 }
431
432 AutoMutex lock(mLock);
433 *updatePeriod = mUpdatePeriod;
434
435 return NO_ERROR;
436 }
437
getPosition(uint32_t * position) const438 status_t AudioRecord::getPosition(uint32_t *position) const
439 {
440 if (position == NULL) {
441 return BAD_VALUE;
442 }
443
444 AutoMutex lock(mLock);
445 mProxy->getPosition().getValue(position);
446
447 return NO_ERROR;
448 }
449
getInputFramesLost() const450 uint32_t AudioRecord::getInputFramesLost() const
451 {
452 // no need to check mActive, because if inactive this will return 0, which is what we want
453 return AudioSystem::getInputFramesLost(getInputPrivate());
454 }
455
getTimestamp(ExtendedTimestamp * timestamp)456 status_t AudioRecord::getTimestamp(ExtendedTimestamp *timestamp)
457 {
458 if (timestamp == nullptr) {
459 return BAD_VALUE;
460 }
461 AutoMutex lock(mLock);
462 status_t status = mProxy->getTimestamp(timestamp);
463 if (status == OK) {
464 timestamp->mPosition[ExtendedTimestamp::LOCATION_CLIENT] = mFramesRead;
465 timestamp->mTimeNs[ExtendedTimestamp::LOCATION_CLIENT] = 0;
466 // server side frame offset in case AudioRecord has been restored.
467 for (int i = ExtendedTimestamp::LOCATION_SERVER;
468 i < ExtendedTimestamp::LOCATION_MAX; ++i) {
469 if (timestamp->mTimeNs[i] >= 0) {
470 timestamp->mPosition[i] += mFramesReadServerOffset;
471 }
472 }
473 }
474 return status;
475 }
476
477 // ---- Explicit Routing ---------------------------------------------------
setInputDevice(audio_port_handle_t deviceId)478 status_t AudioRecord::setInputDevice(audio_port_handle_t deviceId) {
479 AutoMutex lock(mLock);
480 if (mSelectedDeviceId != deviceId) {
481 mSelectedDeviceId = deviceId;
482 // stop capture so that audio policy manager does not reject the new instance start request
483 // as only one capture can be active at a time.
484 if (mAudioRecord != 0 && mActive) {
485 mAudioRecord->stop();
486 }
487 android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
488 }
489 return NO_ERROR;
490 }
491
getInputDevice()492 audio_port_handle_t AudioRecord::getInputDevice() {
493 AutoMutex lock(mLock);
494 return mSelectedDeviceId;
495 }
496
getRoutedDeviceId()497 audio_port_handle_t AudioRecord::getRoutedDeviceId() {
498 AutoMutex lock(mLock);
499 if (mInput == AUDIO_IO_HANDLE_NONE) {
500 return AUDIO_PORT_HANDLE_NONE;
501 }
502 return AudioSystem::getDeviceIdForIo(mInput);
503 }
504
505 // -------------------------------------------------------------------------
506
507 // must be called with mLock held
openRecord_l(const Modulo<uint32_t> & epoch,const String16 & opPackageName)508 status_t AudioRecord::openRecord_l(const Modulo<uint32_t> &epoch, const String16& opPackageName)
509 {
510 const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
511 if (audioFlinger == 0) {
512 ALOGE("Could not get audioflinger");
513 return NO_INIT;
514 }
515
516 if (mDeviceCallback != 0 && mInput != AUDIO_IO_HANDLE_NONE) {
517 AudioSystem::removeAudioDeviceCallback(mDeviceCallback, mInput);
518 }
519 audio_io_handle_t input;
520
521 // mFlags (not mOrigFlags) is modified depending on whether fast request is accepted.
522 // After fast request is denied, we will request again if IAudioRecord is re-created.
523
524 status_t status;
525
526 // Not a conventional loop, but a retry loop for at most two iterations total.
527 // Try first maybe with FAST flag then try again without FAST flag if that fails.
528 // Exits loop normally via a return at the bottom, or with error via a break.
529 // The sp<> references will be dropped when re-entering scope.
530 // The lack of indentation is deliberate, to reduce code churn and ease merges.
531 for (;;) {
532
533 status = AudioSystem::getInputForAttr(&mAttributes, &input,
534 mSessionId,
535 // FIXME compare to AudioTrack
536 mClientPid,
537 mClientUid,
538 mSampleRate, mFormat, mChannelMask,
539 mFlags, mSelectedDeviceId);
540
541 if (status != NO_ERROR || input == AUDIO_IO_HANDLE_NONE) {
542 ALOGE("Could not get audio input for session %d, record source %d, sample rate %u, "
543 "format %#x, channel mask %#x, flags %#x",
544 mSessionId, mAttributes.source, mSampleRate, mFormat, mChannelMask, mFlags);
545 return BAD_VALUE;
546 }
547
548 // Now that we have a reference to an I/O handle and have not yet handed it off to AudioFlinger,
549 // we must release it ourselves if anything goes wrong.
550
551 #if 0
552 size_t afFrameCount;
553 status = AudioSystem::getFrameCount(input, &afFrameCount);
554 if (status != NO_ERROR) {
555 ALOGE("getFrameCount(input=%d) status %d", input, status);
556 break;
557 }
558 #endif
559
560 uint32_t afSampleRate;
561 status = AudioSystem::getSamplingRate(input, &afSampleRate);
562 if (status != NO_ERROR) {
563 ALOGE("getSamplingRate(input=%d) status %d", input, status);
564 break;
565 }
566 if (mSampleRate == 0) {
567 mSampleRate = afSampleRate;
568 }
569
570 // Client can only express a preference for FAST. Server will perform additional tests.
571 if (mFlags & AUDIO_INPUT_FLAG_FAST) {
572 bool useCaseAllowed =
573 // either of these use cases:
574 // use case 1: callback transfer mode
575 (mTransfer == TRANSFER_CALLBACK) ||
576 // use case 2: obtain/release mode
577 (mTransfer == TRANSFER_OBTAIN);
578 // sample rates must also match
579 bool fastAllowed = useCaseAllowed && (mSampleRate == afSampleRate);
580 if (!fastAllowed) {
581 ALOGW("AUDIO_INPUT_FLAG_FAST denied by client; transfer %d, "
582 "track %u Hz, input %u Hz",
583 mTransfer, mSampleRate, afSampleRate);
584 mFlags = (audio_input_flags_t) (mFlags & ~(AUDIO_INPUT_FLAG_FAST |
585 AUDIO_INPUT_FLAG_RAW));
586 AudioSystem::releaseInput(input, mSessionId);
587 continue; // retry
588 }
589 }
590
591 // The notification frame count is the period between callbacks, as suggested by the client
592 // but moderated by the server. For record, the calculations are done entirely on server side.
593 size_t notificationFrames = mNotificationFramesReq;
594 size_t frameCount = mReqFrameCount;
595
596 audio_input_flags_t flags = mFlags;
597
598 pid_t tid = -1;
599 if (mFlags & AUDIO_INPUT_FLAG_FAST) {
600 if (mAudioRecordThread != 0) {
601 tid = mAudioRecordThread->getTid();
602 }
603 }
604
605 size_t temp = frameCount; // temp may be replaced by a revised value of frameCount,
606 // but we will still need the original value also
607 audio_session_t originalSessionId = mSessionId;
608
609 sp<IMemory> iMem; // for cblk
610 sp<IMemory> bufferMem;
611 sp<IAudioRecord> record = audioFlinger->openRecord(input,
612 mSampleRate,
613 mFormat,
614 mChannelMask,
615 opPackageName,
616 &temp,
617 &flags,
618 mClientPid,
619 tid,
620 mClientUid,
621 &mSessionId,
622 ¬ificationFrames,
623 iMem,
624 bufferMem,
625 &status);
626 ALOGE_IF(originalSessionId != AUDIO_SESSION_ALLOCATE && mSessionId != originalSessionId,
627 "session ID changed from %d to %d", originalSessionId, mSessionId);
628
629 if (status != NO_ERROR) {
630 ALOGE("AudioFlinger could not create record track, status: %d", status);
631 break;
632 }
633 ALOG_ASSERT(record != 0);
634
635 // AudioFlinger now owns the reference to the I/O handle,
636 // so we are no longer responsible for releasing it.
637
638 mAwaitBoost = false;
639 if (mFlags & AUDIO_INPUT_FLAG_FAST) {
640 if (flags & AUDIO_INPUT_FLAG_FAST) {
641 ALOGI("AUDIO_INPUT_FLAG_FAST successful; frameCount %zu", frameCount);
642 mAwaitBoost = true;
643 } else {
644 ALOGW("AUDIO_INPUT_FLAG_FAST denied by server; frameCount %zu", frameCount);
645 mFlags = (audio_input_flags_t) (mFlags & ~(AUDIO_INPUT_FLAG_FAST |
646 AUDIO_INPUT_FLAG_RAW));
647 continue; // retry
648 }
649 }
650 mFlags = flags;
651
652 if (iMem == 0) {
653 ALOGE("Could not get control block");
654 return NO_INIT;
655 }
656 void *iMemPointer = iMem->pointer();
657 if (iMemPointer == NULL) {
658 ALOGE("Could not get control block pointer");
659 return NO_INIT;
660 }
661 audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMemPointer);
662
663 // Starting address of buffers in shared memory.
664 // The buffers are either immediately after the control block,
665 // or in a separate area at discretion of server.
666 void *buffers;
667 if (bufferMem == 0) {
668 buffers = cblk + 1;
669 } else {
670 buffers = bufferMem->pointer();
671 if (buffers == NULL) {
672 ALOGE("Could not get buffer pointer");
673 return NO_INIT;
674 }
675 }
676
677 // invariant that mAudioRecord != 0 is true only after set() returns successfully
678 if (mAudioRecord != 0) {
679 IInterface::asBinder(mAudioRecord)->unlinkToDeath(mDeathNotifier, this);
680 mDeathNotifier.clear();
681 }
682 mAudioRecord = record;
683 mCblkMemory = iMem;
684 mBufferMemory = bufferMem;
685 IPCThreadState::self()->flushCommands();
686
687 mCblk = cblk;
688 // note that temp is the (possibly revised) value of frameCount
689 if (temp < frameCount || (frameCount == 0 && temp == 0)) {
690 ALOGW("Requested frameCount %zu but received frameCount %zu", frameCount, temp);
691 }
692 frameCount = temp;
693
694 // Make sure that application is notified with sufficient margin before overrun.
695 // The computation is done on server side.
696 if (mNotificationFramesReq > 0 && notificationFrames != mNotificationFramesReq) {
697 ALOGW("Server adjusted notificationFrames from %u to %zu for frameCount %zu",
698 mNotificationFramesReq, notificationFrames, frameCount);
699 }
700 mNotificationFramesAct = (uint32_t) notificationFrames;
701
702 // We retain a copy of the I/O handle, but don't own the reference
703 mInput = input;
704 mRefreshRemaining = true;
705
706 mFrameCount = frameCount;
707 // If IAudioRecord is re-created, don't let the requested frameCount
708 // decrease. This can confuse clients that cache frameCount().
709 if (frameCount > mReqFrameCount) {
710 mReqFrameCount = frameCount;
711 }
712
713 // update proxy
714 mProxy = new AudioRecordClientProxy(cblk, buffers, mFrameCount, mFrameSize);
715 mProxy->setEpoch(epoch);
716 mProxy->setMinimum(mNotificationFramesAct);
717
718 mDeathNotifier = new DeathNotifier(this);
719 IInterface::asBinder(mAudioRecord)->linkToDeath(mDeathNotifier, this);
720
721 if (mDeviceCallback != 0) {
722 AudioSystem::addAudioDeviceCallback(mDeviceCallback, mInput);
723 }
724
725 return NO_ERROR;
726
727 // End of retry loop.
728 // The lack of indentation is deliberate, to reduce code churn and ease merges.
729 }
730
731 // Arrive here on error, via a break
732 AudioSystem::releaseInput(input, mSessionId);
733 if (status == NO_ERROR) {
734 status = NO_INIT;
735 }
736 return status;
737 }
738
obtainBuffer(Buffer * audioBuffer,int32_t waitCount,size_t * nonContig)739 status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount, size_t *nonContig)
740 {
741 if (audioBuffer == NULL) {
742 if (nonContig != NULL) {
743 *nonContig = 0;
744 }
745 return BAD_VALUE;
746 }
747 if (mTransfer != TRANSFER_OBTAIN) {
748 audioBuffer->frameCount = 0;
749 audioBuffer->size = 0;
750 audioBuffer->raw = NULL;
751 if (nonContig != NULL) {
752 *nonContig = 0;
753 }
754 return INVALID_OPERATION;
755 }
756
757 const struct timespec *requested;
758 struct timespec timeout;
759 if (waitCount == -1) {
760 requested = &ClientProxy::kForever;
761 } else if (waitCount == 0) {
762 requested = &ClientProxy::kNonBlocking;
763 } else if (waitCount > 0) {
764 long long ms = WAIT_PERIOD_MS * (long long) waitCount;
765 timeout.tv_sec = ms / 1000;
766 timeout.tv_nsec = (int) (ms % 1000) * 1000000;
767 requested = &timeout;
768 } else {
769 ALOGE("%s invalid waitCount %d", __func__, waitCount);
770 requested = NULL;
771 }
772 return obtainBuffer(audioBuffer, requested, NULL /*elapsed*/, nonContig);
773 }
774
obtainBuffer(Buffer * audioBuffer,const struct timespec * requested,struct timespec * elapsed,size_t * nonContig)775 status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, const struct timespec *requested,
776 struct timespec *elapsed, size_t *nonContig)
777 {
778 // previous and new IAudioRecord sequence numbers are used to detect track re-creation
779 uint32_t oldSequence = 0;
780 uint32_t newSequence;
781
782 Proxy::Buffer buffer;
783 status_t status = NO_ERROR;
784
785 static const int32_t kMaxTries = 5;
786 int32_t tryCounter = kMaxTries;
787
788 do {
789 // obtainBuffer() is called with mutex unlocked, so keep extra references to these fields to
790 // keep them from going away if another thread re-creates the track during obtainBuffer()
791 sp<AudioRecordClientProxy> proxy;
792 sp<IMemory> iMem;
793 sp<IMemory> bufferMem;
794 {
795 // start of lock scope
796 AutoMutex lock(mLock);
797
798 newSequence = mSequence;
799 // did previous obtainBuffer() fail due to media server death or voluntary invalidation?
800 if (status == DEAD_OBJECT) {
801 // re-create track, unless someone else has already done so
802 if (newSequence == oldSequence) {
803 status = restoreRecord_l("obtainBuffer");
804 if (status != NO_ERROR) {
805 buffer.mFrameCount = 0;
806 buffer.mRaw = NULL;
807 buffer.mNonContig = 0;
808 break;
809 }
810 }
811 }
812 oldSequence = newSequence;
813
814 // Keep the extra references
815 proxy = mProxy;
816 iMem = mCblkMemory;
817 bufferMem = mBufferMemory;
818
819 // Non-blocking if track is stopped
820 if (!mActive) {
821 requested = &ClientProxy::kNonBlocking;
822 }
823
824 } // end of lock scope
825
826 buffer.mFrameCount = audioBuffer->frameCount;
827 // FIXME starts the requested timeout and elapsed over from scratch
828 status = proxy->obtainBuffer(&buffer, requested, elapsed);
829
830 } while ((status == DEAD_OBJECT) && (tryCounter-- > 0));
831
832 audioBuffer->frameCount = buffer.mFrameCount;
833 audioBuffer->size = buffer.mFrameCount * mFrameSize;
834 audioBuffer->raw = buffer.mRaw;
835 if (nonContig != NULL) {
836 *nonContig = buffer.mNonContig;
837 }
838 return status;
839 }
840
releaseBuffer(const Buffer * audioBuffer)841 void AudioRecord::releaseBuffer(const Buffer* audioBuffer)
842 {
843 // FIXME add error checking on mode, by adding an internal version
844
845 size_t stepCount = audioBuffer->size / mFrameSize;
846 if (stepCount == 0) {
847 return;
848 }
849
850 Proxy::Buffer buffer;
851 buffer.mFrameCount = stepCount;
852 buffer.mRaw = audioBuffer->raw;
853
854 AutoMutex lock(mLock);
855 mInOverrun = false;
856 mProxy->releaseBuffer(&buffer);
857
858 // the server does not automatically disable recorder on overrun, so no need to restart
859 }
860
getInputPrivate() const861 audio_io_handle_t AudioRecord::getInputPrivate() const
862 {
863 AutoMutex lock(mLock);
864 return mInput;
865 }
866
867 // -------------------------------------------------------------------------
868
read(void * buffer,size_t userSize,bool blocking)869 ssize_t AudioRecord::read(void* buffer, size_t userSize, bool blocking)
870 {
871 if (mTransfer != TRANSFER_SYNC) {
872 return INVALID_OPERATION;
873 }
874
875 if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) {
876 // sanity-check. user is most-likely passing an error code, and it would
877 // make the return value ambiguous (actualSize vs error).
878 ALOGE("AudioRecord::read(buffer=%p, size=%zu (%zu)", buffer, userSize, userSize);
879 return BAD_VALUE;
880 }
881
882 ssize_t read = 0;
883 Buffer audioBuffer;
884
885 while (userSize >= mFrameSize) {
886 audioBuffer.frameCount = userSize / mFrameSize;
887
888 status_t err = obtainBuffer(&audioBuffer,
889 blocking ? &ClientProxy::kForever : &ClientProxy::kNonBlocking);
890 if (err < 0) {
891 if (read > 0) {
892 break;
893 }
894 if (err == TIMED_OUT || err == -EINTR) {
895 err = WOULD_BLOCK;
896 }
897 return ssize_t(err);
898 }
899
900 size_t bytesRead = audioBuffer.size;
901 memcpy(buffer, audioBuffer.i8, bytesRead);
902 buffer = ((char *) buffer) + bytesRead;
903 userSize -= bytesRead;
904 read += bytesRead;
905
906 releaseBuffer(&audioBuffer);
907 }
908 if (read > 0) {
909 mFramesRead += read / mFrameSize;
910 // mFramesReadTime = systemTime(SYSTEM_TIME_MONOTONIC); // not provided at this time.
911 }
912 return read;
913 }
914
915 // -------------------------------------------------------------------------
916
processAudioBuffer()917 nsecs_t AudioRecord::processAudioBuffer()
918 {
919 mLock.lock();
920 if (mAwaitBoost) {
921 mAwaitBoost = false;
922 mLock.unlock();
923 static const int32_t kMaxTries = 5;
924 int32_t tryCounter = kMaxTries;
925 uint32_t pollUs = 10000;
926 do {
927 int policy = sched_getscheduler(0) & ~SCHED_RESET_ON_FORK;
928 if (policy == SCHED_FIFO || policy == SCHED_RR) {
929 break;
930 }
931 usleep(pollUs);
932 pollUs <<= 1;
933 } while (tryCounter-- > 0);
934 if (tryCounter < 0) {
935 ALOGE("did not receive expected priority boost on time");
936 }
937 // Run again immediately
938 return 0;
939 }
940
941 // Can only reference mCblk while locked
942 int32_t flags = android_atomic_and(~CBLK_OVERRUN, &mCblk->mFlags);
943
944 // Check for track invalidation
945 if (flags & CBLK_INVALID) {
946 (void) restoreRecord_l("processAudioBuffer");
947 mLock.unlock();
948 // Run again immediately, but with a new IAudioRecord
949 return 0;
950 }
951
952 bool active = mActive;
953
954 // Manage overrun callback, must be done under lock to avoid race with releaseBuffer()
955 bool newOverrun = false;
956 if (flags & CBLK_OVERRUN) {
957 if (!mInOverrun) {
958 mInOverrun = true;
959 newOverrun = true;
960 }
961 }
962
963 // Get current position of server
964 Modulo<uint32_t> position(mProxy->getPosition());
965
966 // Manage marker callback
967 bool markerReached = false;
968 Modulo<uint32_t> markerPosition(mMarkerPosition);
969 // FIXME fails for wraparound, need 64 bits
970 if (!mMarkerReached && markerPosition.value() > 0 && position >= markerPosition) {
971 mMarkerReached = markerReached = true;
972 }
973
974 // Determine the number of new position callback(s) that will be needed, while locked
975 size_t newPosCount = 0;
976 Modulo<uint32_t> newPosition(mNewPosition);
977 uint32_t updatePeriod = mUpdatePeriod;
978 // FIXME fails for wraparound, need 64 bits
979 if (updatePeriod > 0 && position >= newPosition) {
980 newPosCount = ((position - newPosition).value() / updatePeriod) + 1;
981 mNewPosition += updatePeriod * newPosCount;
982 }
983
984 // Cache other fields that will be needed soon
985 uint32_t notificationFrames = mNotificationFramesAct;
986 if (mRefreshRemaining) {
987 mRefreshRemaining = false;
988 mRemainingFrames = notificationFrames;
989 mRetryOnPartialBuffer = false;
990 }
991 size_t misalignment = mProxy->getMisalignment();
992 uint32_t sequence = mSequence;
993
994 // These fields don't need to be cached, because they are assigned only by set():
995 // mTransfer, mCbf, mUserData, mSampleRate, mFrameSize
996
997 mLock.unlock();
998
999 // perform callbacks while unlocked
1000 if (newOverrun) {
1001 mCbf(EVENT_OVERRUN, mUserData, NULL);
1002 }
1003 if (markerReached) {
1004 mCbf(EVENT_MARKER, mUserData, &markerPosition);
1005 }
1006 while (newPosCount > 0) {
1007 size_t temp = newPosition.value(); // FIXME size_t != uint32_t
1008 mCbf(EVENT_NEW_POS, mUserData, &temp);
1009 newPosition += updatePeriod;
1010 newPosCount--;
1011 }
1012 if (mObservedSequence != sequence) {
1013 mObservedSequence = sequence;
1014 mCbf(EVENT_NEW_IAUDIORECORD, mUserData, NULL);
1015 }
1016
1017 // if inactive, then don't run me again until re-started
1018 if (!active) {
1019 return NS_INACTIVE;
1020 }
1021
1022 // Compute the estimated time until the next timed event (position, markers)
1023 uint32_t minFrames = ~0;
1024 if (!markerReached && position < markerPosition) {
1025 minFrames = (markerPosition - position).value();
1026 }
1027 if (updatePeriod > 0) {
1028 uint32_t remaining = (newPosition - position).value();
1029 if (remaining < minFrames) {
1030 minFrames = remaining;
1031 }
1032 }
1033
1034 // If > 0, poll periodically to recover from a stuck server. A good value is 2.
1035 static const uint32_t kPoll = 0;
1036 if (kPoll > 0 && mTransfer == TRANSFER_CALLBACK && kPoll * notificationFrames < minFrames) {
1037 minFrames = kPoll * notificationFrames;
1038 }
1039
1040 // Convert frame units to time units
1041 nsecs_t ns = NS_WHENEVER;
1042 if (minFrames != (uint32_t) ~0) {
1043 // This "fudge factor" avoids soaking CPU, and compensates for late progress by server
1044 static const nsecs_t kFudgeNs = 10000000LL; // 10 ms
1045 ns = ((minFrames * 1000000000LL) / mSampleRate) + kFudgeNs;
1046 }
1047
1048 // If not supplying data by EVENT_MORE_DATA, then we're done
1049 if (mTransfer != TRANSFER_CALLBACK) {
1050 return ns;
1051 }
1052
1053 struct timespec timeout;
1054 const struct timespec *requested = &ClientProxy::kForever;
1055 if (ns != NS_WHENEVER) {
1056 timeout.tv_sec = ns / 1000000000LL;
1057 timeout.tv_nsec = ns % 1000000000LL;
1058 ALOGV("timeout %ld.%03d", timeout.tv_sec, (int) timeout.tv_nsec / 1000000);
1059 requested = &timeout;
1060 }
1061
1062 size_t readFrames = 0;
1063 while (mRemainingFrames > 0) {
1064
1065 Buffer audioBuffer;
1066 audioBuffer.frameCount = mRemainingFrames;
1067 size_t nonContig;
1068 status_t err = obtainBuffer(&audioBuffer, requested, NULL, &nonContig);
1069 LOG_ALWAYS_FATAL_IF((err != NO_ERROR) != (audioBuffer.frameCount == 0),
1070 "obtainBuffer() err=%d frameCount=%zu", err, audioBuffer.frameCount);
1071 requested = &ClientProxy::kNonBlocking;
1072 size_t avail = audioBuffer.frameCount + nonContig;
1073 ALOGV("obtainBuffer(%u) returned %zu = %zu + %zu err %d",
1074 mRemainingFrames, avail, audioBuffer.frameCount, nonContig, err);
1075 if (err != NO_ERROR) {
1076 if (err == TIMED_OUT || err == WOULD_BLOCK || err == -EINTR) {
1077 break;
1078 }
1079 ALOGE("Error %d obtaining an audio buffer, giving up.", err);
1080 return NS_NEVER;
1081 }
1082
1083 if (mRetryOnPartialBuffer) {
1084 mRetryOnPartialBuffer = false;
1085 if (avail < mRemainingFrames) {
1086 int64_t myns = ((mRemainingFrames - avail) *
1087 1100000000LL) / mSampleRate;
1088 if (ns < 0 || myns < ns) {
1089 ns = myns;
1090 }
1091 return ns;
1092 }
1093 }
1094
1095 size_t reqSize = audioBuffer.size;
1096 mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
1097 size_t readSize = audioBuffer.size;
1098
1099 // Sanity check on returned size
1100 if (ssize_t(readSize) < 0 || readSize > reqSize) {
1101 ALOGE("EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes",
1102 reqSize, ssize_t(readSize));
1103 return NS_NEVER;
1104 }
1105
1106 if (readSize == 0) {
1107 // The callback is done consuming buffers
1108 // Keep this thread going to handle timed events and
1109 // still try to provide more data in intervals of WAIT_PERIOD_MS
1110 // but don't just loop and block the CPU, so wait
1111 return WAIT_PERIOD_MS * 1000000LL;
1112 }
1113
1114 size_t releasedFrames = readSize / mFrameSize;
1115 audioBuffer.frameCount = releasedFrames;
1116 mRemainingFrames -= releasedFrames;
1117 if (misalignment >= releasedFrames) {
1118 misalignment -= releasedFrames;
1119 } else {
1120 misalignment = 0;
1121 }
1122
1123 releaseBuffer(&audioBuffer);
1124 readFrames += releasedFrames;
1125
1126 // FIXME here is where we would repeat EVENT_MORE_DATA again on same advanced buffer
1127 // if callback doesn't like to accept the full chunk
1128 if (readSize < reqSize) {
1129 continue;
1130 }
1131
1132 // There could be enough non-contiguous frames available to satisfy the remaining request
1133 if (mRemainingFrames <= nonContig) {
1134 continue;
1135 }
1136
1137 #if 0
1138 // This heuristic tries to collapse a series of EVENT_MORE_DATA that would total to a
1139 // sum <= notificationFrames. It replaces that series by at most two EVENT_MORE_DATA
1140 // that total to a sum == notificationFrames.
1141 if (0 < misalignment && misalignment <= mRemainingFrames) {
1142 mRemainingFrames = misalignment;
1143 return (mRemainingFrames * 1100000000LL) / mSampleRate;
1144 }
1145 #endif
1146
1147 }
1148 if (readFrames > 0) {
1149 AutoMutex lock(mLock);
1150 mFramesRead += readFrames;
1151 // mFramesReadTime = systemTime(SYSTEM_TIME_MONOTONIC); // not provided at this time.
1152 }
1153 mRemainingFrames = notificationFrames;
1154 mRetryOnPartialBuffer = true;
1155
1156 // A lot has transpired since ns was calculated, so run again immediately and re-calculate
1157 return 0;
1158 }
1159
restoreRecord_l(const char * from)1160 status_t AudioRecord::restoreRecord_l(const char *from)
1161 {
1162 ALOGW("dead IAudioRecord, creating a new one from %s()", from);
1163 ++mSequence;
1164
1165 mFlags = mOrigFlags;
1166
1167 // if the new IAudioRecord is created, openRecord_l() will modify the
1168 // following member variables: mAudioRecord, mCblkMemory, mCblk, mBufferMemory.
1169 // It will also delete the strong references on previous IAudioRecord and IMemory
1170 Modulo<uint32_t> position(mProxy->getPosition());
1171 mNewPosition = position + mUpdatePeriod;
1172 status_t result = openRecord_l(position, mOpPackageName);
1173 if (result == NO_ERROR) {
1174 if (mActive) {
1175 // callback thread or sync event hasn't changed
1176 // FIXME this fails if we have a new AudioFlinger instance
1177 result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, AUDIO_SESSION_NONE);
1178 }
1179 mFramesReadServerOffset = mFramesRead; // server resets to zero so we need an offset.
1180 }
1181 if (result != NO_ERROR) {
1182 ALOGW("restoreRecord_l() failed status %d", result);
1183 mActive = false;
1184 }
1185
1186 return result;
1187 }
1188
addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback> & callback)1189 status_t AudioRecord::addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback)
1190 {
1191 if (callback == 0) {
1192 ALOGW("%s adding NULL callback!", __FUNCTION__);
1193 return BAD_VALUE;
1194 }
1195 AutoMutex lock(mLock);
1196 if (mDeviceCallback == callback) {
1197 ALOGW("%s adding same callback!", __FUNCTION__);
1198 return INVALID_OPERATION;
1199 }
1200 status_t status = NO_ERROR;
1201 if (mInput != AUDIO_IO_HANDLE_NONE) {
1202 if (mDeviceCallback != 0) {
1203 ALOGW("%s callback already present!", __FUNCTION__);
1204 AudioSystem::removeAudioDeviceCallback(mDeviceCallback, mInput);
1205 }
1206 status = AudioSystem::addAudioDeviceCallback(callback, mInput);
1207 }
1208 mDeviceCallback = callback;
1209 return status;
1210 }
1211
removeAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback> & callback)1212 status_t AudioRecord::removeAudioDeviceCallback(
1213 const sp<AudioSystem::AudioDeviceCallback>& callback)
1214 {
1215 if (callback == 0) {
1216 ALOGW("%s removing NULL callback!", __FUNCTION__);
1217 return BAD_VALUE;
1218 }
1219 AutoMutex lock(mLock);
1220 if (mDeviceCallback != callback) {
1221 ALOGW("%s removing different callback!", __FUNCTION__);
1222 return INVALID_OPERATION;
1223 }
1224 if (mInput != AUDIO_IO_HANDLE_NONE) {
1225 AudioSystem::removeAudioDeviceCallback(mDeviceCallback, mInput);
1226 }
1227 mDeviceCallback = 0;
1228 return NO_ERROR;
1229 }
1230
1231 // =========================================================================
1232
binderDied(const wp<IBinder> & who __unused)1233 void AudioRecord::DeathNotifier::binderDied(const wp<IBinder>& who __unused)
1234 {
1235 sp<AudioRecord> audioRecord = mAudioRecord.promote();
1236 if (audioRecord != 0) {
1237 AutoMutex lock(audioRecord->mLock);
1238 audioRecord->mProxy->binderDied();
1239 }
1240 }
1241
1242 // =========================================================================
1243
AudioRecordThread(AudioRecord & receiver,bool bCanCallJava)1244 AudioRecord::AudioRecordThread::AudioRecordThread(AudioRecord& receiver, bool bCanCallJava)
1245 : Thread(bCanCallJava), mReceiver(receiver), mPaused(true), mPausedInt(false), mPausedNs(0LL),
1246 mIgnoreNextPausedInt(false)
1247 {
1248 }
1249
~AudioRecordThread()1250 AudioRecord::AudioRecordThread::~AudioRecordThread()
1251 {
1252 }
1253
threadLoop()1254 bool AudioRecord::AudioRecordThread::threadLoop()
1255 {
1256 {
1257 AutoMutex _l(mMyLock);
1258 if (mPaused) {
1259 mMyCond.wait(mMyLock);
1260 // caller will check for exitPending()
1261 return true;
1262 }
1263 if (mIgnoreNextPausedInt) {
1264 mIgnoreNextPausedInt = false;
1265 mPausedInt = false;
1266 }
1267 if (mPausedInt) {
1268 if (mPausedNs > 0) {
1269 (void) mMyCond.waitRelative(mMyLock, mPausedNs);
1270 } else {
1271 mMyCond.wait(mMyLock);
1272 }
1273 mPausedInt = false;
1274 return true;
1275 }
1276 }
1277 if (exitPending()) {
1278 return false;
1279 }
1280 nsecs_t ns = mReceiver.processAudioBuffer();
1281 switch (ns) {
1282 case 0:
1283 return true;
1284 case NS_INACTIVE:
1285 pauseInternal();
1286 return true;
1287 case NS_NEVER:
1288 return false;
1289 case NS_WHENEVER:
1290 // Event driven: call wake() when callback notifications conditions change.
1291 ns = INT64_MAX;
1292 // fall through
1293 default:
1294 LOG_ALWAYS_FATAL_IF(ns < 0, "processAudioBuffer() returned %" PRId64, ns);
1295 pauseInternal(ns);
1296 return true;
1297 }
1298 }
1299
requestExit()1300 void AudioRecord::AudioRecordThread::requestExit()
1301 {
1302 // must be in this order to avoid a race condition
1303 Thread::requestExit();
1304 resume();
1305 }
1306
pause()1307 void AudioRecord::AudioRecordThread::pause()
1308 {
1309 AutoMutex _l(mMyLock);
1310 mPaused = true;
1311 }
1312
resume()1313 void AudioRecord::AudioRecordThread::resume()
1314 {
1315 AutoMutex _l(mMyLock);
1316 mIgnoreNextPausedInt = true;
1317 if (mPaused || mPausedInt) {
1318 mPaused = false;
1319 mPausedInt = false;
1320 mMyCond.signal();
1321 }
1322 }
1323
wake()1324 void AudioRecord::AudioRecordThread::wake()
1325 {
1326 AutoMutex _l(mMyLock);
1327 if (!mPaused) {
1328 // wake() might be called while servicing a callback - ignore the next
1329 // pause time and call processAudioBuffer.
1330 mIgnoreNextPausedInt = true;
1331 if (mPausedInt && mPausedNs > 0) {
1332 // audio record is active and internally paused with timeout.
1333 mPausedInt = false;
1334 mMyCond.signal();
1335 }
1336 }
1337 }
1338
pauseInternal(nsecs_t ns)1339 void AudioRecord::AudioRecordThread::pauseInternal(nsecs_t ns)
1340 {
1341 AutoMutex _l(mMyLock);
1342 mPausedInt = true;
1343 mPausedNs = ns;
1344 }
1345
1346 // -------------------------------------------------------------------------
1347
1348 } // namespace android
1349