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