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