Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 16821ec9 authored by Glenn Kasten's avatar Glenn Kasten Committed by Android (Google) Code Review
Browse files

Merge "IAudioFlinger::openRecord returns IMemory(s)"

parents 01427884 d776ac63
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -490,10 +490,12 @@ private:
    int                     mSessionId;
    transfer_type           mTransfer;

    // Next 4 fields may be changed if IAudioRecord is re-created, but always != 0
    // Next 5 fields may be changed if IAudioRecord is re-created, but always != 0
    // provided the initial set() was successful
    sp<IAudioRecord>        mAudioRecord;
    sp<IMemory>             mCblkMemory;
    audio_track_cblk_t*     mCblk;              // re-load after mLock.unlock()
    sp<IMemory>             mBufferMemory;
    audio_io_handle_t       mInput;             // returned by AudioSystem::getInput()

    int                     mPreviousPriority;  // before start()
+2 −0
Original line number Diff line number Diff line
@@ -88,6 +88,8 @@ public:
                                track_flags_t *flags,
                                pid_t tid,  // -1 means unused, otherwise must be valid non-0
                                int *sessionId,
                                sp<IMemory>& cblk,
                                sp<IMemory>& buffers,   // return value 0 means it follows cblk
                                status_t *status) = 0;

    /* query the audio hardware state. This state never changes,
+24 −8
Original line number Diff line number Diff line
@@ -484,6 +484,8 @@ status_t AudioRecord::openRecord_l(size_t epoch)
    size_t temp = frameCount;   // temp may be replaced by a revised value of frameCount,
                                // but we will still need the original value also
    int originalSessionId = mSessionId;
    sp<IMemory> iMem;           // for cblk
    sp<IMemory> bufferMem;
    sp<IAudioRecord> record = audioFlinger->openRecord(input,
                                                       mSampleRate, mFormat,
                                                       mChannelMask,
@@ -491,6 +493,8 @@ status_t AudioRecord::openRecord_l(size_t epoch)
                                                       &trackFlags,
                                                       tid,
                                                       &mSessionId,
                                                       iMem,
                                                       bufferMem,
                                                       &status);
    ALOGE_IF(originalSessionId != AUDIO_SESSION_ALLOCATE && mSessionId != originalSessionId,
            "session ID changed from %d to %d", originalSessionId, mSessionId);
@@ -504,7 +508,6 @@ status_t AudioRecord::openRecord_l(size_t epoch)
    // AudioFlinger now owns the reference to the I/O handle,
    // so we are no longer responsible for releasing it.

    sp<IMemory> iMem = record->getCblk();
    if (iMem == 0) {
        ALOGE("Could not get control block");
        return NO_INIT;
@@ -514,6 +517,22 @@ status_t AudioRecord::openRecord_l(size_t epoch)
        ALOGE("Could not get control block pointer");
        return NO_INIT;
    }
    audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMemPointer);

    // Starting address of buffers in shared memory.
    // The buffers are either immediately after the control block,
    // or in a separate area at discretion of server.
    void *buffers;
    if (bufferMem == 0) {
        buffers = cblk + 1;
    } else {
        buffers = bufferMem->pointer();
        if (buffers == NULL) {
            ALOGE("Could not get buffer pointer");
            return NO_INIT;
        }
    }

    // invariant that mAudioRecord != 0 is true only after set() returns successfully
    if (mAudioRecord != 0) {
        mAudioRecord->asBinder()->unlinkToDeath(mDeathNotifier, this);
@@ -522,7 +541,7 @@ status_t AudioRecord::openRecord_l(size_t epoch)
    mAudioRecord = record;

    mCblkMemory = iMem;
    audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMemPointer);
    mBufferMemory = bufferMem;
    mCblk = cblk;
    // note that temp is the (possibly revised) value of frameCount
    if (temp < frameCount || (frameCount == 0 && temp == 0)) {
@@ -552,11 +571,6 @@ status_t AudioRecord::openRecord_l(size_t epoch)
    mInput = input;
    mRefreshRemaining = true;

    // Starting address of buffers in shared memory, immediately after the control block.  This
    // address is for the mapping within client address space.  AudioFlinger::TrackBase::mBuffer
    // is for the server address space.
    void *buffers = (char*)cblk + sizeof(audio_track_cblk_t);

    mFrameCount = frameCount;
    // If IAudioRecord is re-created, don't let the requested frameCount
    // decrease.  This can confuse clients that cache frameCount().
@@ -631,6 +645,7 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, const struct timespec *r
        // keep them from going away if another thread re-creates the track during obtainBuffer()
        sp<AudioRecordClientProxy> proxy;
        sp<IMemory> iMem;
        sp<IMemory> bufferMem;
        {
            // start of lock scope
            AutoMutex lock(mLock);
@@ -654,6 +669,7 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, const struct timespec *r
            // Keep the extra references
            proxy = mProxy;
            iMem = mCblkMemory;
            bufferMem = mBufferMemory;

            // Non-blocking if track is stopped
            if (!mActive) {
@@ -986,7 +1002,7 @@ status_t AudioRecord::restoreRecord_l(const char *from)
    status_t result;

    // if the new IAudioRecord is created, openRecord_l() will modify the
    // following member variables: mAudioRecord, mCblkMemory and mCblk.
    // following member variables: mAudioRecord, mCblkMemory, mCblk, mBufferMemory.
    // It will also delete the strong references on previous IAudioRecord and IMemory
    size_t position = mProxy->getPosition();
    mNewPosition = position + mUpdatePeriod;
+30 −4
Original line number Diff line number Diff line
@@ -169,6 +169,8 @@ public:
                                track_flags_t *flags,
                                pid_t tid,
                                int *sessionId,
                                sp<IMemory>& cblk,
                                sp<IMemory>& buffers,
                                status_t *status)
    {
        Parcel data, reply;
@@ -188,6 +190,8 @@ public:
            lSessionId = *sessionId;
        }
        data.writeInt32(lSessionId);
        cblk.clear();
        buffers.clear();
        status_t lStatus = remote()->transact(OPEN_RECORD, data, &reply);
        if (lStatus != NO_ERROR) {
            ALOGE("openRecord error: %s", strerror(-lStatus));
@@ -206,17 +210,34 @@ public:
            }
            lStatus = reply.readInt32();
            record = interface_cast<IAudioRecord>(reply.readStrongBinder());
            cblk = interface_cast<IMemory>(reply.readStrongBinder());
            if (cblk != 0 && cblk->pointer() == NULL) {
                cblk.clear();
            }
            buffers = interface_cast<IMemory>(reply.readStrongBinder());
            if (buffers != 0 && buffers->pointer() == NULL) {
                buffers.clear();
            }
            if (lStatus == NO_ERROR) {
                if (record == 0) {
                    ALOGE("openRecord should have returned an IAudioRecord");
                    lStatus = UNKNOWN_ERROR;
                } else if (cblk == 0) {
                    ALOGE("openRecord should have returned a cblk");
                    lStatus = NO_MEMORY;
                }
                // buffers is permitted to be 0
            } else {
                if (record != 0) {
                    ALOGE("openRecord returned an IAudioRecord but with status %d", lStatus);
                    record.clear();
                if (record != 0 || cblk != 0 || buffers != 0) {
                    ALOGE("openRecord returned an IAudioRecord, cblk, "
                          "or buffers but with status %d", lStatus);
                }
            }
            if (lStatus != NO_ERROR) {
                record.clear();
                cblk.clear();
                buffers.clear();
            }
        }
        if (status != NULL) {
            *status = lStatus;
@@ -838,15 +859,20 @@ status_t BnAudioFlinger::onTransact(
            track_flags_t flags = (track_flags_t) data.readInt32();
            pid_t tid = (pid_t) data.readInt32();
            int sessionId = data.readInt32();
            sp<IMemory> cblk;
            sp<IMemory> buffers;
            status_t status;
            sp<IAudioRecord> record = openRecord(input,
                    sampleRate, format, channelMask, &frameCount, &flags, tid, &sessionId, &status);
                    sampleRate, format, channelMask, &frameCount, &flags, tid, &sessionId,
                    cblk, buffers, &status);
            LOG_ALWAYS_FATAL_IF((record != 0) != (status == NO_ERROR));
            reply->writeInt64(frameCount);
            reply->writeInt32(flags);
            reply->writeInt32(sessionId);
            reply->writeInt32(status);
            reply->writeStrongBinder(record->asBinder());
            reply->writeStrongBinder(cblk->asBinder());
            reply->writeStrongBinder(buffers->asBinder());
            return NO_ERROR;
        } break;
        case SAMPLE_RATE: {
+8 −0
Original line number Diff line number Diff line
@@ -1313,6 +1313,8 @@ sp<IAudioRecord> AudioFlinger::openRecord(
        IAudioFlinger::track_flags_t *flags,
        pid_t tid,
        int *sessionId,
        sp<IMemory>& cblk,
        sp<IMemory>& buffers,
        status_t *status)
{
    sp<RecordThread::RecordTrack> recordTrack;
@@ -1321,6 +1323,9 @@ sp<IAudioRecord> AudioFlinger::openRecord(
    status_t lStatus;
    int lSessionId;

    cblk.clear();
    buffers.clear();

    // check calling permissions
    if (!recordingAllowed()) {
        ALOGE("openRecord() permission denied: recording not allowed");
@@ -1396,6 +1401,9 @@ sp<IAudioRecord> AudioFlinger::openRecord(
        goto Exit;
    }

    cblk = recordTrack->getCblk();
    buffers = recordTrack->getBuffers();

    // return handle to client
    recordHandle = new RecordHandle(recordTrack);

Loading