1/*
2**
3** Copyright 2012, 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
19#define LOG_TAG "AudioFlinger"
20//#define LOG_NDEBUG 0
21
22#include "Configuration.h"
23#include <linux/futex.h>
24#include <math.h>
25#include <sys/syscall.h>
26#include <utils/Log.h>
27
28#include <private/media/AudioTrackShared.h>
29
30#include "AudioFlinger.h"
31#include "ServiceUtilities.h"
32
33#include <media/nbaio/Pipe.h>
34#include <media/nbaio/PipeReader.h>
35#include <media/RecordBufferConverter.h>
36#include <audio_utils/minifloat.h>
37
38// ----------------------------------------------------------------------------
39
40// Note: the following macro is used for extremely verbose logging message.  In
41// order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to
42// 0; but one side effect of this is to turn all LOGV's as well.  Some messages
43// are so verbose that we want to suppress them even when we have ALOG_ASSERT
44// turned on.  Do not uncomment the #def below unless you really know what you
45// are doing and want to see all of the extremely verbose messages.
46//#define VERY_VERY_VERBOSE_LOGGING
47#ifdef VERY_VERY_VERBOSE_LOGGING
48#define ALOGVV ALOGV
49#else
50#define ALOGVV(a...) do { } while(0)
51#endif
52
53namespace android {
54
55// ----------------------------------------------------------------------------
56//      TrackBase
57// ----------------------------------------------------------------------------
58
59static volatile int32_t nextTrackId = 55;
60
61// TrackBase constructor must be called with AudioFlinger::mLock held
62AudioFlinger::ThreadBase::TrackBase::TrackBase(
63            ThreadBase *thread,
64            const sp<Client>& client,
65            uint32_t sampleRate,
66            audio_format_t format,
67            audio_channel_mask_t channelMask,
68            size_t frameCount,
69            void *buffer,
70            size_t bufferSize,
71            audio_session_t sessionId,
72            uid_t clientUid,
73            bool isOut,
74            alloc_type alloc,
75            track_type type,
76            audio_port_handle_t portId)
77    :   RefBase(),
78        mThread(thread),
79        mClient(client),
80        mCblk(NULL),
81        // mBuffer, mBufferSize
82        mState(IDLE),
83        mSampleRate(sampleRate),
84        mFormat(format),
85        mChannelMask(channelMask),
86        mChannelCount(isOut ?
87                audio_channel_count_from_out_mask(channelMask) :
88                audio_channel_count_from_in_mask(channelMask)),
89        mFrameSize(audio_has_proportional_frames(format) ?
90                mChannelCount * audio_bytes_per_sample(format) : sizeof(int8_t)),
91        mFrameCount(frameCount),
92        mSessionId(sessionId),
93        mIsOut(isOut),
94        mId(android_atomic_inc(&nextTrackId)),
95        mTerminated(false),
96        mType(type),
97        mThreadIoHandle(thread->id()),
98        mPortId(portId),
99        mIsInvalid(false)
100{
101    const uid_t callingUid = IPCThreadState::self()->getCallingUid();
102    if (!isTrustedCallingUid(callingUid) || clientUid == AUDIO_UID_INVALID) {
103        ALOGW_IF(clientUid != AUDIO_UID_INVALID && clientUid != callingUid,
104                "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, clientUid);
105        clientUid = callingUid;
106    }
107    // clientUid contains the uid of the app that is responsible for this track, so we can blame
108    // battery usage on it.
109    mUid = clientUid;
110
111    // ALOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
112
113    size_t minBufferSize = buffer == NULL ? roundup(frameCount) : frameCount;
114    // check overflow when computing bufferSize due to multiplication by mFrameSize.
115    if (minBufferSize < frameCount  // roundup rounds down for values above UINT_MAX / 2
116            || mFrameSize == 0   // format needs to be correct
117            || minBufferSize > SIZE_MAX / mFrameSize) {
118        android_errorWriteLog(0x534e4554, "34749571");
119        return;
120    }
121    minBufferSize *= mFrameSize;
122
123    if (buffer == nullptr) {
124        bufferSize = minBufferSize; // allocated here.
125    } else if (minBufferSize > bufferSize) {
126        android_errorWriteLog(0x534e4554, "38340117");
127        return;
128    }
129
130    size_t size = sizeof(audio_track_cblk_t);
131    if (buffer == NULL && alloc == ALLOC_CBLK) {
132        // check overflow when computing allocation size for streaming tracks.
133        if (size > SIZE_MAX - bufferSize) {
134            android_errorWriteLog(0x534e4554, "34749571");
135            return;
136        }
137        size += bufferSize;
138    }
139
140    if (client != 0) {
141        mCblkMemory = client->heap()->allocate(size);
142        if (mCblkMemory == 0 ||
143                (mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer())) == NULL) {
144            ALOGE("not enough memory for AudioTrack size=%zu", size);
145            client->heap()->dump("AudioTrack");
146            mCblkMemory.clear();
147            return;
148        }
149    } else {
150        mCblk = (audio_track_cblk_t *) malloc(size);
151        if (mCblk == NULL) {
152            ALOGE("not enough memory for AudioTrack size=%zu", size);
153            return;
154        }
155    }
156
157    // construct the shared structure in-place.
158    if (mCblk != NULL) {
159        new(mCblk) audio_track_cblk_t();
160        switch (alloc) {
161        case ALLOC_READONLY: {
162            const sp<MemoryDealer> roHeap(thread->readOnlyHeap());
163            if (roHeap == 0 ||
164                    (mBufferMemory = roHeap->allocate(bufferSize)) == 0 ||
165                    (mBuffer = mBufferMemory->pointer()) == NULL) {
166                ALOGE("not enough memory for read-only buffer size=%zu", bufferSize);
167                if (roHeap != 0) {
168                    roHeap->dump("buffer");
169                }
170                mCblkMemory.clear();
171                mBufferMemory.clear();
172                return;
173            }
174            memset(mBuffer, 0, bufferSize);
175            } break;
176        case ALLOC_PIPE:
177            mBufferMemory = thread->pipeMemory();
178            // mBuffer is the virtual address as seen from current process (mediaserver),
179            // and should normally be coming from mBufferMemory->pointer().
180            // However in this case the TrackBase does not reference the buffer directly.
181            // It should references the buffer via the pipe.
182            // Therefore, to detect incorrect usage of the buffer, we set mBuffer to NULL.
183            mBuffer = NULL;
184            bufferSize = 0;
185            break;
186        case ALLOC_CBLK:
187            // clear all buffers
188            if (buffer == NULL) {
189                mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
190                memset(mBuffer, 0, bufferSize);
191            } else {
192                mBuffer = buffer;
193#if 0
194                mCblk->mFlags = CBLK_FORCEREADY;    // FIXME hack, need to fix the track ready logic
195#endif
196            }
197            break;
198        case ALLOC_LOCAL:
199            mBuffer = calloc(1, bufferSize);
200            break;
201        case ALLOC_NONE:
202            mBuffer = buffer;
203            break;
204        default:
205            LOG_ALWAYS_FATAL("invalid allocation type: %d", (int)alloc);
206        }
207        mBufferSize = bufferSize;
208
209#ifdef TEE_SINK
210        if (mTeeSinkTrackEnabled) {
211            NBAIO_Format pipeFormat = Format_from_SR_C(mSampleRate, mChannelCount, mFormat);
212            if (Format_isValid(pipeFormat)) {
213                Pipe *pipe = new Pipe(mTeeSinkTrackFrames, pipeFormat);
214                size_t numCounterOffers = 0;
215                const NBAIO_Format offers[1] = {pipeFormat};
216                ssize_t index = pipe->negotiate(offers, 1, NULL, numCounterOffers);
217                ALOG_ASSERT(index == 0);
218                PipeReader *pipeReader = new PipeReader(*pipe);
219                numCounterOffers = 0;
220                index = pipeReader->negotiate(offers, 1, NULL, numCounterOffers);
221                ALOG_ASSERT(index == 0);
222                mTeeSink = pipe;
223                mTeeSource = pipeReader;
224            }
225        }
226#endif
227
228    }
229}
230
231status_t AudioFlinger::ThreadBase::TrackBase::initCheck() const
232{
233    status_t status;
234    if (mType == TYPE_OUTPUT || mType == TYPE_PATCH) {
235        status = cblk() != NULL ? NO_ERROR : NO_MEMORY;
236    } else {
237        status = getCblk() != 0 ? NO_ERROR : NO_MEMORY;
238    }
239    return status;
240}
241
242AudioFlinger::ThreadBase::TrackBase::~TrackBase()
243{
244#ifdef TEE_SINK
245    dumpTee(-1, mTeeSource, mId, 'T');
246#endif
247    // delete the proxy before deleting the shared memory it refers to, to avoid dangling reference
248    mServerProxy.clear();
249    if (mCblk != NULL) {
250        mCblk->~audio_track_cblk_t();   // destroy our shared-structure.
251        if (mClient == 0) {
252            free(mCblk);
253        }
254    }
255    mCblkMemory.clear();    // free the shared memory before releasing the heap it belongs to
256    if (mClient != 0) {
257        // Client destructor must run with AudioFlinger client mutex locked
258        Mutex::Autolock _l(mClient->audioFlinger()->mClientLock);
259        // If the client's reference count drops to zero, the associated destructor
260        // must run with AudioFlinger lock held. Thus the explicit clear() rather than
261        // relying on the automatic clear() at end of scope.
262        mClient.clear();
263    }
264    // flush the binder command buffer
265    IPCThreadState::self()->flushCommands();
266}
267
268// AudioBufferProvider interface
269// getNextBuffer() = 0;
270// This implementation of releaseBuffer() is used by Track and RecordTrack
271void AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
272{
273#ifdef TEE_SINK
274    if (mTeeSink != 0) {
275        (void) mTeeSink->write(buffer->raw, buffer->frameCount);
276    }
277#endif
278
279    ServerProxy::Buffer buf;
280    buf.mFrameCount = buffer->frameCount;
281    buf.mRaw = buffer->raw;
282    buffer->frameCount = 0;
283    buffer->raw = NULL;
284    mServerProxy->releaseBuffer(&buf);
285}
286
287status_t AudioFlinger::ThreadBase::TrackBase::setSyncEvent(const sp<SyncEvent>& event)
288{
289    mSyncEvents.add(event);
290    return NO_ERROR;
291}
292
293// ----------------------------------------------------------------------------
294//      Playback
295// ----------------------------------------------------------------------------
296
297AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::PlaybackThread::Track>& track)
298    : BnAudioTrack(),
299      mTrack(track)
300{
301}
302
303AudioFlinger::TrackHandle::~TrackHandle() {
304    // just stop the track on deletion, associated resources
305    // will be freed from the main thread once all pending buffers have
306    // been played. Unless it's not in the active track list, in which
307    // case we free everything now...
308    mTrack->destroy();
309}
310
311sp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
312    return mTrack->getCblk();
313}
314
315status_t AudioFlinger::TrackHandle::start() {
316    return mTrack->start();
317}
318
319void AudioFlinger::TrackHandle::stop() {
320    mTrack->stop();
321}
322
323void AudioFlinger::TrackHandle::flush() {
324    mTrack->flush();
325}
326
327void AudioFlinger::TrackHandle::pause() {
328    mTrack->pause();
329}
330
331status_t AudioFlinger::TrackHandle::attachAuxEffect(int EffectId)
332{
333    return mTrack->attachAuxEffect(EffectId);
334}
335
336status_t AudioFlinger::TrackHandle::setParameters(const String8& keyValuePairs) {
337    return mTrack->setParameters(keyValuePairs);
338}
339
340VolumeShaper::Status AudioFlinger::TrackHandle::applyVolumeShaper(
341        const sp<VolumeShaper::Configuration>& configuration,
342        const sp<VolumeShaper::Operation>& operation) {
343    return mTrack->applyVolumeShaper(configuration, operation);
344}
345
346sp<VolumeShaper::State> AudioFlinger::TrackHandle::getVolumeShaperState(int id) {
347    return mTrack->getVolumeShaperState(id);
348}
349
350status_t AudioFlinger::TrackHandle::getTimestamp(AudioTimestamp& timestamp)
351{
352    return mTrack->getTimestamp(timestamp);
353}
354
355
356void AudioFlinger::TrackHandle::signal()
357{
358    return mTrack->signal();
359}
360
361status_t AudioFlinger::TrackHandle::onTransact(
362    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
363{
364    return BnAudioTrack::onTransact(code, data, reply, flags);
365}
366
367// ----------------------------------------------------------------------------
368
369// Track constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held
370AudioFlinger::PlaybackThread::Track::Track(
371            PlaybackThread *thread,
372            const sp<Client>& client,
373            audio_stream_type_t streamType,
374            uint32_t sampleRate,
375            audio_format_t format,
376            audio_channel_mask_t channelMask,
377            size_t frameCount,
378            void *buffer,
379            size_t bufferSize,
380            const sp<IMemory>& sharedBuffer,
381            audio_session_t sessionId,
382            uid_t uid,
383            audio_output_flags_t flags,
384            track_type type,
385            audio_port_handle_t portId)
386    :   TrackBase(thread, client, sampleRate, format, channelMask, frameCount,
387                  (sharedBuffer != 0) ? sharedBuffer->pointer() : buffer,
388                  (sharedBuffer != 0) ? sharedBuffer->size() : bufferSize,
389                  sessionId, uid, true /*isOut*/,
390                  (type == TYPE_PATCH) ? ( buffer == NULL ? ALLOC_LOCAL : ALLOC_NONE) : ALLOC_CBLK,
391                  type, portId),
392    mFillingUpStatus(FS_INVALID),
393    // mRetryCount initialized later when needed
394    mSharedBuffer(sharedBuffer),
395    mStreamType(streamType),
396    mName(-1),  // see note below
397    mMainBuffer(thread->mixBuffer()),
398    mAuxBuffer(NULL),
399    mAuxEffectId(0), mHasVolumeController(false),
400    mPresentationCompleteFrames(0),
401    mFrameMap(16 /* sink-frame-to-track-frame map memory */),
402    mVolumeHandler(new VolumeHandler(sampleRate)),
403    // mSinkTimestamp
404    mFastIndex(-1),
405    mCachedVolume(1.0),
406    mResumeToStopping(false),
407    mFlushHwPending(false),
408    mFlags(flags)
409{
410    // client == 0 implies sharedBuffer == 0
411    ALOG_ASSERT(!(client == 0 && sharedBuffer != 0));
412
413    ALOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %zu", sharedBuffer->pointer(),
414            sharedBuffer->size());
415
416    if (mCblk == NULL) {
417        return;
418    }
419
420    if (sharedBuffer == 0) {
421        mAudioTrackServerProxy = new AudioTrackServerProxy(mCblk, mBuffer, frameCount,
422                mFrameSize, !isExternalTrack(), sampleRate);
423    } else {
424        mAudioTrackServerProxy = new StaticAudioTrackServerProxy(mCblk, mBuffer, frameCount,
425                mFrameSize);
426    }
427    mServerProxy = mAudioTrackServerProxy;
428
429    mName = thread->getTrackName_l(channelMask, format, sessionId, uid);
430    if (mName < 0) {
431        ALOGE("no more track names available");
432        return;
433    }
434    // only allocate a fast track index if we were able to allocate a normal track name
435    if (flags & AUDIO_OUTPUT_FLAG_FAST) {
436        // FIXME: Not calling framesReadyIsCalledByMultipleThreads() exposes a potential
437        // race with setSyncEvent(). However, if we call it, we cannot properly start
438        // static fast tracks (SoundPool) immediately after stopping.
439        //mAudioTrackServerProxy->framesReadyIsCalledByMultipleThreads();
440        ALOG_ASSERT(thread->mFastTrackAvailMask != 0);
441        int i = __builtin_ctz(thread->mFastTrackAvailMask);
442        ALOG_ASSERT(0 < i && i < (int)FastMixerState::sMaxFastTracks);
443        // FIXME This is too eager.  We allocate a fast track index before the
444        //       fast track becomes active.  Since fast tracks are a scarce resource,
445        //       this means we are potentially denying other more important fast tracks from
446        //       being created.  It would be better to allocate the index dynamically.
447        mFastIndex = i;
448        thread->mFastTrackAvailMask &= ~(1 << i);
449    }
450}
451
452AudioFlinger::PlaybackThread::Track::~Track()
453{
454    ALOGV("PlaybackThread::Track destructor");
455
456    // The destructor would clear mSharedBuffer,
457    // but it will not push the decremented reference count,
458    // leaving the client's IMemory dangling indefinitely.
459    // This prevents that leak.
460    if (mSharedBuffer != 0) {
461        mSharedBuffer.clear();
462    }
463}
464
465status_t AudioFlinger::PlaybackThread::Track::initCheck() const
466{
467    status_t status = TrackBase::initCheck();
468    if (status == NO_ERROR && mName < 0) {
469        status = NO_MEMORY;
470    }
471    return status;
472}
473
474void AudioFlinger::PlaybackThread::Track::destroy()
475{
476    // NOTE: destroyTrack_l() can remove a strong reference to this Track
477    // by removing it from mTracks vector, so there is a risk that this Tracks's
478    // destructor is called. As the destructor needs to lock mLock,
479    // we must acquire a strong reference on this Track before locking mLock
480    // here so that the destructor is called only when exiting this function.
481    // On the other hand, as long as Track::destroy() is only called by
482    // TrackHandle destructor, the TrackHandle still holds a strong ref on
483    // this Track with its member mTrack.
484    sp<Track> keep(this);
485    { // scope for mLock
486        bool wasActive = false;
487        sp<ThreadBase> thread = mThread.promote();
488        if (thread != 0) {
489            Mutex::Autolock _l(thread->mLock);
490            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
491            wasActive = playbackThread->destroyTrack_l(this);
492        }
493        if (isExternalTrack() && !wasActive) {
494            AudioSystem::releaseOutput(mThreadIoHandle, mStreamType, mSessionId);
495        }
496    }
497}
498
499/*static*/ void AudioFlinger::PlaybackThread::Track::appendDumpHeader(String8& result)
500{
501    result.append("T Name Active Client Session S  Flags "
502                  "  Format Chn mask  SRate "
503                  "ST  L dB  R dB  VS dB "
504                  "  Server FrmCnt  FrmRdy F Underruns  Flushed "
505                  "Main Buf  Aux Buf\n");
506}
507
508void AudioFlinger::PlaybackThread::Track::appendDump(String8& result, bool active)
509{
510    char trackType;
511    switch (mType) {
512    case TYPE_DEFAULT:
513    case TYPE_OUTPUT:
514        if (mSharedBuffer.get() != nullptr) {
515            trackType = 'S'; // static
516        } else {
517            trackType = ' '; // normal
518        }
519        break;
520    case TYPE_PATCH:
521        trackType = 'P';
522        break;
523    default:
524        trackType = '?';
525    }
526
527    if (isFastTrack()) {
528        result.appendFormat("F%c %3d", trackType, mFastIndex);
529    } else if (mName >= AudioMixer::TRACK0) {
530        result.appendFormat("%c %4d", trackType, mName - AudioMixer::TRACK0);
531    } else {
532        result.appendFormat("%c none", trackType);
533    }
534
535    char nowInUnderrun;
536    switch (mObservedUnderruns.mBitFields.mMostRecent) {
537    case UNDERRUN_FULL:
538        nowInUnderrun = ' ';
539        break;
540    case UNDERRUN_PARTIAL:
541        nowInUnderrun = '<';
542        break;
543    case UNDERRUN_EMPTY:
544        nowInUnderrun = '*';
545        break;
546    default:
547        nowInUnderrun = '?';
548        break;
549    }
550
551    char fillingStatus;
552    switch (mFillingUpStatus) {
553    case FS_INVALID:
554        fillingStatus = 'I';
555        break;
556    case FS_FILLING:
557        fillingStatus = 'f';
558        break;
559    case FS_FILLED:
560        fillingStatus = 'F';
561        break;
562    case FS_ACTIVE:
563        fillingStatus = 'A';
564        break;
565    default:
566        fillingStatus = '?';
567        break;
568    }
569
570    // clip framesReadySafe to max representation in dump
571    const size_t framesReadySafe =
572            std::min(mAudioTrackServerProxy->framesReadySafe(), (size_t)99999999);
573
574    // obtain volumes
575    const gain_minifloat_packed_t vlr = mAudioTrackServerProxy->getVolumeLR();
576    const std::pair<float /* volume */, bool /* active */> vsVolume =
577            mVolumeHandler->getLastVolume();
578
579    // Our effective frame count is obtained by ServerProxy::getBufferSizeInFrames()
580    // as it may be reduced by the application.
581    const size_t bufferSizeInFrames = (size_t)mAudioTrackServerProxy->getBufferSizeInFrames();
582    // Check whether the buffer size has been modified by the app.
583    const char modifiedBufferChar = bufferSizeInFrames < mFrameCount
584            ? 'r' /* buffer reduced */: bufferSizeInFrames > mFrameCount
585                    ? 'e' /* error */ : ' ' /* identical */;
586
587    result.appendFormat("%7s %6u %7u %2s 0x%03X "
588                           "%08X %08X %6u "
589                           "%2u %5.2g %5.2g %5.2g%c "
590                           "%08X %6zu%c %6zu %c %9u%c %7u "
591                           "%08zX %08zX\n",
592            active ? "yes" : "no",
593            (mClient == 0) ? getpid_cached : mClient->pid(),
594            mSessionId,
595            getTrackStateString(),
596            mCblk->mFlags,
597
598            mFormat,
599            mChannelMask,
600            mAudioTrackServerProxy->getSampleRate(),
601
602            mStreamType,
603            20.0 * log10(float_from_gain(gain_minifloat_unpack_left(vlr))),
604            20.0 * log10(float_from_gain(gain_minifloat_unpack_right(vlr))),
605            20.0 * log10(vsVolume.first), // VolumeShaper(s) total volume
606            vsVolume.second ? 'A' : ' ',  // if any VolumeShapers active
607
608            mCblk->mServer,
609            bufferSizeInFrames,
610            modifiedBufferChar,
611            framesReadySafe,
612            fillingStatus,
613            mAudioTrackServerProxy->getUnderrunFrames(),
614            nowInUnderrun,
615            (unsigned)mAudioTrackServerProxy->framesFlushed() % 10000000,
616
617            (size_t)mMainBuffer, // use %zX as %p appends 0x
618            (size_t)mAuxBuffer   // use %zX as %p appends 0x
619            );
620}
621
622uint32_t AudioFlinger::PlaybackThread::Track::sampleRate() const {
623    return mAudioTrackServerProxy->getSampleRate();
624}
625
626// AudioBufferProvider interface
627status_t AudioFlinger::PlaybackThread::Track::getNextBuffer(
628        AudioBufferProvider::Buffer* buffer)
629{
630    ServerProxy::Buffer buf;
631    size_t desiredFrames = buffer->frameCount;
632    buf.mFrameCount = desiredFrames;
633    status_t status = mServerProxy->obtainBuffer(&buf);
634    buffer->frameCount = buf.mFrameCount;
635    buffer->raw = buf.mRaw;
636    if (buf.mFrameCount == 0 && !isStopping() && !isStopped() && !isPaused()) {
637        ALOGV("underrun,  framesReady(%zu) < framesDesired(%zd), state: %d",
638                buf.mFrameCount, desiredFrames, mState);
639        mAudioTrackServerProxy->tallyUnderrunFrames(desiredFrames);
640    } else {
641        mAudioTrackServerProxy->tallyUnderrunFrames(0);
642    }
643
644    return status;
645}
646
647// releaseBuffer() is not overridden
648
649// ExtendedAudioBufferProvider interface
650
651// framesReady() may return an approximation of the number of frames if called
652// from a different thread than the one calling Proxy->obtainBuffer() and
653// Proxy->releaseBuffer(). Also note there is no mutual exclusion in the
654// AudioTrackServerProxy so be especially careful calling with FastTracks.
655size_t AudioFlinger::PlaybackThread::Track::framesReady() const {
656    if (mSharedBuffer != 0 && (isStopped() || isStopping())) {
657        // Static tracks return zero frames immediately upon stopping (for FastTracks).
658        // The remainder of the buffer is not drained.
659        return 0;
660    }
661    return mAudioTrackServerProxy->framesReady();
662}
663
664int64_t AudioFlinger::PlaybackThread::Track::framesReleased() const
665{
666    return mAudioTrackServerProxy->framesReleased();
667}
668
669void AudioFlinger::PlaybackThread::Track::onTimestamp(const ExtendedTimestamp &timestamp)
670{
671    // This call comes from a FastTrack and should be kept lockless.
672    // The server side frames are already translated to client frames.
673    mAudioTrackServerProxy->setTimestamp(timestamp);
674
675    // We do not set drained here, as FastTrack timestamp may not go to very last frame.
676}
677
678// Don't call for fast tracks; the framesReady() could result in priority inversion
679bool AudioFlinger::PlaybackThread::Track::isReady() const {
680    if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing()) {
681        return true;
682    }
683
684    if (isStopping()) {
685        if (framesReady() > 0) {
686            mFillingUpStatus = FS_FILLED;
687        }
688        return true;
689    }
690
691    if (framesReady() >= mServerProxy->getBufferSizeInFrames() ||
692            (mCblk->mFlags & CBLK_FORCEREADY)) {
693        mFillingUpStatus = FS_FILLED;
694        android_atomic_and(~CBLK_FORCEREADY, &mCblk->mFlags);
695        return true;
696    }
697    return false;
698}
699
700status_t AudioFlinger::PlaybackThread::Track::start(AudioSystem::sync_event_t event __unused,
701                                                    audio_session_t triggerSession __unused)
702{
703    status_t status = NO_ERROR;
704    ALOGV("start(%d), calling pid %d session %d",
705            mName, IPCThreadState::self()->getCallingPid(), mSessionId);
706
707    sp<ThreadBase> thread = mThread.promote();
708    if (thread != 0) {
709        if (isOffloaded()) {
710            Mutex::Autolock _laf(thread->mAudioFlinger->mLock);
711            Mutex::Autolock _lth(thread->mLock);
712            sp<EffectChain> ec = thread->getEffectChain_l(mSessionId);
713            if (thread->mAudioFlinger->isNonOffloadableGlobalEffectEnabled_l() ||
714                    (ec != 0 && ec->isNonOffloadableEnabled())) {
715                invalidate();
716                return PERMISSION_DENIED;
717            }
718        }
719        Mutex::Autolock _lth(thread->mLock);
720        track_state state = mState;
721        // here the track could be either new, or restarted
722        // in both cases "unstop" the track
723
724        // initial state-stopping. next state-pausing.
725        // What if resume is called ?
726
727        if (state == PAUSED || state == PAUSING) {
728            if (mResumeToStopping) {
729                // happened we need to resume to STOPPING_1
730                mState = TrackBase::STOPPING_1;
731                ALOGV("PAUSED => STOPPING_1 (%d) on thread %p", mName, this);
732            } else {
733                mState = TrackBase::RESUMING;
734                ALOGV("PAUSED => RESUMING (%d) on thread %p", mName, this);
735            }
736        } else {
737            mState = TrackBase::ACTIVE;
738            ALOGV("? => ACTIVE (%d) on thread %p", mName, this);
739        }
740
741        // states to reset position info for non-offloaded/direct tracks
742        if (!isOffloaded() && !isDirect()
743                && (state == IDLE || state == STOPPED || state == FLUSHED)) {
744            mFrameMap.reset();
745        }
746        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
747        if (isFastTrack()) {
748            // refresh fast track underruns on start because that field is never cleared
749            // by the fast mixer; furthermore, the same track can be recycled, i.e. start
750            // after stop.
751            mObservedUnderruns = playbackThread->getFastTrackUnderruns(mFastIndex);
752        }
753        status = playbackThread->addTrack_l(this);
754        if (status == INVALID_OPERATION || status == PERMISSION_DENIED) {
755            triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
756            //  restore previous state if start was rejected by policy manager
757            if (status == PERMISSION_DENIED) {
758                mState = state;
759            }
760        }
761        // track was already in the active list, not a problem
762        if (status == ALREADY_EXISTS) {
763            status = NO_ERROR;
764        } else {
765            // Acknowledge any pending flush(), so that subsequent new data isn't discarded.
766            // It is usually unsafe to access the server proxy from a binder thread.
767            // But in this case we know the mixer thread (whether normal mixer or fast mixer)
768            // isn't looking at this track yet:  we still hold the normal mixer thread lock,
769            // and for fast tracks the track is not yet in the fast mixer thread's active set.
770            // For static tracks, this is used to acknowledge change in position or loop.
771            ServerProxy::Buffer buffer;
772            buffer.mFrameCount = 1;
773            (void) mAudioTrackServerProxy->obtainBuffer(&buffer, true /*ackFlush*/);
774        }
775    } else {
776        status = BAD_VALUE;
777    }
778    return status;
779}
780
781void AudioFlinger::PlaybackThread::Track::stop()
782{
783    ALOGV("stop(%d), calling pid %d", mName, IPCThreadState::self()->getCallingPid());
784    sp<ThreadBase> thread = mThread.promote();
785    if (thread != 0) {
786        Mutex::Autolock _l(thread->mLock);
787        track_state state = mState;
788        if (state == RESUMING || state == ACTIVE || state == PAUSING || state == PAUSED) {
789            // If the track is not active (PAUSED and buffers full), flush buffers
790            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
791            if (playbackThread->mActiveTracks.indexOf(this) < 0) {
792                reset();
793                mState = STOPPED;
794            } else if (!isFastTrack() && !isOffloaded() && !isDirect()) {
795                mState = STOPPED;
796            } else {
797                // For fast tracks prepareTracks_l() will set state to STOPPING_2
798                // presentation is complete
799                // For an offloaded track this starts a drain and state will
800                // move to STOPPING_2 when drain completes and then STOPPED
801                mState = STOPPING_1;
802                if (isOffloaded()) {
803                    mRetryCount = PlaybackThread::kMaxTrackStopRetriesOffload;
804                }
805            }
806            playbackThread->broadcast_l();
807            ALOGV("not stopping/stopped => stopping/stopped (%d) on thread %p", mName,
808                    playbackThread);
809        }
810    }
811}
812
813void AudioFlinger::PlaybackThread::Track::pause()
814{
815    ALOGV("pause(%d), calling pid %d", mName, IPCThreadState::self()->getCallingPid());
816    sp<ThreadBase> thread = mThread.promote();
817    if (thread != 0) {
818        Mutex::Autolock _l(thread->mLock);
819        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
820        switch (mState) {
821        case STOPPING_1:
822        case STOPPING_2:
823            if (!isOffloaded()) {
824                /* nothing to do if track is not offloaded */
825                break;
826            }
827
828            // Offloaded track was draining, we need to carry on draining when resumed
829            mResumeToStopping = true;
830            // fall through...
831        case ACTIVE:
832        case RESUMING:
833            mState = PAUSING;
834            ALOGV("ACTIVE/RESUMING => PAUSING (%d) on thread %p", mName, thread.get());
835            playbackThread->broadcast_l();
836            break;
837
838        default:
839            break;
840        }
841    }
842}
843
844void AudioFlinger::PlaybackThread::Track::flush()
845{
846    ALOGV("flush(%d)", mName);
847    sp<ThreadBase> thread = mThread.promote();
848    if (thread != 0) {
849        Mutex::Autolock _l(thread->mLock);
850        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
851
852        // Flush the ring buffer now if the track is not active in the PlaybackThread.
853        // Otherwise the flush would not be done until the track is resumed.
854        // Requires FastTrack removal be BLOCK_UNTIL_ACKED
855        if (playbackThread->mActiveTracks.indexOf(this) < 0) {
856            (void)mServerProxy->flushBufferIfNeeded();
857        }
858
859        if (isOffloaded()) {
860            // If offloaded we allow flush during any state except terminated
861            // and keep the track active to avoid problems if user is seeking
862            // rapidly and underlying hardware has a significant delay handling
863            // a pause
864            if (isTerminated()) {
865                return;
866            }
867
868            ALOGV("flush: offload flush");
869            reset();
870
871            if (mState == STOPPING_1 || mState == STOPPING_2) {
872                ALOGV("flushed in STOPPING_1 or 2 state, change state to ACTIVE");
873                mState = ACTIVE;
874            }
875
876            mFlushHwPending = true;
877            mResumeToStopping = false;
878        } else {
879            if (mState != STOPPING_1 && mState != STOPPING_2 && mState != STOPPED &&
880                    mState != PAUSED && mState != PAUSING && mState != IDLE && mState != FLUSHED) {
881                return;
882            }
883            // No point remaining in PAUSED state after a flush => go to
884            // FLUSHED state
885            mState = FLUSHED;
886            // do not reset the track if it is still in the process of being stopped or paused.
887            // this will be done by prepareTracks_l() when the track is stopped.
888            // prepareTracks_l() will see mState == FLUSHED, then
889            // remove from active track list, reset(), and trigger presentation complete
890            if (isDirect()) {
891                mFlushHwPending = true;
892            }
893            if (playbackThread->mActiveTracks.indexOf(this) < 0) {
894                reset();
895            }
896        }
897        // Prevent flush being lost if the track is flushed and then resumed
898        // before mixer thread can run. This is important when offloading
899        // because the hardware buffer could hold a large amount of audio
900        playbackThread->broadcast_l();
901    }
902}
903
904// must be called with thread lock held
905void AudioFlinger::PlaybackThread::Track::flushAck()
906{
907    if (!isOffloaded() && !isDirect())
908        return;
909
910    // Clear the client ring buffer so that the app can prime the buffer while paused.
911    // Otherwise it might not get cleared until playback is resumed and obtainBuffer() is called.
912    mServerProxy->flushBufferIfNeeded();
913
914    mFlushHwPending = false;
915}
916
917void AudioFlinger::PlaybackThread::Track::reset()
918{
919    // Do not reset twice to avoid discarding data written just after a flush and before
920    // the audioflinger thread detects the track is stopped.
921    if (!mResetDone) {
922        // Force underrun condition to avoid false underrun callback until first data is
923        // written to buffer
924        android_atomic_and(~CBLK_FORCEREADY, &mCblk->mFlags);
925        mFillingUpStatus = FS_FILLING;
926        mResetDone = true;
927        if (mState == FLUSHED) {
928            mState = IDLE;
929        }
930    }
931}
932
933status_t AudioFlinger::PlaybackThread::Track::setParameters(const String8& keyValuePairs)
934{
935    sp<ThreadBase> thread = mThread.promote();
936    if (thread == 0) {
937        ALOGE("thread is dead");
938        return FAILED_TRANSACTION;
939    } else if ((thread->type() == ThreadBase::DIRECT) ||
940                    (thread->type() == ThreadBase::OFFLOAD)) {
941        return thread->setParameters(keyValuePairs);
942    } else {
943        return PERMISSION_DENIED;
944    }
945}
946
947VolumeShaper::Status AudioFlinger::PlaybackThread::Track::applyVolumeShaper(
948        const sp<VolumeShaper::Configuration>& configuration,
949        const sp<VolumeShaper::Operation>& operation)
950{
951    sp<VolumeShaper::Configuration> newConfiguration;
952
953    if (isOffloadedOrDirect()) {
954        const VolumeShaper::Configuration::OptionFlag optionFlag
955            = configuration->getOptionFlags();
956        if ((optionFlag & VolumeShaper::Configuration::OPTION_FLAG_CLOCK_TIME) == 0) {
957            ALOGW("%s tracks do not support frame counted VolumeShaper,"
958                    " using clock time instead", isOffloaded() ? "Offload" : "Direct");
959            newConfiguration = new VolumeShaper::Configuration(*configuration);
960            newConfiguration->setOptionFlags(
961                VolumeShaper::Configuration::OptionFlag(optionFlag
962                        | VolumeShaper::Configuration::OPTION_FLAG_CLOCK_TIME));
963        }
964    }
965
966    VolumeShaper::Status status = mVolumeHandler->applyVolumeShaper(
967            (newConfiguration.get() != nullptr ? newConfiguration : configuration), operation);
968
969    if (isOffloadedOrDirect()) {
970        // Signal thread to fetch new volume.
971        sp<ThreadBase> thread = mThread.promote();
972        if (thread != 0) {
973             Mutex::Autolock _l(thread->mLock);
974            thread->broadcast_l();
975        }
976    }
977    return status;
978}
979
980sp<VolumeShaper::State> AudioFlinger::PlaybackThread::Track::getVolumeShaperState(int id)
981{
982    // Note: We don't check if Thread exists.
983
984    // mVolumeHandler is thread safe.
985    return mVolumeHandler->getVolumeShaperState(id);
986}
987
988status_t AudioFlinger::PlaybackThread::Track::getTimestamp(AudioTimestamp& timestamp)
989{
990    if (!isOffloaded() && !isDirect()) {
991        return INVALID_OPERATION; // normal tracks handled through SSQ
992    }
993    sp<ThreadBase> thread = mThread.promote();
994    if (thread == 0) {
995        return INVALID_OPERATION;
996    }
997
998    Mutex::Autolock _l(thread->mLock);
999    PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
1000    return playbackThread->getTimestamp_l(timestamp);
1001}
1002
1003status_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId)
1004{
1005    status_t status = DEAD_OBJECT;
1006    sp<ThreadBase> thread = mThread.promote();
1007    if (thread != 0) {
1008        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
1009        sp<AudioFlinger> af = mClient->audioFlinger();
1010
1011        Mutex::Autolock _l(af->mLock);
1012
1013        sp<PlaybackThread> srcThread = af->getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId);
1014
1015        if (EffectId != 0 && srcThread != 0 && playbackThread != srcThread.get()) {
1016            Mutex::Autolock _dl(playbackThread->mLock);
1017            Mutex::Autolock _sl(srcThread->mLock);
1018            sp<EffectChain> chain = srcThread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
1019            if (chain == 0) {
1020                return INVALID_OPERATION;
1021            }
1022
1023            sp<EffectModule> effect = chain->getEffectFromId_l(EffectId);
1024            if (effect == 0) {
1025                return INVALID_OPERATION;
1026            }
1027            srcThread->removeEffect_l(effect);
1028            status = playbackThread->addEffect_l(effect);
1029            if (status != NO_ERROR) {
1030                srcThread->addEffect_l(effect);
1031                return INVALID_OPERATION;
1032            }
1033            // removeEffect_l() has stopped the effect if it was active so it must be restarted
1034            if (effect->state() == EffectModule::ACTIVE ||
1035                    effect->state() == EffectModule::STOPPING) {
1036                effect->start();
1037            }
1038
1039            sp<EffectChain> dstChain = effect->chain().promote();
1040            if (dstChain == 0) {
1041                srcThread->addEffect_l(effect);
1042                return INVALID_OPERATION;
1043            }
1044            AudioSystem::unregisterEffect(effect->id());
1045            AudioSystem::registerEffect(&effect->desc(),
1046                                        srcThread->id(),
1047                                        dstChain->strategy(),
1048                                        AUDIO_SESSION_OUTPUT_MIX,
1049                                        effect->id());
1050            AudioSystem::setEffectEnabled(effect->id(), effect->isEnabled());
1051        }
1052        status = playbackThread->attachAuxEffect(this, EffectId);
1053    }
1054    return status;
1055}
1056
1057void AudioFlinger::PlaybackThread::Track::setAuxBuffer(int EffectId, int32_t *buffer)
1058{
1059    mAuxEffectId = EffectId;
1060    mAuxBuffer = buffer;
1061}
1062
1063bool AudioFlinger::PlaybackThread::Track::presentationComplete(
1064        int64_t framesWritten, size_t audioHalFrames)
1065{
1066    // TODO: improve this based on FrameMap if it exists, to ensure full drain.
1067    // This assists in proper timestamp computation as well as wakelock management.
1068
1069    // a track is considered presented when the total number of frames written to audio HAL
1070    // corresponds to the number of frames written when presentationComplete() is called for the
1071    // first time (mPresentationCompleteFrames == 0) plus the buffer filling status at that time.
1072    // For an offloaded track the HAL+h/w delay is variable so a HAL drain() is used
1073    // to detect when all frames have been played. In this case framesWritten isn't
1074    // useful because it doesn't always reflect whether there is data in the h/w
1075    // buffers, particularly if a track has been paused and resumed during draining
1076    ALOGV("presentationComplete() mPresentationCompleteFrames %lld framesWritten %lld",
1077            (long long)mPresentationCompleteFrames, (long long)framesWritten);
1078    if (mPresentationCompleteFrames == 0) {
1079        mPresentationCompleteFrames = framesWritten + audioHalFrames;
1080        ALOGV("presentationComplete() reset: mPresentationCompleteFrames %lld audioHalFrames %zu",
1081                (long long)mPresentationCompleteFrames, audioHalFrames);
1082    }
1083
1084    bool complete;
1085    if (isOffloaded()) {
1086        complete = true;
1087    } else if (isDirect() || isFastTrack()) { // these do not go through linear map
1088        complete = framesWritten >= (int64_t) mPresentationCompleteFrames;
1089    } else {  // Normal tracks, OutputTracks, and PatchTracks
1090        complete = framesWritten >= (int64_t) mPresentationCompleteFrames
1091                && mAudioTrackServerProxy->isDrained();
1092    }
1093
1094    if (complete) {
1095        triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE);
1096        mAudioTrackServerProxy->setStreamEndDone();
1097        return true;
1098    }
1099    return false;
1100}
1101
1102void AudioFlinger::PlaybackThread::Track::triggerEvents(AudioSystem::sync_event_t type)
1103{
1104    for (size_t i = 0; i < mSyncEvents.size(); i++) {
1105        if (mSyncEvents[i]->type() == type) {
1106            mSyncEvents[i]->trigger();
1107            mSyncEvents.removeAt(i);
1108            i--;
1109        }
1110    }
1111}
1112
1113// implement VolumeBufferProvider interface
1114
1115gain_minifloat_packed_t AudioFlinger::PlaybackThread::Track::getVolumeLR()
1116{
1117    // called by FastMixer, so not allowed to take any locks, block, or do I/O including logs
1118    ALOG_ASSERT(isFastTrack() && (mCblk != NULL));
1119    gain_minifloat_packed_t vlr = mAudioTrackServerProxy->getVolumeLR();
1120    float vl = float_from_gain(gain_minifloat_unpack_left(vlr));
1121    float vr = float_from_gain(gain_minifloat_unpack_right(vlr));
1122    // track volumes come from shared memory, so can't be trusted and must be clamped
1123    if (vl > GAIN_FLOAT_UNITY) {
1124        vl = GAIN_FLOAT_UNITY;
1125    }
1126    if (vr > GAIN_FLOAT_UNITY) {
1127        vr = GAIN_FLOAT_UNITY;
1128    }
1129    // now apply the cached master volume and stream type volume;
1130    // this is trusted but lacks any synchronization or barrier so may be stale
1131    float v = mCachedVolume;
1132    vl *= v;
1133    vr *= v;
1134    // re-combine into packed minifloat
1135    vlr = gain_minifloat_pack(gain_from_float(vl), gain_from_float(vr));
1136    // FIXME look at mute, pause, and stop flags
1137    return vlr;
1138}
1139
1140status_t AudioFlinger::PlaybackThread::Track::setSyncEvent(const sp<SyncEvent>& event)
1141{
1142    if (isTerminated() || mState == PAUSED ||
1143            ((framesReady() == 0) && ((mSharedBuffer != 0) ||
1144                                      (mState == STOPPED)))) {
1145        ALOGW("Track::setSyncEvent() in invalid state %d on session %d %s mode, framesReady %zu",
1146              mState, mSessionId, (mSharedBuffer != 0) ? "static" : "stream", framesReady());
1147        event->cancel();
1148        return INVALID_OPERATION;
1149    }
1150    (void) TrackBase::setSyncEvent(event);
1151    return NO_ERROR;
1152}
1153
1154void AudioFlinger::PlaybackThread::Track::invalidate()
1155{
1156    TrackBase::invalidate();
1157    signalClientFlag(CBLK_INVALID);
1158}
1159
1160void AudioFlinger::PlaybackThread::Track::disable()
1161{
1162    signalClientFlag(CBLK_DISABLED);
1163}
1164
1165void AudioFlinger::PlaybackThread::Track::signalClientFlag(int32_t flag)
1166{
1167    // FIXME should use proxy, and needs work
1168    audio_track_cblk_t* cblk = mCblk;
1169    android_atomic_or(flag, &cblk->mFlags);
1170    android_atomic_release_store(0x40000000, &cblk->mFutex);
1171    // client is not in server, so FUTEX_WAKE is needed instead of FUTEX_WAKE_PRIVATE
1172    (void) syscall(__NR_futex, &cblk->mFutex, FUTEX_WAKE, INT_MAX);
1173}
1174
1175void AudioFlinger::PlaybackThread::Track::signal()
1176{
1177    sp<ThreadBase> thread = mThread.promote();
1178    if (thread != 0) {
1179        PlaybackThread *t = (PlaybackThread *)thread.get();
1180        Mutex::Autolock _l(t->mLock);
1181        t->broadcast_l();
1182    }
1183}
1184
1185//To be called with thread lock held
1186bool AudioFlinger::PlaybackThread::Track::isResumePending() {
1187
1188    if (mState == RESUMING)
1189        return true;
1190    /* Resume is pending if track was stopping before pause was called */
1191    if (mState == STOPPING_1 &&
1192        mResumeToStopping)
1193        return true;
1194
1195    return false;
1196}
1197
1198//To be called with thread lock held
1199void AudioFlinger::PlaybackThread::Track::resumeAck() {
1200
1201
1202    if (mState == RESUMING)
1203        mState = ACTIVE;
1204
1205    // Other possibility of  pending resume is stopping_1 state
1206    // Do not update the state from stopping as this prevents
1207    // drain being called.
1208    if (mState == STOPPING_1) {
1209        mResumeToStopping = false;
1210    }
1211}
1212
1213//To be called with thread lock held
1214void AudioFlinger::PlaybackThread::Track::updateTrackFrameInfo(
1215        int64_t trackFramesReleased, int64_t sinkFramesWritten,
1216        const ExtendedTimestamp &timeStamp) {
1217    //update frame map
1218    mFrameMap.push(trackFramesReleased, sinkFramesWritten);
1219
1220    // adjust server times and set drained state.
1221    //
1222    // Our timestamps are only updated when the track is on the Thread active list.
1223    // We need to ensure that tracks are not removed before full drain.
1224    ExtendedTimestamp local = timeStamp;
1225    bool checked = false;
1226    for (int i = ExtendedTimestamp::LOCATION_MAX - 1;
1227            i >= ExtendedTimestamp::LOCATION_SERVER; --i) {
1228        // Lookup the track frame corresponding to the sink frame position.
1229        if (local.mTimeNs[i] > 0) {
1230            local.mPosition[i] = mFrameMap.findX(local.mPosition[i]);
1231            // check drain state from the latest stage in the pipeline.
1232            if (!checked && i <= ExtendedTimestamp::LOCATION_KERNEL) {
1233                mAudioTrackServerProxy->setDrained(
1234                        local.mPosition[i] >= mAudioTrackServerProxy->framesReleased());
1235                checked = true;
1236            }
1237        }
1238    }
1239    if (!checked) { // no server info, assume drained.
1240        mAudioTrackServerProxy->setDrained(true);
1241    }
1242    // Set correction for flushed frames that are not accounted for in released.
1243    local.mFlushed = mAudioTrackServerProxy->framesFlushed();
1244    mServerProxy->setTimestamp(local);
1245}
1246
1247// ----------------------------------------------------------------------------
1248
1249AudioFlinger::PlaybackThread::OutputTrack::OutputTrack(
1250            PlaybackThread *playbackThread,
1251            DuplicatingThread *sourceThread,
1252            uint32_t sampleRate,
1253            audio_format_t format,
1254            audio_channel_mask_t channelMask,
1255            size_t frameCount,
1256            uid_t uid)
1257    :   Track(playbackThread, NULL, AUDIO_STREAM_PATCH,
1258              sampleRate, format, channelMask, frameCount,
1259              nullptr /* buffer */, (size_t)0 /* bufferSize */, nullptr /* sharedBuffer */,
1260              AUDIO_SESSION_NONE, uid, AUDIO_OUTPUT_FLAG_NONE,
1261              TYPE_OUTPUT),
1262    mActive(false), mSourceThread(sourceThread)
1263{
1264
1265    if (mCblk != NULL) {
1266        mOutBuffer.frameCount = 0;
1267        playbackThread->mTracks.add(this);
1268        ALOGV("OutputTrack constructor mCblk %p, mBuffer %p, "
1269                "frameCount %zu, mChannelMask 0x%08x",
1270                mCblk, mBuffer,
1271                frameCount, mChannelMask);
1272        // since client and server are in the same process,
1273        // the buffer has the same virtual address on both sides
1274        mClientProxy = new AudioTrackClientProxy(mCblk, mBuffer, mFrameCount, mFrameSize,
1275                true /*clientInServer*/);
1276        mClientProxy->setVolumeLR(GAIN_MINIFLOAT_PACKED_UNITY);
1277        mClientProxy->setSendLevel(0.0);
1278        mClientProxy->setSampleRate(sampleRate);
1279    } else {
1280        ALOGW("Error creating output track on thread %p", playbackThread);
1281    }
1282}
1283
1284AudioFlinger::PlaybackThread::OutputTrack::~OutputTrack()
1285{
1286    clearBufferQueue();
1287    // superclass destructor will now delete the server proxy and shared memory both refer to
1288}
1289
1290status_t AudioFlinger::PlaybackThread::OutputTrack::start(AudioSystem::sync_event_t event,
1291                                                          audio_session_t triggerSession)
1292{
1293    status_t status = Track::start(event, triggerSession);
1294    if (status != NO_ERROR) {
1295        return status;
1296    }
1297
1298    mActive = true;
1299    mRetryCount = 127;
1300    return status;
1301}
1302
1303void AudioFlinger::PlaybackThread::OutputTrack::stop()
1304{
1305    Track::stop();
1306    clearBufferQueue();
1307    mOutBuffer.frameCount = 0;
1308    mActive = false;
1309}
1310
1311bool AudioFlinger::PlaybackThread::OutputTrack::write(void* data, uint32_t frames)
1312{
1313    Buffer *pInBuffer;
1314    Buffer inBuffer;
1315    bool outputBufferFull = false;
1316    inBuffer.frameCount = frames;
1317    inBuffer.raw = data;
1318
1319    uint32_t waitTimeLeftMs = mSourceThread->waitTimeMs();
1320
1321    if (!mActive && frames != 0) {
1322        (void) start();
1323    }
1324
1325    while (waitTimeLeftMs) {
1326        // First write pending buffers, then new data
1327        if (mBufferQueue.size()) {
1328            pInBuffer = mBufferQueue.itemAt(0);
1329        } else {
1330            pInBuffer = &inBuffer;
1331        }
1332
1333        if (pInBuffer->frameCount == 0) {
1334            break;
1335        }
1336
1337        if (mOutBuffer.frameCount == 0) {
1338            mOutBuffer.frameCount = pInBuffer->frameCount;
1339            nsecs_t startTime = systemTime();
1340            status_t status = obtainBuffer(&mOutBuffer, waitTimeLeftMs);
1341            if (status != NO_ERROR && status != NOT_ENOUGH_DATA) {
1342                ALOGV("OutputTrack::write() %p thread %p no more output buffers; status %d", this,
1343                        mThread.unsafe_get(), status);
1344                outputBufferFull = true;
1345                break;
1346            }
1347            uint32_t waitTimeMs = (uint32_t)ns2ms(systemTime() - startTime);
1348            if (waitTimeLeftMs >= waitTimeMs) {
1349                waitTimeLeftMs -= waitTimeMs;
1350            } else {
1351                waitTimeLeftMs = 0;
1352            }
1353            if (status == NOT_ENOUGH_DATA) {
1354                restartIfDisabled();
1355                continue;
1356            }
1357        }
1358
1359        uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount :
1360                pInBuffer->frameCount;
1361        memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * mFrameSize);
1362        Proxy::Buffer buf;
1363        buf.mFrameCount = outFrames;
1364        buf.mRaw = NULL;
1365        mClientProxy->releaseBuffer(&buf);
1366        restartIfDisabled();
1367        pInBuffer->frameCount -= outFrames;
1368        pInBuffer->raw = (int8_t *)pInBuffer->raw + outFrames * mFrameSize;
1369        mOutBuffer.frameCount -= outFrames;
1370        mOutBuffer.raw = (int8_t *)mOutBuffer.raw + outFrames * mFrameSize;
1371
1372        if (pInBuffer->frameCount == 0) {
1373            if (mBufferQueue.size()) {
1374                mBufferQueue.removeAt(0);
1375                free(pInBuffer->mBuffer);
1376                if (pInBuffer != &inBuffer) {
1377                    delete pInBuffer;
1378                }
1379                ALOGV("OutputTrack::write() %p thread %p released overflow buffer %zu", this,
1380                        mThread.unsafe_get(), mBufferQueue.size());
1381            } else {
1382                break;
1383            }
1384        }
1385    }
1386
1387    // If we could not write all frames, allocate a buffer and queue it for next time.
1388    if (inBuffer.frameCount) {
1389        sp<ThreadBase> thread = mThread.promote();
1390        if (thread != 0 && !thread->standby()) {
1391            if (mBufferQueue.size() < kMaxOverFlowBuffers) {
1392                pInBuffer = new Buffer;
1393                pInBuffer->mBuffer = malloc(inBuffer.frameCount * mFrameSize);
1394                pInBuffer->frameCount = inBuffer.frameCount;
1395                pInBuffer->raw = pInBuffer->mBuffer;
1396                memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * mFrameSize);
1397                mBufferQueue.add(pInBuffer);
1398                ALOGV("OutputTrack::write() %p thread %p adding overflow buffer %zu", this,
1399                        mThread.unsafe_get(), mBufferQueue.size());
1400            } else {
1401                ALOGW("OutputTrack::write() %p thread %p no more overflow buffers",
1402                        mThread.unsafe_get(), this);
1403            }
1404        }
1405    }
1406
1407    // Calling write() with a 0 length buffer means that no more data will be written:
1408    // We rely on stop() to set the appropriate flags to allow the remaining frames to play out.
1409    if (frames == 0 && mBufferQueue.size() == 0 && mActive) {
1410        stop();
1411    }
1412
1413    return outputBufferFull;
1414}
1415
1416status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(
1417        AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs)
1418{
1419    ClientProxy::Buffer buf;
1420    buf.mFrameCount = buffer->frameCount;
1421    struct timespec timeout;
1422    timeout.tv_sec = waitTimeMs / 1000;
1423    timeout.tv_nsec = (int) (waitTimeMs % 1000) * 1000000;
1424    status_t status = mClientProxy->obtainBuffer(&buf, &timeout);
1425    buffer->frameCount = buf.mFrameCount;
1426    buffer->raw = buf.mRaw;
1427    return status;
1428}
1429
1430void AudioFlinger::PlaybackThread::OutputTrack::clearBufferQueue()
1431{
1432    size_t size = mBufferQueue.size();
1433
1434    for (size_t i = 0; i < size; i++) {
1435        Buffer *pBuffer = mBufferQueue.itemAt(i);
1436        free(pBuffer->mBuffer);
1437        delete pBuffer;
1438    }
1439    mBufferQueue.clear();
1440}
1441
1442void AudioFlinger::PlaybackThread::OutputTrack::restartIfDisabled()
1443{
1444    int32_t flags = android_atomic_and(~CBLK_DISABLED, &mCblk->mFlags);
1445    if (mActive && (flags & CBLK_DISABLED)) {
1446        start();
1447    }
1448}
1449
1450AudioFlinger::PlaybackThread::PatchTrack::PatchTrack(PlaybackThread *playbackThread,
1451                                                     audio_stream_type_t streamType,
1452                                                     uint32_t sampleRate,
1453                                                     audio_channel_mask_t channelMask,
1454                                                     audio_format_t format,
1455                                                     size_t frameCount,
1456                                                     void *buffer,
1457                                                     size_t bufferSize,
1458                                                     audio_output_flags_t flags)
1459    :   Track(playbackThread, NULL, streamType,
1460              sampleRate, format, channelMask, frameCount,
1461              buffer, bufferSize, nullptr /* sharedBuffer */,
1462              AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
1463              mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true))
1464{
1465    uint64_t mixBufferNs = ((uint64_t)2 * playbackThread->frameCount() * 1000000000) /
1466                                                                    playbackThread->sampleRate();
1467    mPeerTimeout.tv_sec = mixBufferNs / 1000000000;
1468    mPeerTimeout.tv_nsec = (int) (mixBufferNs % 1000000000);
1469
1470    ALOGV("PatchTrack %p sampleRate %d mPeerTimeout %d.%03d sec",
1471                                      this, sampleRate,
1472                                      (int)mPeerTimeout.tv_sec,
1473                                      (int)(mPeerTimeout.tv_nsec / 1000000));
1474}
1475
1476AudioFlinger::PlaybackThread::PatchTrack::~PatchTrack()
1477{
1478}
1479
1480status_t AudioFlinger::PlaybackThread::PatchTrack::start(AudioSystem::sync_event_t event,
1481                                                          audio_session_t triggerSession)
1482{
1483    status_t status = Track::start(event, triggerSession);
1484    if (status != NO_ERROR) {
1485        return status;
1486    }
1487    android_atomic_and(~CBLK_DISABLED, &mCblk->mFlags);
1488    return status;
1489}
1490
1491// AudioBufferProvider interface
1492status_t AudioFlinger::PlaybackThread::PatchTrack::getNextBuffer(
1493        AudioBufferProvider::Buffer* buffer)
1494{
1495    ALOG_ASSERT(mPeerProxy != 0, "PatchTrack::getNextBuffer() called without peer proxy");
1496    Proxy::Buffer buf;
1497    buf.mFrameCount = buffer->frameCount;
1498    status_t status = mPeerProxy->obtainBuffer(&buf, &mPeerTimeout);
1499    ALOGV_IF(status != NO_ERROR, "PatchTrack() %p getNextBuffer status %d", this, status);
1500    buffer->frameCount = buf.mFrameCount;
1501    if (buf.mFrameCount == 0) {
1502        return WOULD_BLOCK;
1503    }
1504    status = Track::getNextBuffer(buffer);
1505    return status;
1506}
1507
1508void AudioFlinger::PlaybackThread::PatchTrack::releaseBuffer(AudioBufferProvider::Buffer* buffer)
1509{
1510    ALOG_ASSERT(mPeerProxy != 0, "PatchTrack::releaseBuffer() called without peer proxy");
1511    Proxy::Buffer buf;
1512    buf.mFrameCount = buffer->frameCount;
1513    buf.mRaw = buffer->raw;
1514    mPeerProxy->releaseBuffer(&buf);
1515    TrackBase::releaseBuffer(buffer);
1516}
1517
1518status_t AudioFlinger::PlaybackThread::PatchTrack::obtainBuffer(Proxy::Buffer* buffer,
1519                                                                const struct timespec *timeOut)
1520{
1521    status_t status = NO_ERROR;
1522    static const int32_t kMaxTries = 5;
1523    int32_t tryCounter = kMaxTries;
1524    do {
1525        if (status == NOT_ENOUGH_DATA) {
1526            restartIfDisabled();
1527        }
1528        status = mProxy->obtainBuffer(buffer, timeOut);
1529    } while ((status == NOT_ENOUGH_DATA) && (tryCounter-- > 0));
1530    return status;
1531}
1532
1533void AudioFlinger::PlaybackThread::PatchTrack::releaseBuffer(Proxy::Buffer* buffer)
1534{
1535    mProxy->releaseBuffer(buffer);
1536    restartIfDisabled();
1537    android_atomic_or(CBLK_FORCEREADY, &mCblk->mFlags);
1538}
1539
1540void AudioFlinger::PlaybackThread::PatchTrack::restartIfDisabled()
1541{
1542    if (android_atomic_and(~CBLK_DISABLED, &mCblk->mFlags) & CBLK_DISABLED) {
1543        ALOGW("PatchTrack::releaseBuffer() disabled due to previous underrun, restarting");
1544        start();
1545    }
1546}
1547
1548// ----------------------------------------------------------------------------
1549//      Record
1550// ----------------------------------------------------------------------------
1551
1552AudioFlinger::RecordHandle::RecordHandle(
1553        const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack)
1554    : BnAudioRecord(),
1555    mRecordTrack(recordTrack)
1556{
1557}
1558
1559AudioFlinger::RecordHandle::~RecordHandle() {
1560    stop_nonvirtual();
1561    mRecordTrack->destroy();
1562}
1563
1564status_t AudioFlinger::RecordHandle::start(int /*AudioSystem::sync_event_t*/ event,
1565        audio_session_t triggerSession) {
1566    ALOGV("RecordHandle::start()");
1567    return mRecordTrack->start((AudioSystem::sync_event_t)event, triggerSession);
1568}
1569
1570void AudioFlinger::RecordHandle::stop() {
1571    stop_nonvirtual();
1572}
1573
1574void AudioFlinger::RecordHandle::stop_nonvirtual() {
1575    ALOGV("RecordHandle::stop()");
1576    mRecordTrack->stop();
1577}
1578
1579status_t AudioFlinger::RecordHandle::onTransact(
1580    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
1581{
1582    return BnAudioRecord::onTransact(code, data, reply, flags);
1583}
1584
1585// ----------------------------------------------------------------------------
1586
1587// RecordTrack constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held
1588AudioFlinger::RecordThread::RecordTrack::RecordTrack(
1589            RecordThread *thread,
1590            const sp<Client>& client,
1591            uint32_t sampleRate,
1592            audio_format_t format,
1593            audio_channel_mask_t channelMask,
1594            size_t frameCount,
1595            void *buffer,
1596            size_t bufferSize,
1597            audio_session_t sessionId,
1598            uid_t uid,
1599            audio_input_flags_t flags,
1600            track_type type,
1601            audio_port_handle_t portId)
1602    :   TrackBase(thread, client, sampleRate, format,
1603                  channelMask, frameCount, buffer, bufferSize, sessionId, uid, false /*isOut*/,
1604                  (type == TYPE_DEFAULT) ?
1605                          ((flags & AUDIO_INPUT_FLAG_FAST) ? ALLOC_PIPE : ALLOC_CBLK) :
1606                          ((buffer == NULL) ? ALLOC_LOCAL : ALLOC_NONE),
1607                  type, portId),
1608        mOverflow(false),
1609        mFramesToDrop(0),
1610        mResamplerBufferProvider(NULL), // initialize in case of early constructor exit
1611        mRecordBufferConverter(NULL),
1612        mFlags(flags)
1613{
1614    if (mCblk == NULL) {
1615        return;
1616    }
1617
1618    mRecordBufferConverter = new RecordBufferConverter(
1619            thread->mChannelMask, thread->mFormat, thread->mSampleRate,
1620            channelMask, format, sampleRate);
1621    // Check if the RecordBufferConverter construction was successful.
1622    // If not, don't continue with construction.
1623    //
1624    // NOTE: It would be extremely rare that the record track cannot be created
1625    // for the current device, but a pending or future device change would make
1626    // the record track configuration valid.
1627    if (mRecordBufferConverter->initCheck() != NO_ERROR) {
1628        ALOGE("RecordTrack unable to create record buffer converter");
1629        return;
1630    }
1631
1632    mServerProxy = new AudioRecordServerProxy(mCblk, mBuffer, frameCount,
1633            mFrameSize, !isExternalTrack());
1634
1635    mResamplerBufferProvider = new ResamplerBufferProvider(this);
1636
1637    if (flags & AUDIO_INPUT_FLAG_FAST) {
1638        ALOG_ASSERT(thread->mFastTrackAvail);
1639        thread->mFastTrackAvail = false;
1640    }
1641}
1642
1643AudioFlinger::RecordThread::RecordTrack::~RecordTrack()
1644{
1645    ALOGV("%s", __func__);
1646    delete mRecordBufferConverter;
1647    delete mResamplerBufferProvider;
1648}
1649
1650status_t AudioFlinger::RecordThread::RecordTrack::initCheck() const
1651{
1652    status_t status = TrackBase::initCheck();
1653    if (status == NO_ERROR && mServerProxy == 0) {
1654        status = BAD_VALUE;
1655    }
1656    return status;
1657}
1658
1659// AudioBufferProvider interface
1660status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
1661{
1662    ServerProxy::Buffer buf;
1663    buf.mFrameCount = buffer->frameCount;
1664    status_t status = mServerProxy->obtainBuffer(&buf);
1665    buffer->frameCount = buf.mFrameCount;
1666    buffer->raw = buf.mRaw;
1667    if (buf.mFrameCount == 0) {
1668        // FIXME also wake futex so that overrun is noticed more quickly
1669        (void) android_atomic_or(CBLK_OVERRUN, &mCblk->mFlags);
1670    }
1671    return status;
1672}
1673
1674status_t AudioFlinger::RecordThread::RecordTrack::start(AudioSystem::sync_event_t event,
1675                                                        audio_session_t triggerSession)
1676{
1677    sp<ThreadBase> thread = mThread.promote();
1678    if (thread != 0) {
1679        RecordThread *recordThread = (RecordThread *)thread.get();
1680        return recordThread->start(this, event, triggerSession);
1681    } else {
1682        return BAD_VALUE;
1683    }
1684}
1685
1686void AudioFlinger::RecordThread::RecordTrack::stop()
1687{
1688    sp<ThreadBase> thread = mThread.promote();
1689    if (thread != 0) {
1690        RecordThread *recordThread = (RecordThread *)thread.get();
1691        if (recordThread->stop(this) && isExternalTrack()) {
1692            AudioSystem::stopInput(mThreadIoHandle, mSessionId);
1693        }
1694    }
1695}
1696
1697void AudioFlinger::RecordThread::RecordTrack::destroy()
1698{
1699    // see comments at AudioFlinger::PlaybackThread::Track::destroy()
1700    sp<RecordTrack> keep(this);
1701    {
1702        if (isExternalTrack()) {
1703            if (mState == ACTIVE || mState == RESUMING) {
1704                AudioSystem::stopInput(mThreadIoHandle, mSessionId);
1705            }
1706            AudioSystem::releaseInput(mThreadIoHandle, mSessionId);
1707        }
1708        sp<ThreadBase> thread = mThread.promote();
1709        if (thread != 0) {
1710            Mutex::Autolock _l(thread->mLock);
1711            RecordThread *recordThread = (RecordThread *) thread.get();
1712            recordThread->destroyTrack_l(this);
1713        }
1714    }
1715}
1716
1717void AudioFlinger::RecordThread::RecordTrack::invalidate()
1718{
1719    TrackBase::invalidate();
1720    // FIXME should use proxy, and needs work
1721    audio_track_cblk_t* cblk = mCblk;
1722    android_atomic_or(CBLK_INVALID, &cblk->mFlags);
1723    android_atomic_release_store(0x40000000, &cblk->mFutex);
1724    // client is not in server, so FUTEX_WAKE is needed instead of FUTEX_WAKE_PRIVATE
1725    (void) syscall(__NR_futex, &cblk->mFutex, FUTEX_WAKE, INT_MAX);
1726}
1727
1728
1729/*static*/ void AudioFlinger::RecordThread::RecordTrack::appendDumpHeader(String8& result)
1730{
1731    result.append("Active Client Session S  Flags   Format Chn mask  SRate   Server FrmCnt\n");
1732}
1733
1734void AudioFlinger::RecordThread::RecordTrack::appendDump(String8& result, bool active)
1735{
1736    result.appendFormat("%c%5s %6u %7u %2s 0x%03X "
1737            "%08X %08X %6u "
1738            "%08X %6zu\n",
1739            isFastTrack() ? 'F' : ' ',
1740            active ? "yes" : "no",
1741            (mClient == 0) ? getpid_cached : mClient->pid(),
1742            mSessionId,
1743            getTrackStateString(),
1744            mCblk->mFlags,
1745
1746            mFormat,
1747            mChannelMask,
1748            mSampleRate,
1749
1750            mCblk->mServer,
1751            mFrameCount
1752            );
1753}
1754
1755void AudioFlinger::RecordThread::RecordTrack::handleSyncStartEvent(const sp<SyncEvent>& event)
1756{
1757    if (event == mSyncStartEvent) {
1758        ssize_t framesToDrop = 0;
1759        sp<ThreadBase> threadBase = mThread.promote();
1760        if (threadBase != 0) {
1761            // TODO: use actual buffer filling status instead of 2 buffers when info is available
1762            // from audio HAL
1763            framesToDrop = threadBase->mFrameCount * 2;
1764        }
1765        mFramesToDrop = framesToDrop;
1766    }
1767}
1768
1769void AudioFlinger::RecordThread::RecordTrack::clearSyncStartEvent()
1770{
1771    if (mSyncStartEvent != 0) {
1772        mSyncStartEvent->cancel();
1773        mSyncStartEvent.clear();
1774    }
1775    mFramesToDrop = 0;
1776}
1777
1778void AudioFlinger::RecordThread::RecordTrack::updateTrackFrameInfo(
1779        int64_t trackFramesReleased, int64_t sourceFramesRead,
1780        uint32_t halSampleRate, const ExtendedTimestamp &timestamp)
1781{
1782    ExtendedTimestamp local = timestamp;
1783
1784    // Convert HAL frames to server-side track frames at track sample rate.
1785    // We use trackFramesReleased and sourceFramesRead as an anchor point.
1786    for (int i = ExtendedTimestamp::LOCATION_SERVER; i < ExtendedTimestamp::LOCATION_MAX; ++i) {
1787        if (local.mTimeNs[i] != 0) {
1788            const int64_t relativeServerFrames = local.mPosition[i] - sourceFramesRead;
1789            const int64_t relativeTrackFrames = relativeServerFrames
1790                    * mSampleRate / halSampleRate; // TODO: potential computation overflow
1791            local.mPosition[i] = relativeTrackFrames + trackFramesReleased;
1792        }
1793    }
1794    mServerProxy->setTimestamp(local);
1795}
1796
1797AudioFlinger::RecordThread::PatchRecord::PatchRecord(RecordThread *recordThread,
1798                                                     uint32_t sampleRate,
1799                                                     audio_channel_mask_t channelMask,
1800                                                     audio_format_t format,
1801                                                     size_t frameCount,
1802                                                     void *buffer,
1803                                                     size_t bufferSize,
1804                                                     audio_input_flags_t flags)
1805    :   RecordTrack(recordThread, NULL, sampleRate, format, channelMask, frameCount,
1806                buffer, bufferSize, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
1807                mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true))
1808{
1809    uint64_t mixBufferNs = ((uint64_t)2 * recordThread->frameCount() * 1000000000) /
1810                                                                recordThread->sampleRate();
1811    mPeerTimeout.tv_sec = mixBufferNs / 1000000000;
1812    mPeerTimeout.tv_nsec = (int) (mixBufferNs % 1000000000);
1813
1814    ALOGV("PatchRecord %p sampleRate %d mPeerTimeout %d.%03d sec",
1815                                      this, sampleRate,
1816                                      (int)mPeerTimeout.tv_sec,
1817                                      (int)(mPeerTimeout.tv_nsec / 1000000));
1818}
1819
1820AudioFlinger::RecordThread::PatchRecord::~PatchRecord()
1821{
1822}
1823
1824// AudioBufferProvider interface
1825status_t AudioFlinger::RecordThread::PatchRecord::getNextBuffer(
1826                                                  AudioBufferProvider::Buffer* buffer)
1827{
1828    ALOG_ASSERT(mPeerProxy != 0, "PatchRecord::getNextBuffer() called without peer proxy");
1829    Proxy::Buffer buf;
1830    buf.mFrameCount = buffer->frameCount;
1831    status_t status = mPeerProxy->obtainBuffer(&buf, &mPeerTimeout);
1832    ALOGV_IF(status != NO_ERROR,
1833             "PatchRecord() %p mPeerProxy->obtainBuffer status %d", this, status);
1834    buffer->frameCount = buf.mFrameCount;
1835    if (buf.mFrameCount == 0) {
1836        return WOULD_BLOCK;
1837    }
1838    status = RecordTrack::getNextBuffer(buffer);
1839    return status;
1840}
1841
1842void AudioFlinger::RecordThread::PatchRecord::releaseBuffer(AudioBufferProvider::Buffer* buffer)
1843{
1844    ALOG_ASSERT(mPeerProxy != 0, "PatchRecord::releaseBuffer() called without peer proxy");
1845    Proxy::Buffer buf;
1846    buf.mFrameCount = buffer->frameCount;
1847    buf.mRaw = buffer->raw;
1848    mPeerProxy->releaseBuffer(&buf);
1849    TrackBase::releaseBuffer(buffer);
1850}
1851
1852status_t AudioFlinger::RecordThread::PatchRecord::obtainBuffer(Proxy::Buffer* buffer,
1853                                                               const struct timespec *timeOut)
1854{
1855    return mProxy->obtainBuffer(buffer, timeOut);
1856}
1857
1858void AudioFlinger::RecordThread::PatchRecord::releaseBuffer(Proxy::Buffer* buffer)
1859{
1860    mProxy->releaseBuffer(buffer);
1861}
1862
1863
1864
1865AudioFlinger::MmapThread::MmapTrack::MmapTrack(ThreadBase *thread,
1866        uint32_t sampleRate,
1867        audio_format_t format,
1868        audio_channel_mask_t channelMask,
1869        audio_session_t sessionId,
1870        uid_t uid,
1871        pid_t pid,
1872        audio_port_handle_t portId)
1873    :   TrackBase(thread, NULL, sampleRate, format,
1874                  channelMask, (size_t)0 /* frameCount */,
1875                  nullptr /* buffer */, (size_t)0 /* bufferSize */,
1876                  sessionId, uid, false /* isOut */,
1877                  ALLOC_NONE,
1878                  TYPE_DEFAULT, portId),
1879        mPid(pid)
1880{
1881}
1882
1883AudioFlinger::MmapThread::MmapTrack::~MmapTrack()
1884{
1885}
1886
1887status_t AudioFlinger::MmapThread::MmapTrack::initCheck() const
1888{
1889    return NO_ERROR;
1890}
1891
1892status_t AudioFlinger::MmapThread::MmapTrack::start(AudioSystem::sync_event_t event __unused,
1893                                                        audio_session_t triggerSession __unused)
1894{
1895    return NO_ERROR;
1896}
1897
1898void AudioFlinger::MmapThread::MmapTrack::stop()
1899{
1900}
1901
1902// AudioBufferProvider interface
1903status_t AudioFlinger::MmapThread::MmapTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
1904{
1905    buffer->frameCount = 0;
1906    buffer->raw = nullptr;
1907    return INVALID_OPERATION;
1908}
1909
1910// ExtendedAudioBufferProvider interface
1911size_t AudioFlinger::MmapThread::MmapTrack::framesReady() const {
1912    return 0;
1913}
1914
1915int64_t AudioFlinger::MmapThread::MmapTrack::framesReleased() const
1916{
1917    return 0;
1918}
1919
1920void AudioFlinger::MmapThread::MmapTrack::onTimestamp(const ExtendedTimestamp &timestamp __unused)
1921{
1922}
1923
1924/*static*/ void AudioFlinger::MmapThread::MmapTrack::appendDumpHeader(String8& result)
1925{
1926    result.append("Client Session   Format Chn mask  SRate\n");
1927}
1928
1929void AudioFlinger::MmapThread::MmapTrack::appendDump(String8& result, bool active __unused)
1930{
1931    result.appendFormat("%6u %7u %08X %08X %6u\n",
1932            mPid,
1933            mSessionId,
1934            mFormat,
1935            mChannelMask,
1936            mSampleRate);
1937}
1938
1939} // namespace android
1940