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

Commit 35160cf7 authored by Eric Laurent's avatar Eric Laurent Committed by android-build-team Robot
Browse files

Revert "refactor AudioRecord and AudioFlinger openRecord()"

This reverts commit 3e1acc0c.

bug: 70388312

Change-Id: I6782d6eceeece1bad998b02af26c0119da70a13d
(cherry picked from commit 0aa3c6eb)
parent f1212249
Loading
Loading
Loading
Loading
+174 −104
Original line number Original line Diff line number Diff line
@@ -69,7 +69,8 @@ AudioRecord::AudioRecord(const String16 &opPackageName)
    : mActive(false), mStatus(NO_INIT), mOpPackageName(opPackageName),
    : mActive(false), mStatus(NO_INIT), mOpPackageName(opPackageName),
      mSessionId(AUDIO_SESSION_ALLOCATE),
      mSessionId(AUDIO_SESSION_ALLOCATE),
      mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT),
      mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT),
      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE)
      mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), mRoutedDeviceId(AUDIO_PORT_HANDLE_NONE),
      mPortId(AUDIO_PORT_HANDLE_NONE)
{
{
}
}


@@ -96,9 +97,10 @@ AudioRecord::AudioRecord(
      mSessionId(AUDIO_SESSION_ALLOCATE),
      mSessionId(AUDIO_SESSION_ALLOCATE),
      mPreviousPriority(ANDROID_PRIORITY_NORMAL),
      mPreviousPriority(ANDROID_PRIORITY_NORMAL),
      mPreviousSchedulingGroup(SP_DEFAULT),
      mPreviousSchedulingGroup(SP_DEFAULT),
      mProxy(NULL)
      mProxy(NULL),
      mPortId(AUDIO_PORT_HANDLE_NONE)
{
{
    (void)set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user,
    mStatus = set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user,
            notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags,
            notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags,
            uid, pid, pAttributes, selectedDeviceId);
            uid, pid, pAttributes, selectedDeviceId);
}
}
@@ -149,11 +151,6 @@ status_t AudioRecord::set(
        const audio_attributes_t* pAttributes,
        const audio_attributes_t* pAttributes,
        audio_port_handle_t selectedDeviceId)
        audio_port_handle_t selectedDeviceId)
{
{
    status_t status = NO_ERROR;
    uint32_t channelCount;
    pid_t callingPid;
    pid_t myPid;

    ALOGV("set(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
    ALOGV("set(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
          "notificationFrames %u, sessionId %d, transferType %d, flags %#x, opPackageName %s "
          "notificationFrames %u, sessionId %d, transferType %d, flags %#x, opPackageName %s "
          "uid %d, pid %d",
          "uid %d, pid %d",
@@ -173,8 +170,7 @@ status_t AudioRecord::set(
    case TRANSFER_CALLBACK:
    case TRANSFER_CALLBACK:
        if (cbf == NULL) {
        if (cbf == NULL) {
            ALOGE("Transfer type TRANSFER_CALLBACK but cbf == NULL");
            ALOGE("Transfer type TRANSFER_CALLBACK but cbf == NULL");
            status = BAD_VALUE;
            return BAD_VALUE;
            goto exit;
        }
        }
        break;
        break;
    case TRANSFER_OBTAIN:
    case TRANSFER_OBTAIN:
@@ -182,16 +178,14 @@ status_t AudioRecord::set(
        break;
        break;
    default:
    default:
        ALOGE("Invalid transfer type %d", transferType);
        ALOGE("Invalid transfer type %d", transferType);
        status = BAD_VALUE;
        return BAD_VALUE;
        goto exit;
    }
    }
    mTransfer = transferType;
    mTransfer = transferType;


    // invariant that mAudioRecord != 0 is true only after set() returns successfully
    // invariant that mAudioRecord != 0 is true only after set() returns successfully
    if (mAudioRecord != 0) {
    if (mAudioRecord != 0) {
        ALOGE("Track already in use");
        ALOGE("Track already in use");
        status = INVALID_OPERATION;
        return INVALID_OPERATION;
        goto exit;
    }
    }


    if (pAttributes == NULL) {
    if (pAttributes == NULL) {
@@ -215,18 +209,16 @@ status_t AudioRecord::set(
    // AudioFlinger capture only supports linear PCM
    // AudioFlinger capture only supports linear PCM
    if (!audio_is_valid_format(format) || !audio_is_linear_pcm(format)) {
    if (!audio_is_valid_format(format) || !audio_is_linear_pcm(format)) {
        ALOGE("Format %#x is not linear pcm", format);
        ALOGE("Format %#x is not linear pcm", format);
        status = BAD_VALUE;
        return BAD_VALUE;
        goto exit;
    }
    }
    mFormat = format;
    mFormat = format;


    if (!audio_is_input_channel(channelMask)) {
    if (!audio_is_input_channel(channelMask)) {
        ALOGE("Invalid channel mask %#x", channelMask);
        ALOGE("Invalid channel mask %#x", channelMask);
        status = BAD_VALUE;
        return BAD_VALUE;
        goto exit;
    }
    }
    mChannelMask = channelMask;
    mChannelMask = channelMask;
    channelCount = audio_channel_count_from_in_mask(channelMask);
    uint32_t channelCount = audio_channel_count_from_in_mask(channelMask);
    mChannelCount = channelCount;
    mChannelCount = channelCount;


    if (audio_is_linear_pcm(format)) {
    if (audio_is_linear_pcm(format)) {
@@ -235,24 +227,28 @@ status_t AudioRecord::set(
        mFrameSize = sizeof(uint8_t);
        mFrameSize = sizeof(uint8_t);
    }
    }


    // mFrameCount is initialized in createRecord_l
    // mFrameCount is initialized in openRecord_l
    mReqFrameCount = frameCount;
    mReqFrameCount = frameCount;


    mNotificationFramesReq = notificationFrames;
    mNotificationFramesReq = notificationFrames;
    // mNotificationFramesAct is initialized in createRecord_l
    // mNotificationFramesAct is initialized in openRecord_l


    if (sessionId == AUDIO_SESSION_ALLOCATE) {
        mSessionId = (audio_session_t) AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
    } else {
        mSessionId = sessionId;
        mSessionId = sessionId;
    }
    ALOGV("set(): mSessionId %d", mSessionId);
    ALOGV("set(): mSessionId %d", mSessionId);


    callingPid = IPCThreadState::self()->getCallingPid();
    int callingpid = IPCThreadState::self()->getCallingPid();
    myPid = getpid();
    int mypid = getpid();
    if (uid == AUDIO_UID_INVALID || (callingPid != myPid)) {
    if (uid == AUDIO_UID_INVALID || (callingpid != mypid)) {
        mClientUid = IPCThreadState::self()->getCallingUid();
        mClientUid = IPCThreadState::self()->getCallingUid();
    } else {
    } else {
        mClientUid = uid;
        mClientUid = uid;
    }
    }
    if (pid == -1 || (callingPid != myPid)) {
    if (pid == -1 || (callingpid != mypid)) {
        mClientPid = callingPid;
        mClientPid = callingpid;
    } else {
    } else {
        mClientPid = pid;
        mClientPid = pid;
    }
    }
@@ -267,7 +263,7 @@ status_t AudioRecord::set(
    }
    }


    // create the IAudioRecord
    // create the IAudioRecord
    status = createRecord_l(0 /*epoch*/, mOpPackageName);
    status_t status = openRecord_l(0 /*epoch*/, mOpPackageName);


    if (status != NO_ERROR) {
    if (status != NO_ERROR) {
        if (mAudioRecordThread != 0) {
        if (mAudioRecordThread != 0) {
@@ -275,9 +271,10 @@ status_t AudioRecord::set(
            mAudioRecordThread->requestExitAndWait();
            mAudioRecordThread->requestExitAndWait();
            mAudioRecordThread.clear();
            mAudioRecordThread.clear();
        }
        }
        goto exit;
        return status;
    }
    }


    mStatus = NO_ERROR;
    mUserData = user;
    mUserData = user;
    // TODO: add audio hardware input latency here
    // TODO: add audio hardware input latency here
    mLatency = (1000LL * mFrameCount) / mSampleRate;
    mLatency = (1000LL * mFrameCount) / mSampleRate;
@@ -292,9 +289,7 @@ status_t AudioRecord::set(
    mFramesRead = 0;
    mFramesRead = 0;
    mFramesReadServerOffset = 0;
    mFramesReadServerOffset = 0;


exit:
    return NO_ERROR;
    mStatus = status;
    return status;
}
}


// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
@@ -545,29 +540,70 @@ const char * AudioRecord::convertTransferToText(transfer_type transferType) {
}
}


// must be called with mLock held
// must be called with mLock held
status_t AudioRecord::createRecord_l(const Modulo<uint32_t> &epoch, const String16& opPackageName)
status_t AudioRecord::openRecord_l(const Modulo<uint32_t> &epoch, const String16& opPackageName)
{
{
    const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
    const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
    IAudioFlinger::CreateRecordInput input;
    IAudioFlinger::CreateRecordOutput output;
    audio_session_t originalSessionId;
    sp<media::IAudioRecord> record;
    void *iMemPointer;
    audio_track_cblk_t* cblk;
    status_t status;

    if (audioFlinger == 0) {
    if (audioFlinger == 0) {
        ALOGE("Could not get audioflinger");
        ALOGE("Could not get audioflinger");
        status = NO_INIT;
        return NO_INIT;
        goto exit;
    }
    }


    audio_io_handle_t input;

    // mFlags (not mOrigFlags) is modified depending on whether fast request is accepted.
    // mFlags (not mOrigFlags) is modified depending on whether fast request is accepted.
    // After fast request is denied, we will request again if IAudioRecord is re-created.
    // After fast request is denied, we will request again if IAudioRecord is re-created.


    status_t status;

    // Not a conventional loop, but a retry loop for at most two iterations total.
    // Try first maybe with FAST flag then try again without FAST flag if that fails.
    // Exits loop normally via a return at the bottom, or with error via a break.
    // The sp<> references will be dropped when re-entering scope.
    // The lack of indentation is deliberate, to reduce code churn and ease merges.
    for (;;) {
    audio_config_base_t config  = {
            .sample_rate = mSampleRate,
            .channel_mask = mChannelMask,
            .format = mFormat
        };
    mRoutedDeviceId = mSelectedDeviceId;
    status = AudioSystem::getInputForAttr(&mAttributes, &input,
                                        mSessionId,
                                        // FIXME compare to AudioTrack
                                        mClientPid,
                                        mClientUid,
                                        &config,
                                        mFlags, &mRoutedDeviceId, &mPortId);

    if (status != NO_ERROR || input == AUDIO_IO_HANDLE_NONE) {
        ALOGE("Could not get audio input for session %d, record source %d, sample rate %u, "
              "format %#x, channel mask %#x, flags %#x",
              mSessionId, mAttributes.source, mSampleRate, mFormat, mChannelMask, mFlags);
        return BAD_VALUE;
    }

    // Now that we have a reference to an I/O handle and have not yet handed it off to AudioFlinger,
    // Now that we have a reference to an I/O handle and have not yet handed it off to AudioFlinger,
    // we must release it ourselves if anything goes wrong.
    // we must release it ourselves if anything goes wrong.


#if 0
    size_t afFrameCount;
    status = AudioSystem::getFrameCount(input, &afFrameCount);
    if (status != NO_ERROR) {
        ALOGE("getFrameCount(input=%d) status %d", input, status);
        break;
    }
#endif

    uint32_t afSampleRate;
    status = AudioSystem::getSamplingRate(input, &afSampleRate);
    if (status != NO_ERROR) {
        ALOGE("getSamplingRate(input=%d) status %d", input, status);
        break;
    }
    if (mSampleRate == 0) {
        mSampleRate = afSampleRate;
    }

    // Client can only express a preference for FAST.  Server will perform additional tests.
    // Client can only express a preference for FAST.  Server will perform additional tests.
    if (mFlags & AUDIO_INPUT_FLAG_FAST) {
    if (mFlags & AUDIO_INPUT_FLAG_FAST) {
        bool useCaseAllowed =
        bool useCaseAllowed =
@@ -586,41 +622,66 @@ status_t AudioRecord::createRecord_l(const Modulo<uint32_t> &epoch, const String
        if (!useCaseAllowed) {
        if (!useCaseAllowed) {
            ALOGW("AUDIO_INPUT_FLAG_FAST denied, incompatible transfer = %s",
            ALOGW("AUDIO_INPUT_FLAG_FAST denied, incompatible transfer = %s",
                  convertTransferToText(mTransfer));
                  convertTransferToText(mTransfer));
        }

        // sample rates must also match
        bool sampleRateAllowed = mSampleRate == afSampleRate;
        if (!sampleRateAllowed) {
            ALOGW("AUDIO_INPUT_FLAG_FAST denied, rates do not match %u Hz, require %u Hz",
                  mSampleRate, afSampleRate);
        }

        bool fastAllowed = useCaseAllowed && sampleRateAllowed;
        if (!fastAllowed) {
            mFlags = (audio_input_flags_t) (mFlags & ~(AUDIO_INPUT_FLAG_FAST |
            mFlags = (audio_input_flags_t) (mFlags & ~(AUDIO_INPUT_FLAG_FAST |
                    AUDIO_INPUT_FLAG_RAW));
                    AUDIO_INPUT_FLAG_RAW));
            AudioSystem::releaseInput(input, mSessionId);
            continue;   // retry
        }
        }
    }
    }


    input.attr = mAttributes;
    // The notification frame count is the period between callbacks, as suggested by the client
    input.config.sample_rate = mSampleRate;
    // but moderated by the server.  For record, the calculations are done entirely on server side.
    input.config.channel_mask = mChannelMask;
    size_t notificationFrames = mNotificationFramesReq;
    input.config.format = mFormat;
    size_t frameCount = mReqFrameCount;
    input.clientInfo.clientUid = mClientUid;

    input.clientInfo.clientPid = mClientPid;
    audio_input_flags_t flags = mFlags;
    input.clientInfo.clientTid = -1;

    pid_t tid = -1;
    if (mFlags & AUDIO_INPUT_FLAG_FAST) {
    if (mFlags & AUDIO_INPUT_FLAG_FAST) {
        if (mAudioRecordThread != 0) {
        if (mAudioRecordThread != 0) {
            input.clientInfo.clientTid = mAudioRecordThread->getTid();
            tid = mAudioRecordThread->getTid();
        }
        }
    }
    }
    input.opPackageName = opPackageName;


    input.flags = mFlags;
    size_t temp = frameCount;   // temp may be replaced by a revised value of frameCount,
    // The notification frame count is the period between callbacks, as suggested by the client
                                // but we will still need the original value also
    // but moderated by the server.  For record, the calculations are done entirely on server side.
    audio_session_t originalSessionId = mSessionId;
    input.frameCount = mReqFrameCount;
    input.notificationFrameCount = mNotificationFramesReq;
    input.selectedDeviceId = mSelectedDeviceId;
    input.sessionId = mSessionId;
    originalSessionId = mSessionId;


    record = audioFlinger->createRecord(input,
    sp<IMemory> iMem;           // for cblk
                                                              output,
    sp<IMemory> bufferMem;
                                                              &status);
    sp<media::IAudioRecord> record = audioFlinger->openRecord(input,
                                                              mSampleRate,
                                                              mFormat,
                                                              mChannelMask,
                                                              opPackageName,
                                                              &temp,
                                                              &flags,
                                                              mClientPid,
                                                              tid,
                                                              mClientUid,
                                                              &mSessionId,
                                                              &notificationFrames,
                                                              iMem,
                                                              bufferMem,
                                                              &status,
                                                              mPortId);
    ALOGE_IF(originalSessionId != AUDIO_SESSION_ALLOCATE && mSessionId != originalSessionId,
            "session ID changed from %d to %d", originalSessionId, mSessionId);


    if (status != NO_ERROR) {
    if (status != NO_ERROR) {
        ALOGE("AudioFlinger could not create record track, status: %d", status);
        ALOGE("AudioFlinger could not create record track, status: %d", status);
        goto exit;
        break;
    }
    }
    ALOG_ASSERT(record != 0);
    ALOG_ASSERT(record != 0);


@@ -628,41 +689,41 @@ status_t AudioRecord::createRecord_l(const Modulo<uint32_t> &epoch, const String
    // so we are no longer responsible for releasing it.
    // so we are no longer responsible for releasing it.


    mAwaitBoost = false;
    mAwaitBoost = false;
    if (output.flags & AUDIO_INPUT_FLAG_FAST) {
    if (mFlags & AUDIO_INPUT_FLAG_FAST) {
        ALOGI("AUDIO_INPUT_FLAG_FAST successful; frameCount %zu -> %zu",
        if (flags & AUDIO_INPUT_FLAG_FAST) {
              mReqFrameCount, output.frameCount);
            ALOGI("AUDIO_INPUT_FLAG_FAST successful; frameCount %zu -> %zu", frameCount, temp);
            mAwaitBoost = true;
            mAwaitBoost = true;
        } else {
            ALOGW("AUDIO_INPUT_FLAG_FAST denied by server; frameCount %zu -> %zu", frameCount, temp);
            mFlags = (audio_input_flags_t) (mFlags & ~(AUDIO_INPUT_FLAG_FAST |
                    AUDIO_INPUT_FLAG_RAW));
            continue;   // retry
        }
    }
    }
    mFlags = output.flags;
    mFlags = flags;
    mRoutedDeviceId = output.selectedDeviceId;
    mSessionId = output.sessionId;
    mSampleRate = output.sampleRate;


    if (output.cblk == 0) {
    if (iMem == 0) {
        ALOGE("Could not get control block");
        ALOGE("Could not get control block");
        status = NO_INIT;
        return NO_INIT;
        goto exit;
    }
    }
    iMemPointer = output.cblk ->pointer();
    void *iMemPointer = iMem->pointer();
    if (iMemPointer == NULL) {
    if (iMemPointer == NULL) {
        ALOGE("Could not get control block pointer");
        ALOGE("Could not get control block pointer");
        status = NO_INIT;
        return NO_INIT;
        goto exit;
    }
    }
    cblk = static_cast<audio_track_cblk_t*>(iMemPointer);
    audio_track_cblk_t* cblk = static_cast<audio_track_cblk_t*>(iMemPointer);


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


@@ -672,42 +733,43 @@ status_t AudioRecord::createRecord_l(const Modulo<uint32_t> &epoch, const String
        mDeathNotifier.clear();
        mDeathNotifier.clear();
    }
    }
    mAudioRecord = record;
    mAudioRecord = record;
    mCblkMemory = output.cblk;
    mCblkMemory = iMem;
    mBufferMemory = output.buffers;
    mBufferMemory = bufferMem;
    IPCThreadState::self()->flushCommands();
    IPCThreadState::self()->flushCommands();


    mCblk = cblk;
    mCblk = cblk;
    // note that output.frameCount is the (possibly revised) value of mReqFrameCount
    // note that temp is the (possibly revised) value of frameCount
    if (output.frameCount < mReqFrameCount || (mReqFrameCount == 0 && output.frameCount == 0)) {
    if (temp < frameCount || (frameCount == 0 && temp == 0)) {
        ALOGW("Requested frameCount %zu but received frameCount %zu",
        ALOGW("Requested frameCount %zu but received frameCount %zu", frameCount, temp);
              mReqFrameCount,  output.frameCount);
    }
    }
    frameCount = temp;


    // Make sure that application is notified with sufficient margin before overrun.
    // Make sure that application is notified with sufficient margin before overrun.
    // The computation is done on server side.
    // The computation is done on server side.
    if (mNotificationFramesReq > 0 && output.notificationFrameCount != mNotificationFramesReq) {
    if (mNotificationFramesReq > 0 && notificationFrames != mNotificationFramesReq) {
        ALOGW("Server adjusted notificationFrames from %u to %zu for frameCount %zu",
        ALOGW("Server adjusted notificationFrames from %u to %zu for frameCount %zu",
                mNotificationFramesReq, output.notificationFrameCount, output.frameCount);
                mNotificationFramesReq, notificationFrames, frameCount);
    }
    }
    mNotificationFramesAct = (uint32_t)output.notificationFrameCount;
    mNotificationFramesAct = (uint32_t) notificationFrames;



    //mInput != input includes the case where mInput == AUDIO_IO_HANDLE_NONE for first creation
    //mInput != input includes the case where mInput == AUDIO_IO_HANDLE_NONE for first creation
    if (mDeviceCallback != 0 && mInput != output.inputId) {
    if (mDeviceCallback != 0 && mInput != input) {
        if (mInput != AUDIO_IO_HANDLE_NONE) {
        if (mInput != AUDIO_IO_HANDLE_NONE) {
            AudioSystem::removeAudioDeviceCallback(this, mInput);
            AudioSystem::removeAudioDeviceCallback(this, mInput);
        }
        }
        AudioSystem::addAudioDeviceCallback(this, output.inputId);
        AudioSystem::addAudioDeviceCallback(this, input);
    }
    }


    // We retain a copy of the I/O handle, but don't own the reference
    // We retain a copy of the I/O handle, but don't own the reference
    mInput = output.inputId;
    mInput = input;
    mRefreshRemaining = true;
    mRefreshRemaining = true;


    mFrameCount = output.frameCount;
    mFrameCount = frameCount;
    // If IAudioRecord is re-created, don't let the requested frameCount
    // If IAudioRecord is re-created, don't let the requested frameCount
    // decrease.  This can confuse clients that cache frameCount().
    // decrease.  This can confuse clients that cache frameCount().
    if (mFrameCount > mReqFrameCount) {
    if (frameCount > mReqFrameCount) {
        mReqFrameCount = mFrameCount;
        mReqFrameCount = frameCount;
    }
    }


    // update proxy
    // update proxy
@@ -718,9 +780,17 @@ status_t AudioRecord::createRecord_l(const Modulo<uint32_t> &epoch, const String
    mDeathNotifier = new DeathNotifier(this);
    mDeathNotifier = new DeathNotifier(this);
    IInterface::asBinder(mAudioRecord)->linkToDeath(mDeathNotifier, this);
    IInterface::asBinder(mAudioRecord)->linkToDeath(mDeathNotifier, this);


exit:
    return NO_ERROR;
    mStatus = status;

    // sp<IAudioTrack> track destructor will cause releaseOutput() to be called by AudioFlinger
    // End of retry loop.
    // The lack of indentation is deliberate, to reduce code churn and ease merges.
    }

// Arrive here on error, via a break
    AudioSystem::releaseInput(input, mSessionId);
    if (status == NO_ERROR) {
        status = NO_INIT;
    }
    return status;
    return status;
}
}


@@ -1152,12 +1222,12 @@ status_t AudioRecord::restoreRecord_l(const char *from)


    mFlags = mOrigFlags;
    mFlags = mOrigFlags;


    // if the new IAudioRecord is created, createRecord_l() will modify the
    // if the new IAudioRecord is created, openRecord_l() will modify the
    // following member variables: mAudioRecord, mCblkMemory, mCblk, mBufferMemory.
    // following member variables: mAudioRecord, mCblkMemory, mCblk, mBufferMemory.
    // It will also delete the strong references on previous IAudioRecord and IMemory
    // It will also delete the strong references on previous IAudioRecord and IMemory
    Modulo<uint32_t> position(mProxy->getPosition());
    Modulo<uint32_t> position(mProxy->getPosition());
    mNewPosition = position + mUpdatePeriod;
    mNewPosition = position + mUpdatePeriod;
    status_t result = createRecord_l(position, mOpPackageName);
    status_t result = openRecord_l(position, mOpPackageName);
    if (result == NO_ERROR) {
    if (result == NO_ERROR) {
        if (mActive) {
        if (mActive) {
            // callback thread or sync event hasn't changed
            // callback thread or sync event hasn't changed
+117 −46

File changed.

Preview size limit exceeded, changes collapsed.

+0 −1
Original line number Original line Diff line number Diff line
@@ -16,7 +16,6 @@


package android.media;
package android.media;


/* Native code must specify namespace media (media::IAudioRecord) when referring to this class */
interface IAudioRecord {
interface IAudioRecord {


  /* After it's created the track is not active. Call start() to
  /* After it's created the track is not active. Call start() to
+3 −4
Original line number Original line Diff line number Diff line
@@ -19,13 +19,12 @@
#define ANDROID_AUDIO_CLIENT_H
#define ANDROID_AUDIO_CLIENT_H


#include <binder/Parcel.h>
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
#include <system/audio.h>
#include <system/audio.h>
#include <utils/String16.h>
#include <utils/String16.h>


namespace android {
namespace android {


class AudioClient : public Parcelable {
class AudioClient {
 public:
 public:
    AudioClient() :
    AudioClient() :
        clientUid(-1), clientPid(-1), clientTid(-1), packageName("") {}
        clientUid(-1), clientPid(-1), clientTid(-1), packageName("") {}
@@ -35,7 +34,7 @@ class AudioClient : public Parcelable {
    pid_t clientTid;
    pid_t clientTid;
    String16 packageName;
    String16 packageName;


    status_t readFromParcel(const Parcel *parcel) override {
    status_t readFromParcel(Parcel *parcel) {
        clientUid = parcel->readInt32();
        clientUid = parcel->readInt32();
        clientPid = parcel->readInt32();
        clientPid = parcel->readInt32();
        clientTid = parcel->readInt32();
        clientTid = parcel->readInt32();
@@ -43,7 +42,7 @@ class AudioClient : public Parcelable {
        return NO_ERROR;
        return NO_ERROR;
    }
    }


    status_t writeToParcel(Parcel *parcel) const override {
    status_t writeToParcel(Parcel *parcel) const {
        parcel->writeInt32(clientUid);
        parcel->writeInt32(clientUid);
        parcel->writeInt32(clientPid);
        parcel->writeInt32(clientPid);
        parcel->writeInt32(clientTid);
        parcel->writeInt32(clientTid);
+2 −1
Original line number Original line Diff line number Diff line
@@ -570,7 +570,7 @@ private:


            // caller must hold lock on mLock for all _l methods
            // caller must hold lock on mLock for all _l methods


            status_t createRecord_l(const Modulo<uint32_t> &epoch, const String16& opPackageName);
            status_t openRecord_l(const Modulo<uint32_t> &epoch, const String16& opPackageName);


            // FIXME enum is faster than strcmp() for parameter 'from'
            // FIXME enum is faster than strcmp() for parameter 'from'
            status_t restoreRecord_l(const char *from);
            status_t restoreRecord_l(const char *from);
@@ -682,6 +682,7 @@ private:
                                              // May not match the app selection depending on other
                                              // May not match the app selection depending on other
                                              // activity and connected devices
                                              // activity and connected devices
    wp<AudioSystem::AudioDeviceCallback> mDeviceCallback;
    wp<AudioSystem::AudioDeviceCallback> mDeviceCallback;
    audio_port_handle_t    mPortId;  // unique ID allocated by audio policy


};
};


Loading