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