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 IAudioFlinger::track_flags_t trackFlags = IAudioFlinger::TRACK_DEFAULT;
597
598 pid_t tid = -1;
599 if (mFlags & AUDIO_INPUT_FLAG_FAST) {
600 trackFlags |= IAudioFlinger::TRACK_FAST;
601 if (mAudioRecordThread != 0) {
602 tid = mAudioRecordThread->getTid();
603 }
604 }
605
606 size_t temp = frameCount; // temp may be replaced by a revised value of frameCount,
607 // but we will still need the original value also
608 audio_session_t originalSessionId = mSessionId;
609
610 sp<IMemory> iMem; // for cblk
611 sp<IMemory> bufferMem;
612 sp<IAudioRecord> record = audioFlinger->openRecord(input,
613 mSampleRate,
614 mFormat,
615 mChannelMask,
616 opPackageName,
617 &temp,
618 &trackFlags,
619 mClientPid,
620 tid,
621 mClientUid,
622 &mSessionId,
623 ¬ificationFrames,
624 iMem,
625 bufferMem,
626 &status);
627 ALOGE_IF(originalSessionId != AUDIO_SESSION_ALLOCATE && mSessionId != originalSessionId,
628 "session ID changed from %d to %d", originalSessionId, mSessionId);
629
630 if (status != NO_ERROR) {
631 ALOGE("AudioFlinger could not create record track, status: %d", status);
632 break;
633 }
634 ALOG_ASSERT(record != 0);
635
636 // AudioFlinger now owns the reference to the I/O handle,
637 // so we are no longer responsible for releasing it.
638
639 mAwaitBoost = false;
640 if (mFlags & AUDIO_INPUT_FLAG_FAST) {
641 if (trackFlags & IAudioFlinger::TRACK_FAST) {
642 ALOGI("AUDIO_INPUT_FLAG_FAST successful; frameCount %zu", frameCount);
643 mAwaitBoost = true;
644 } else {
645 ALOGW("AUDIO_INPUT_FLAG_FAST denied by server; frameCount %zu", frameCount);
646 mFlags = (audio_input_flags_t) (mFlags & ~(AUDIO_INPUT_FLAG_FAST |
647 AUDIO_INPUT_FLAG_RAW));
648 continue; // retry
649 }
650 }
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 return ssize_t(err);
895 }
896
897 size_t bytesRead = audioBuffer.size;
898 memcpy(buffer, audioBuffer.i8, bytesRead);
899 buffer = ((char *) buffer) + bytesRead;
900 userSize -= bytesRead;
901 read += bytesRead;
902
903 releaseBuffer(&audioBuffer);
904 }
905 if (read > 0) {
906 mFramesRead += read / mFrameSize;
907 // mFramesReadTime = systemTime(SYSTEM_TIME_MONOTONIC); // not provided at this time.
908 }
909 return read;
910 }
911
912 // -------------------------------------------------------------------------
913
processAudioBuffer()914 nsecs_t AudioRecord::processAudioBuffer()
915 {
916 mLock.lock();
917 if (mAwaitBoost) {
918 mAwaitBoost = false;
919 mLock.unlock();
920 static const int32_t kMaxTries = 5;
921 int32_t tryCounter = kMaxTries;
922 uint32_t pollUs = 10000;
923 do {
924 int policy = sched_getscheduler(0);
925 if (policy == SCHED_FIFO || policy == SCHED_RR) {
926 break;
927 }
928 usleep(pollUs);
929 pollUs <<= 1;
930 } while (tryCounter-- > 0);
931 if (tryCounter < 0) {
932 ALOGE("did not receive expected priority boost on time");
933 }
934 // Run again immediately
935 return 0;
936 }
937
938 // Can only reference mCblk while locked
939 int32_t flags = android_atomic_and(~CBLK_OVERRUN, &mCblk->mFlags);
940
941 // Check for track invalidation
942 if (flags & CBLK_INVALID) {
943 (void) restoreRecord_l("processAudioBuffer");
944 mLock.unlock();
945 // Run again immediately, but with a new IAudioRecord
946 return 0;
947 }
948
949 bool active = mActive;
950
951 // Manage overrun callback, must be done under lock to avoid race with releaseBuffer()
952 bool newOverrun = false;
953 if (flags & CBLK_OVERRUN) {
954 if (!mInOverrun) {
955 mInOverrun = true;
956 newOverrun = true;
957 }
958 }
959
960 // Get current position of server
961 Modulo<uint32_t> position(mProxy->getPosition());
962
963 // Manage marker callback
964 bool markerReached = false;
965 Modulo<uint32_t> markerPosition(mMarkerPosition);
966 // FIXME fails for wraparound, need 64 bits
967 if (!mMarkerReached && markerPosition.value() > 0 && position >= markerPosition) {
968 mMarkerReached = markerReached = true;
969 }
970
971 // Determine the number of new position callback(s) that will be needed, while locked
972 size_t newPosCount = 0;
973 Modulo<uint32_t> newPosition(mNewPosition);
974 uint32_t updatePeriod = mUpdatePeriod;
975 // FIXME fails for wraparound, need 64 bits
976 if (updatePeriod > 0 && position >= newPosition) {
977 newPosCount = ((position - newPosition).value() / updatePeriod) + 1;
978 mNewPosition += updatePeriod * newPosCount;
979 }
980
981 // Cache other fields that will be needed soon
982 uint32_t notificationFrames = mNotificationFramesAct;
983 if (mRefreshRemaining) {
984 mRefreshRemaining = false;
985 mRemainingFrames = notificationFrames;
986 mRetryOnPartialBuffer = false;
987 }
988 size_t misalignment = mProxy->getMisalignment();
989 uint32_t sequence = mSequence;
990
991 // These fields don't need to be cached, because they are assigned only by set():
992 // mTransfer, mCbf, mUserData, mSampleRate, mFrameSize
993
994 mLock.unlock();
995
996 // perform callbacks while unlocked
997 if (newOverrun) {
998 mCbf(EVENT_OVERRUN, mUserData, NULL);
999 }
1000 if (markerReached) {
1001 mCbf(EVENT_MARKER, mUserData, &markerPosition);
1002 }
1003 while (newPosCount > 0) {
1004 size_t temp = newPosition.value(); // FIXME size_t != uint32_t
1005 mCbf(EVENT_NEW_POS, mUserData, &temp);
1006 newPosition += updatePeriod;
1007 newPosCount--;
1008 }
1009 if (mObservedSequence != sequence) {
1010 mObservedSequence = sequence;
1011 mCbf(EVENT_NEW_IAUDIORECORD, mUserData, NULL);
1012 }
1013
1014 // if inactive, then don't run me again until re-started
1015 if (!active) {
1016 return NS_INACTIVE;
1017 }
1018
1019 // Compute the estimated time until the next timed event (position, markers)
1020 uint32_t minFrames = ~0;
1021 if (!markerReached && position < markerPosition) {
1022 minFrames = (markerPosition - position).value();
1023 }
1024 if (updatePeriod > 0) {
1025 uint32_t remaining = (newPosition - position).value();
1026 if (remaining < minFrames) {
1027 minFrames = remaining;
1028 }
1029 }
1030
1031 // If > 0, poll periodically to recover from a stuck server. A good value is 2.
1032 static const uint32_t kPoll = 0;
1033 if (kPoll > 0 && mTransfer == TRANSFER_CALLBACK && kPoll * notificationFrames < minFrames) {
1034 minFrames = kPoll * notificationFrames;
1035 }
1036
1037 // Convert frame units to time units
1038 nsecs_t ns = NS_WHENEVER;
1039 if (minFrames != (uint32_t) ~0) {
1040 // This "fudge factor" avoids soaking CPU, and compensates for late progress by server
1041 static const nsecs_t kFudgeNs = 10000000LL; // 10 ms
1042 ns = ((minFrames * 1000000000LL) / mSampleRate) + kFudgeNs;
1043 }
1044
1045 // If not supplying data by EVENT_MORE_DATA, then we're done
1046 if (mTransfer != TRANSFER_CALLBACK) {
1047 return ns;
1048 }
1049
1050 struct timespec timeout;
1051 const struct timespec *requested = &ClientProxy::kForever;
1052 if (ns != NS_WHENEVER) {
1053 timeout.tv_sec = ns / 1000000000LL;
1054 timeout.tv_nsec = ns % 1000000000LL;
1055 ALOGV("timeout %ld.%03d", timeout.tv_sec, (int) timeout.tv_nsec / 1000000);
1056 requested = &timeout;
1057 }
1058
1059 size_t readFrames = 0;
1060 while (mRemainingFrames > 0) {
1061
1062 Buffer audioBuffer;
1063 audioBuffer.frameCount = mRemainingFrames;
1064 size_t nonContig;
1065 status_t err = obtainBuffer(&audioBuffer, requested, NULL, &nonContig);
1066 LOG_ALWAYS_FATAL_IF((err != NO_ERROR) != (audioBuffer.frameCount == 0),
1067 "obtainBuffer() err=%d frameCount=%zu", err, audioBuffer.frameCount);
1068 requested = &ClientProxy::kNonBlocking;
1069 size_t avail = audioBuffer.frameCount + nonContig;
1070 ALOGV("obtainBuffer(%u) returned %zu = %zu + %zu err %d",
1071 mRemainingFrames, avail, audioBuffer.frameCount, nonContig, err);
1072 if (err != NO_ERROR) {
1073 if (err == TIMED_OUT || err == WOULD_BLOCK || err == -EINTR) {
1074 break;
1075 }
1076 ALOGE("Error %d obtaining an audio buffer, giving up.", err);
1077 return NS_NEVER;
1078 }
1079
1080 if (mRetryOnPartialBuffer) {
1081 mRetryOnPartialBuffer = false;
1082 if (avail < mRemainingFrames) {
1083 int64_t myns = ((mRemainingFrames - avail) *
1084 1100000000LL) / mSampleRate;
1085 if (ns < 0 || myns < ns) {
1086 ns = myns;
1087 }
1088 return ns;
1089 }
1090 }
1091
1092 size_t reqSize = audioBuffer.size;
1093 mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer);
1094 size_t readSize = audioBuffer.size;
1095
1096 // Sanity check on returned size
1097 if (ssize_t(readSize) < 0 || readSize > reqSize) {
1098 ALOGE("EVENT_MORE_DATA requested %zu bytes but callback returned %zd bytes",
1099 reqSize, ssize_t(readSize));
1100 return NS_NEVER;
1101 }
1102
1103 if (readSize == 0) {
1104 // The callback is done consuming buffers
1105 // Keep this thread going to handle timed events and
1106 // still try to provide more data in intervals of WAIT_PERIOD_MS
1107 // but don't just loop and block the CPU, so wait
1108 return WAIT_PERIOD_MS * 1000000LL;
1109 }
1110
1111 size_t releasedFrames = readSize / mFrameSize;
1112 audioBuffer.frameCount = releasedFrames;
1113 mRemainingFrames -= releasedFrames;
1114 if (misalignment >= releasedFrames) {
1115 misalignment -= releasedFrames;
1116 } else {
1117 misalignment = 0;
1118 }
1119
1120 releaseBuffer(&audioBuffer);
1121 readFrames += releasedFrames;
1122
1123 // FIXME here is where we would repeat EVENT_MORE_DATA again on same advanced buffer
1124 // if callback doesn't like to accept the full chunk
1125 if (readSize < reqSize) {
1126 continue;
1127 }
1128
1129 // There could be enough non-contiguous frames available to satisfy the remaining request
1130 if (mRemainingFrames <= nonContig) {
1131 continue;
1132 }
1133
1134 #if 0
1135 // This heuristic tries to collapse a series of EVENT_MORE_DATA that would total to a
1136 // sum <= notificationFrames. It replaces that series by at most two EVENT_MORE_DATA
1137 // that total to a sum == notificationFrames.
1138 if (0 < misalignment && misalignment <= mRemainingFrames) {
1139 mRemainingFrames = misalignment;
1140 return (mRemainingFrames * 1100000000LL) / mSampleRate;
1141 }
1142 #endif
1143
1144 }
1145 if (readFrames > 0) {
1146 AutoMutex lock(mLock);
1147 mFramesRead += readFrames;
1148 // mFramesReadTime = systemTime(SYSTEM_TIME_MONOTONIC); // not provided at this time.
1149 }
1150 mRemainingFrames = notificationFrames;
1151 mRetryOnPartialBuffer = true;
1152
1153 // A lot has transpired since ns was calculated, so run again immediately and re-calculate
1154 return 0;
1155 }
1156
restoreRecord_l(const char * from)1157 status_t AudioRecord::restoreRecord_l(const char *from)
1158 {
1159 ALOGW("dead IAudioRecord, creating a new one from %s()", from);
1160 ++mSequence;
1161
1162 mFlags = mOrigFlags;
1163
1164 // if the new IAudioRecord is created, openRecord_l() will modify the
1165 // following member variables: mAudioRecord, mCblkMemory, mCblk, mBufferMemory.
1166 // It will also delete the strong references on previous IAudioRecord and IMemory
1167 Modulo<uint32_t> position(mProxy->getPosition());
1168 mNewPosition = position + mUpdatePeriod;
1169 status_t result = openRecord_l(position, mOpPackageName);
1170 if (result == NO_ERROR) {
1171 if (mActive) {
1172 // callback thread or sync event hasn't changed
1173 // FIXME this fails if we have a new AudioFlinger instance
1174 result = mAudioRecord->start(AudioSystem::SYNC_EVENT_SAME, AUDIO_SESSION_NONE);
1175 }
1176 mFramesReadServerOffset = mFramesRead; // server resets to zero so we need an offset.
1177 }
1178 if (result != NO_ERROR) {
1179 ALOGW("restoreRecord_l() failed status %d", result);
1180 mActive = false;
1181 }
1182
1183 return result;
1184 }
1185
addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback> & callback)1186 status_t AudioRecord::addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback)
1187 {
1188 if (callback == 0) {
1189 ALOGW("%s adding NULL callback!", __FUNCTION__);
1190 return BAD_VALUE;
1191 }
1192 AutoMutex lock(mLock);
1193 if (mDeviceCallback == callback) {
1194 ALOGW("%s adding same callback!", __FUNCTION__);
1195 return INVALID_OPERATION;
1196 }
1197 status_t status = NO_ERROR;
1198 if (mInput != AUDIO_IO_HANDLE_NONE) {
1199 if (mDeviceCallback != 0) {
1200 ALOGW("%s callback already present!", __FUNCTION__);
1201 AudioSystem::removeAudioDeviceCallback(mDeviceCallback, mInput);
1202 }
1203 status = AudioSystem::addAudioDeviceCallback(callback, mInput);
1204 }
1205 mDeviceCallback = callback;
1206 return status;
1207 }
1208
removeAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback> & callback)1209 status_t AudioRecord::removeAudioDeviceCallback(
1210 const sp<AudioSystem::AudioDeviceCallback>& callback)
1211 {
1212 if (callback == 0) {
1213 ALOGW("%s removing NULL callback!", __FUNCTION__);
1214 return BAD_VALUE;
1215 }
1216 AutoMutex lock(mLock);
1217 if (mDeviceCallback != callback) {
1218 ALOGW("%s removing different callback!", __FUNCTION__);
1219 return INVALID_OPERATION;
1220 }
1221 if (mInput != AUDIO_IO_HANDLE_NONE) {
1222 AudioSystem::removeAudioDeviceCallback(mDeviceCallback, mInput);
1223 }
1224 mDeviceCallback = 0;
1225 return NO_ERROR;
1226 }
1227
1228 // =========================================================================
1229
binderDied(const wp<IBinder> & who __unused)1230 void AudioRecord::DeathNotifier::binderDied(const wp<IBinder>& who __unused)
1231 {
1232 sp<AudioRecord> audioRecord = mAudioRecord.promote();
1233 if (audioRecord != 0) {
1234 AutoMutex lock(audioRecord->mLock);
1235 audioRecord->mProxy->binderDied();
1236 }
1237 }
1238
1239 // =========================================================================
1240
AudioRecordThread(AudioRecord & receiver,bool bCanCallJava)1241 AudioRecord::AudioRecordThread::AudioRecordThread(AudioRecord& receiver, bool bCanCallJava)
1242 : Thread(bCanCallJava), mReceiver(receiver), mPaused(true), mPausedInt(false), mPausedNs(0LL),
1243 mIgnoreNextPausedInt(false)
1244 {
1245 }
1246
~AudioRecordThread()1247 AudioRecord::AudioRecordThread::~AudioRecordThread()
1248 {
1249 }
1250
threadLoop()1251 bool AudioRecord::AudioRecordThread::threadLoop()
1252 {
1253 {
1254 AutoMutex _l(mMyLock);
1255 if (mPaused) {
1256 mMyCond.wait(mMyLock);
1257 // caller will check for exitPending()
1258 return true;
1259 }
1260 if (mIgnoreNextPausedInt) {
1261 mIgnoreNextPausedInt = false;
1262 mPausedInt = false;
1263 }
1264 if (mPausedInt) {
1265 if (mPausedNs > 0) {
1266 (void) mMyCond.waitRelative(mMyLock, mPausedNs);
1267 } else {
1268 mMyCond.wait(mMyLock);
1269 }
1270 mPausedInt = false;
1271 return true;
1272 }
1273 }
1274 nsecs_t ns = mReceiver.processAudioBuffer();
1275 switch (ns) {
1276 case 0:
1277 return true;
1278 case NS_INACTIVE:
1279 pauseInternal();
1280 return true;
1281 case NS_NEVER:
1282 return false;
1283 case NS_WHENEVER:
1284 // Event driven: call wake() when callback notifications conditions change.
1285 ns = INT64_MAX;
1286 // fall through
1287 default:
1288 LOG_ALWAYS_FATAL_IF(ns < 0, "processAudioBuffer() returned %" PRId64, ns);
1289 pauseInternal(ns);
1290 return true;
1291 }
1292 }
1293
requestExit()1294 void AudioRecord::AudioRecordThread::requestExit()
1295 {
1296 // must be in this order to avoid a race condition
1297 Thread::requestExit();
1298 resume();
1299 }
1300
pause()1301 void AudioRecord::AudioRecordThread::pause()
1302 {
1303 AutoMutex _l(mMyLock);
1304 mPaused = true;
1305 }
1306
resume()1307 void AudioRecord::AudioRecordThread::resume()
1308 {
1309 AutoMutex _l(mMyLock);
1310 mIgnoreNextPausedInt = true;
1311 if (mPaused || mPausedInt) {
1312 mPaused = false;
1313 mPausedInt = false;
1314 mMyCond.signal();
1315 }
1316 }
1317
wake()1318 void AudioRecord::AudioRecordThread::wake()
1319 {
1320 AutoMutex _l(mMyLock);
1321 if (!mPaused) {
1322 // wake() might be called while servicing a callback - ignore the next
1323 // pause time and call processAudioBuffer.
1324 mIgnoreNextPausedInt = true;
1325 if (mPausedInt && mPausedNs > 0) {
1326 // audio record is active and internally paused with timeout.
1327 mPausedInt = false;
1328 mMyCond.signal();
1329 }
1330 }
1331 }
1332
pauseInternal(nsecs_t ns)1333 void AudioRecord::AudioRecordThread::pauseInternal(nsecs_t ns)
1334 {
1335 AutoMutex _l(mMyLock);
1336 mPausedInt = true;
1337 mPausedNs = ns;
1338 }
1339
1340 // -------------------------------------------------------------------------
1341
1342 } // namespace android
1343