Merge changes Ia0217951,Ie8293036,Ic359e977,I9d939d17

* changes:
  audiopolicy: Refactor AudioPolicyManager::updateCallRouting
  audiopolicy: Remove ; after namespace bracket
  audiopolicy: Use C++11 atomics, factor out handle generation
  audiopolicy: Make fields of HwModule private
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index 741d084..2432cac 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -69,7 +69,8 @@
     : mActive(false), mStatus(NO_INIT), mOpPackageName(opPackageName),
       mSessionId(AUDIO_SESSION_ALLOCATE),
       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 @@
       mSessionId(AUDIO_SESSION_ALLOCATE),
       mPreviousPriority(ANDROID_PRIORITY_NORMAL),
       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,
             uid, pid, pAttributes, selectedDeviceId);
 }
@@ -149,11 +151,6 @@
         const audio_attributes_t* pAttributes,
         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, "
           "notificationFrames %u, sessionId %d, transferType %d, flags %#x, opPackageName %s "
           "uid %d, pid %d",
@@ -173,8 +170,7 @@
     case TRANSFER_CALLBACK:
         if (cbf == NULL) {
             ALOGE("Transfer type TRANSFER_CALLBACK but cbf == NULL");
-            status = BAD_VALUE;
-            goto exit;
+            return BAD_VALUE;
         }
         break;
     case TRANSFER_OBTAIN:
@@ -182,16 +178,14 @@
         break;
     default:
         ALOGE("Invalid transfer type %d", transferType);
-        status = BAD_VALUE;
-        goto exit;
+        return BAD_VALUE;
     }
     mTransfer = transferType;
 
     // invariant that mAudioRecord != 0 is true only after set() returns successfully
     if (mAudioRecord != 0) {
         ALOGE("Track already in use");
-        status = INVALID_OPERATION;
-        goto exit;
+        return INVALID_OPERATION;
     }
 
     if (pAttributes == NULL) {
@@ -215,18 +209,16 @@
     // AudioFlinger capture only supports linear PCM
     if (!audio_is_valid_format(format) || !audio_is_linear_pcm(format)) {
         ALOGE("Format %#x is not linear pcm", format);
-        status = BAD_VALUE;
-        goto exit;
+        return BAD_VALUE;
     }
     mFormat = format;
 
     if (!audio_is_input_channel(channelMask)) {
         ALOGE("Invalid channel mask %#x", channelMask);
-        status = BAD_VALUE;
-        goto exit;
+        return BAD_VALUE;
     }
     mChannelMask = channelMask;
-    channelCount = audio_channel_count_from_in_mask(channelMask);
+    uint32_t channelCount = audio_channel_count_from_in_mask(channelMask);
     mChannelCount = channelCount;
 
     if (audio_is_linear_pcm(format)) {
@@ -235,24 +227,28 @@
         mFrameSize = sizeof(uint8_t);
     }
 
-    // mFrameCount is initialized in createRecord_l
+    // mFrameCount is initialized in openRecord_l
     mReqFrameCount = frameCount;
 
     mNotificationFramesReq = notificationFrames;
-    // mNotificationFramesAct is initialized in createRecord_l
+    // mNotificationFramesAct is initialized in openRecord_l
 
-    mSessionId = sessionId;
+    if (sessionId == AUDIO_SESSION_ALLOCATE) {
+        mSessionId = (audio_session_t) AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
+    } else {
+        mSessionId = sessionId;
+    }
     ALOGV("set(): mSessionId %d", mSessionId);
 
-    callingPid = IPCThreadState::self()->getCallingPid();
-    myPid = getpid();
-    if (uid == AUDIO_UID_INVALID || (callingPid != myPid)) {
+    int callingpid = IPCThreadState::self()->getCallingPid();
+    int mypid = getpid();
+    if (uid == AUDIO_UID_INVALID || (callingpid != mypid)) {
         mClientUid = IPCThreadState::self()->getCallingUid();
     } else {
         mClientUid = uid;
     }
-    if (pid == -1 || (callingPid != myPid)) {
-        mClientPid = callingPid;
+    if (pid == -1 || (callingpid != mypid)) {
+        mClientPid = callingpid;
     } else {
         mClientPid = pid;
     }
@@ -267,7 +263,7 @@
     }
 
     // create the IAudioRecord
-    status = createRecord_l(0 /*epoch*/, mOpPackageName);
+    status_t status = openRecord_l(0 /*epoch*/, mOpPackageName);
 
     if (status != NO_ERROR) {
         if (mAudioRecordThread != 0) {
@@ -275,9 +271,10 @@
             mAudioRecordThread->requestExitAndWait();
             mAudioRecordThread.clear();
         }
-        goto exit;
+        return status;
     }
 
+    mStatus = NO_ERROR;
     mUserData = user;
     // TODO: add audio hardware input latency here
     mLatency = (1000LL * mFrameCount) / mSampleRate;
@@ -292,9 +289,7 @@
     mFramesRead = 0;
     mFramesReadServerOffset = 0;
 
-exit:
-    mStatus = status;
-    return status;
+    return NO_ERROR;
 }
 
 // -------------------------------------------------------------------------
@@ -545,29 +540,70 @@
 }
 
 // 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();
-    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) {
         ALOGE("Could not get audioflinger");
-        status = NO_INIT;
-        goto exit;
+        return NO_INIT;
     }
 
+    audio_io_handle_t input;
+
     // 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.
 
+    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,
     // 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.
     if (mFlags & AUDIO_INPUT_FLAG_FAST) {
         bool useCaseAllowed =
@@ -586,41 +622,66 @@
         if (!useCaseAllowed) {
             ALOGW("AUDIO_INPUT_FLAG_FAST denied, incompatible transfer = %s",
                   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 |
                     AUDIO_INPUT_FLAG_RAW));
+            AudioSystem::releaseInput(input, mSessionId);
+            continue;   // retry
         }
     }
 
-    input.attr = mAttributes;
-    input.config.sample_rate = mSampleRate;
-    input.config.channel_mask = mChannelMask;
-    input.config.format = mFormat;
-    input.clientInfo.clientUid = mClientUid;
-    input.clientInfo.clientPid = mClientPid;
-    input.clientInfo.clientTid = -1;
-    if (mFlags & AUDIO_INPUT_FLAG_FAST) {
-        if (mAudioRecordThread != 0) {
-            input.clientInfo.clientTid = mAudioRecordThread->getTid();
-        }
-    }
-    input.opPackageName = opPackageName;
-
-    input.flags = mFlags;
     // The notification frame count is the period between callbacks, as suggested by the client
     // but moderated by the server.  For record, the calculations are done entirely on server side.
-    input.frameCount = mReqFrameCount;
-    input.notificationFrameCount = mNotificationFramesReq;
-    input.selectedDeviceId = mSelectedDeviceId;
-    input.sessionId = mSessionId;
-    originalSessionId = mSessionId;
+    size_t notificationFrames = mNotificationFramesReq;
+    size_t frameCount = mReqFrameCount;
 
-    record = audioFlinger->createRecord(input,
-                                                              output,
-                                                              &status);
+    audio_input_flags_t flags = mFlags;
+
+    pid_t tid = -1;
+    if (mFlags & AUDIO_INPUT_FLAG_FAST) {
+        if (mAudioRecordThread != 0) {
+            tid = mAudioRecordThread->getTid();
+        }
+    }
+
+    size_t temp = frameCount;   // temp may be replaced by a revised value of frameCount,
+                                // but we will still need the original value also
+    audio_session_t originalSessionId = mSessionId;
+
+    sp<IMemory> iMem;           // for cblk
+    sp<IMemory> bufferMem;
+    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) {
         ALOGE("AudioFlinger could not create record track, status: %d", status);
-        goto exit;
+        break;
     }
     ALOG_ASSERT(record != 0);
 
@@ -628,41 +689,41 @@
     // so we are no longer responsible for releasing it.
 
     mAwaitBoost = false;
-    if (output.flags & AUDIO_INPUT_FLAG_FAST) {
-        ALOGI("AUDIO_INPUT_FLAG_FAST successful; frameCount %zu -> %zu",
-              mReqFrameCount, output.frameCount);
-        mAwaitBoost = true;
+    if (mFlags & AUDIO_INPUT_FLAG_FAST) {
+        if (flags & AUDIO_INPUT_FLAG_FAST) {
+            ALOGI("AUDIO_INPUT_FLAG_FAST successful; frameCount %zu -> %zu", frameCount, temp);
+            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;
-    mRoutedDeviceId = output.selectedDeviceId;
-    mSessionId = output.sessionId;
-    mSampleRate = output.sampleRate;
+    mFlags = flags;
 
-    if (output.cblk == 0) {
+    if (iMem == 0) {
         ALOGE("Could not get control block");
-        status = NO_INIT;
-        goto exit;
+        return NO_INIT;
     }
-    iMemPointer = output.cblk ->pointer();
+    void *iMemPointer = iMem->pointer();
     if (iMemPointer == NULL) {
         ALOGE("Could not get control block pointer");
-        status = NO_INIT;
-        goto exit;
+        return NO_INIT;
     }
-    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.
     // The buffers are either immediately after the control block,
     // or in a separate area at discretion of server.
     void *buffers;
-    if (output.buffers == 0) {
+    if (bufferMem == 0) {
         buffers = cblk + 1;
     } else {
-        buffers = output.buffers->pointer();
+        buffers = bufferMem->pointer();
         if (buffers == NULL) {
             ALOGE("Could not get buffer pointer");
-            status = NO_INIT;
-            goto exit;
+            return NO_INIT;
         }
     }
 
@@ -672,42 +733,43 @@
         mDeathNotifier.clear();
     }
     mAudioRecord = record;
-    mCblkMemory = output.cblk;
-    mBufferMemory = output.buffers;
+    mCblkMemory = iMem;
+    mBufferMemory = bufferMem;
     IPCThreadState::self()->flushCommands();
 
     mCblk = cblk;
-    // note that output.frameCount is the (possibly revised) value of mReqFrameCount
-    if (output.frameCount < mReqFrameCount || (mReqFrameCount == 0 && output.frameCount == 0)) {
-        ALOGW("Requested frameCount %zu but received frameCount %zu",
-              mReqFrameCount,  output.frameCount);
+    // note that temp is the (possibly revised) value of frameCount
+    if (temp < frameCount || (frameCount == 0 && temp == 0)) {
+        ALOGW("Requested frameCount %zu but received frameCount %zu", frameCount, temp);
     }
+    frameCount = temp;
 
     // Make sure that application is notified with sufficient margin before overrun.
     // 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",
-                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
-    if (mDeviceCallback != 0 && mInput != output.inputId) {
+    if (mDeviceCallback != 0 && mInput != input) {
         if (mInput != AUDIO_IO_HANDLE_NONE) {
             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
-    mInput = output.inputId;
+    mInput = input;
     mRefreshRemaining = true;
 
-    mFrameCount = output.frameCount;
+    mFrameCount = frameCount;
     // If IAudioRecord is re-created, don't let the requested frameCount
     // decrease.  This can confuse clients that cache frameCount().
-    if (mFrameCount > mReqFrameCount) {
-        mReqFrameCount = mFrameCount;
+    if (frameCount > mReqFrameCount) {
+        mReqFrameCount = frameCount;
     }
 
     // update proxy
@@ -718,9 +780,17 @@
     mDeathNotifier = new DeathNotifier(this);
     IInterface::asBinder(mAudioRecord)->linkToDeath(mDeathNotifier, this);
 
-exit:
-    mStatus = status;
-    // sp<IAudioTrack> track destructor will cause releaseOutput() to be called by AudioFlinger
+    return NO_ERROR;
+
+    // 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;
 }
 
@@ -1152,12 +1222,12 @@
 
     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.
     // It will also delete the strong references on previous IAudioRecord and IMemory
     Modulo<uint32_t> position(mProxy->getPosition());
     mNewPosition = position + mUpdatePeriod;
-    status_t result = createRecord_l(position, mOpPackageName);
+    status_t result = openRecord_l(position, mOpPackageName);
     if (result == NO_ERROR) {
         if (mActive) {
             // callback thread or sync event hasn't changed
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 56ddd4f..5cf2bdb 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -22,7 +22,6 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <binder/IPCThreadState.h>
 #include <binder/Parcel.h>
 
 #include "IAudioFlinger.h"
@@ -31,7 +30,7 @@
 
 enum {
     CREATE_TRACK = IBinder::FIRST_CALL_TRANSACTION,
-    CREATE_RECORD,
+    OPEN_RECORD,
     SAMPLE_RATE,
     RESERVED,   // obsolete, was CHANNEL_COUNT
     FORMAT,
@@ -131,39 +130,102 @@
         return track;
     }
 
-    virtual sp<media::IAudioRecord> createRecord(const CreateRecordInput& input,
-                                                 CreateRecordOutput& output,
-                                                 status_t *status)
+    virtual sp<media::IAudioRecord> openRecord(
+                                audio_io_handle_t input,
+                                uint32_t sampleRate,
+                                audio_format_t format,
+                                audio_channel_mask_t channelMask,
+                                const String16& opPackageName,
+                                size_t *pFrameCount,
+                                audio_input_flags_t *flags,
+                                pid_t pid,
+                                pid_t tid,
+                                int clientUid,
+                                audio_session_t *sessionId,
+                                size_t *notificationFrames,
+                                sp<IMemory>& cblk,
+                                sp<IMemory>& buffers,
+                                status_t *status,
+                                audio_port_handle_t portId)
     {
         Parcel data, reply;
         sp<media::IAudioRecord> record;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-
-        if (status == nullptr) {
-            return record;
+        data.writeInt32((int32_t) input);
+        data.writeInt32(sampleRate);
+        data.writeInt32(format);
+        data.writeInt32(channelMask);
+        data.writeString16(opPackageName);
+        size_t frameCount = pFrameCount != NULL ? *pFrameCount : 0;
+        data.writeInt64(frameCount);
+        audio_input_flags_t lFlags = flags != NULL ? *flags : AUDIO_INPUT_FLAG_NONE;
+        data.writeInt32(lFlags);
+        data.writeInt32((int32_t) pid);
+        data.writeInt32((int32_t) tid);
+        data.writeInt32((int32_t) clientUid);
+        audio_session_t lSessionId = AUDIO_SESSION_ALLOCATE;
+        if (sessionId != NULL) {
+            lSessionId = *sessionId;
         }
-
-        input.writeToParcel(&data);
-
-        status_t lStatus = remote()->transact(CREATE_RECORD, data, &reply);
+        data.writeInt32(lSessionId);
+        data.writeInt64(notificationFrames != NULL ? *notificationFrames : 0);
+        data.writeInt32(portId);
+        cblk.clear();
+        buffers.clear();
+        status_t lStatus = remote()->transact(OPEN_RECORD, data, &reply);
         if (lStatus != NO_ERROR) {
-            ALOGE("createRecord transaction error %d", lStatus);
-            *status = DEAD_OBJECT;
-            return record;
+            ALOGE("openRecord error: %s", strerror(-lStatus));
+        } else {
+            frameCount = reply.readInt64();
+            if (pFrameCount != NULL) {
+                *pFrameCount = frameCount;
+            }
+            lFlags = (audio_input_flags_t)reply.readInt32();
+            if (flags != NULL) {
+                *flags = lFlags;
+            }
+            lSessionId = (audio_session_t) reply.readInt32();
+            if (sessionId != NULL) {
+                *sessionId = lSessionId;
+            }
+            size_t lNotificationFrames = (size_t) reply.readInt64();
+            if (notificationFrames != NULL) {
+                *notificationFrames = lNotificationFrames;
+            }
+            lStatus = reply.readInt32();
+            record = interface_cast<media::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 || 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();
+            }
         }
-        *status = reply.readInt32();
-        if (*status != NO_ERROR) {
-            ALOGE("createRecord returned error %d", *status);
-            return record;
+        if (status != NULL) {
+            *status = lStatus;
         }
-
-        record = interface_cast<media::IAudioRecord>(reply.readStrongBinder());
-        if (record == 0) {
-            ALOGE("createRecord returned a NULL IAudioRecord with status OK");
-            *status = DEAD_OBJECT;
-            return record;
-        }
-        output.readFromParcel(&reply);
         return record;
     }
 
@@ -837,46 +899,21 @@
 status_t BnAudioFlinger::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
-    // make sure transactions reserved to AudioPolicyManager do not come from other processes
-    switch (code) {
-        case SET_STREAM_VOLUME:
-        case SET_STREAM_MUTE:
-        case SET_MODE:
-        case OPEN_OUTPUT:
-        case OPEN_DUPLICATE_OUTPUT:
-        case CLOSE_OUTPUT:
-        case SUSPEND_OUTPUT:
-        case RESTORE_OUTPUT:
-        case OPEN_INPUT:
-        case CLOSE_INPUT:
-        case INVALIDATE_STREAM:
-        case SET_VOICE_VOLUME:
-        case MOVE_EFFECTS:
-        case LOAD_HW_MODULE:
-        case LIST_AUDIO_PORTS:
-        case GET_AUDIO_PORT:
-        case CREATE_AUDIO_PATCH:
-        case RELEASE_AUDIO_PATCH:
-        case LIST_AUDIO_PATCHES:
-        case SET_AUDIO_PORT_CONFIG:
-            ALOGW("%s: transaction %d received from PID %d",
-                  __func__, code, IPCThreadState::self()->getCallingPid());
-            return INVALID_OPERATION;
-        default:
-            break;
-    }
-
     // Whitelist of relevant events to trigger log merging.
     // Log merging should activate during audio activity of any kind. This are considered the
     // most relevant events.
     // TODO should select more wisely the items from the list
     switch (code) {
         case CREATE_TRACK:
-        case CREATE_RECORD:
+        case OPEN_RECORD:
         case SET_MASTER_VOLUME:
         case SET_MASTER_MUTE:
+        case SET_STREAM_VOLUME:
+        case SET_STREAM_MUTE:
         case SET_MIC_MUTE:
         case SET_PARAMETERS:
+        case OPEN_INPUT:
+        case SET_VOICE_VOLUME:
         case CREATE_EFFECT:
         case SYSTEM_READY: {
             requestLogMerge();
@@ -885,7 +922,6 @@
         default:
             break;
     }
-
     switch (code) {
         case CREATE_TRACK: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
@@ -912,29 +948,37 @@
             output.writeToParcel(reply);
             return NO_ERROR;
         } break;
-        case CREATE_RECORD: {
+        case OPEN_RECORD: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
-
-            CreateRecordInput input;
-            if (input.readFromParcel((Parcel*)&data) != NO_ERROR) {
-                reply->writeInt32(DEAD_OBJECT);
-                return NO_ERROR;
-            }
-
-            status_t status;
-            CreateRecordOutput output;
-
-            sp<media::IAudioRecord> record = createRecord(input,
-                                                          output,
-                                                          &status);
-
+            audio_io_handle_t input = (audio_io_handle_t) data.readInt32();
+            uint32_t sampleRate = data.readInt32();
+            audio_format_t format = (audio_format_t) data.readInt32();
+            audio_channel_mask_t channelMask = data.readInt32();
+            const String16& opPackageName = data.readString16();
+            size_t frameCount = data.readInt64();
+            audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
+            pid_t pid = (pid_t) data.readInt32();
+            pid_t tid = (pid_t) data.readInt32();
+            int clientUid = data.readInt32();
+            audio_session_t sessionId = (audio_session_t) data.readInt32();
+            size_t notificationFrames = data.readInt64();
+            audio_port_handle_t portId = (audio_port_handle_t) data.readInt32();
+            sp<IMemory> cblk;
+            sp<IMemory> buffers;
+            status_t status = NO_ERROR;
+            sp<media::IAudioRecord> record = openRecord(input,
+                    sampleRate, format, channelMask, opPackageName, &frameCount, &flags,
+                    pid, tid, clientUid, &sessionId, &notificationFrames, cblk, buffers,
+                    &status, portId);
             LOG_ALWAYS_FATAL_IF((record != 0) != (status == NO_ERROR));
+            reply->writeInt64(frameCount);
+            reply->writeInt32(flags);
+            reply->writeInt32(sessionId);
+            reply->writeInt64(notificationFrames);
             reply->writeInt32(status);
-            if (status != NO_ERROR) {
-                return NO_ERROR;
-            }
             reply->writeStrongBinder(IInterface::asBinder(record));
-            output.writeToParcel(reply);
+            reply->writeStrongBinder(IInterface::asBinder(cblk));
+            reply->writeStrongBinder(IInterface::asBinder(buffers));
             return NO_ERROR;
         } break;
         case SAMPLE_RATE: {
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 53bc1b7..970ae90 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -22,7 +22,6 @@
 #include <math.h>
 #include <sys/types.h>
 
-#include <binder/IPCThreadState.h>
 #include <binder/Parcel.h>
 
 #include <media/AudioEffect.h>
@@ -832,33 +831,10 @@
 
 // ----------------------------------------------------------------------
 
+
 status_t BnAudioPolicyService::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
-    // make sure transactions reserved to AudioFlinger do not come from other processes
-    switch (code) {
-        case START_OUTPUT:
-        case STOP_OUTPUT:
-        case RELEASE_OUTPUT:
-        case GET_INPUT_FOR_ATTR:
-        case START_INPUT:
-        case STOP_INPUT:
-        case RELEASE_INPUT:
-        case GET_STRATEGY_FOR_STREAM:
-        case GET_OUTPUT_FOR_EFFECT:
-        case REGISTER_EFFECT:
-        case UNREGISTER_EFFECT:
-        case SET_EFFECT_ENABLED:
-        case GET_OUTPUT_FOR_ATTR:
-        case ACQUIRE_SOUNDTRIGGER_SESSION:
-        case RELEASE_SOUNDTRIGGER_SESSION:
-            ALOGW("%s: transaction %d received from PID %d",
-                  __func__, code, IPCThreadState::self()->getCallingPid());
-            return INVALID_OPERATION;
-        default:
-            break;
-    }
-
     switch (code) {
         case SET_DEVICE_CONNECTION_STATE: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
diff --git a/media/libaudioclient/aidl/android/media/IAudioRecord.aidl b/media/libaudioclient/aidl/android/media/IAudioRecord.aidl
index 7572671..50ce78f 100644
--- a/media/libaudioclient/aidl/android/media/IAudioRecord.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioRecord.aidl
@@ -16,7 +16,6 @@
 
 package android.media;
 
-/* Native code must specify namespace media (media::IAudioRecord) when referring to this class */
 interface IAudioRecord {
 
   /* After it's created the track is not active. Call start() to
diff --git a/media/libaudioclient/include/media/AudioClient.h b/media/libaudioclient/include/media/AudioClient.h
index 247af9e..108e326 100644
--- a/media/libaudioclient/include/media/AudioClient.h
+++ b/media/libaudioclient/include/media/AudioClient.h
@@ -19,13 +19,12 @@
 #define ANDROID_AUDIO_CLIENT_H
 
 #include <binder/Parcel.h>
-#include <binder/Parcelable.h>
 #include <system/audio.h>
 #include <utils/String16.h>
 
 namespace android {
 
-class AudioClient : public Parcelable {
+class AudioClient {
  public:
     AudioClient() :
         clientUid(-1), clientPid(-1), clientTid(-1), packageName("") {}
@@ -35,7 +34,7 @@
     pid_t clientTid;
     String16 packageName;
 
-    status_t readFromParcel(const Parcel *parcel) override {
+    status_t readFromParcel(Parcel *parcel) {
         clientUid = parcel->readInt32();
         clientPid = parcel->readInt32();
         clientTid = parcel->readInt32();
@@ -43,7 +42,7 @@
         return NO_ERROR;
     }
 
-    status_t writeToParcel(Parcel *parcel) const override {
+    status_t writeToParcel(Parcel *parcel) const {
         parcel->writeInt32(clientUid);
         parcel->writeInt32(clientPid);
         parcel->writeInt32(clientTid);
diff --git a/media/libaudioclient/include/media/AudioRecord.h b/media/libaudioclient/include/media/AudioRecord.h
index 00c2a88..51596a2 100644
--- a/media/libaudioclient/include/media/AudioRecord.h
+++ b/media/libaudioclient/include/media/AudioRecord.h
@@ -570,7 +570,7 @@
 
             // 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'
             status_t restoreRecord_l(const char *from);
@@ -682,6 +682,7 @@
                                               // May not match the app selection depending on other
                                               // activity and connected devices
     wp<AudioSystem::AudioDeviceCallback> mDeviceCallback;
+    audio_port_handle_t    mPortId;  // unique ID allocated by audio policy
 
 };
 
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 24a6e22..66601da 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -231,7 +231,7 @@
                               audio_stream_type_t stream,
                               audio_session_t session);
 
-    // Client must successfully hand off the handle reference to AudioFlinger via createRecord(),
+    // Client must successfully hand off the handle reference to AudioFlinger via openRecord(),
     // or release it with releaseInput().
     static status_t getInputForAttr(const audio_attributes_t *attr,
                                     audio_io_handle_t *input,
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 57d9778..9061c26 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -25,7 +25,6 @@
 #include <utils/Errors.h>
 #include <binder/IInterface.h>
 #include <binder/Parcel.h>
-#include <binder/Parcelable.h>
 #include <media/AudioClient.h>
 #include <media/IAudioTrack.h>
 #include <media/IAudioFlingerClient.h>
@@ -51,9 +50,9 @@
      * when calling createTrack() including arguments that will be updated by AudioFlinger
      * and returned in CreateTrackOutput object
      */
-    class CreateTrackInput : public Parcelable {
+    class CreateTrackInput {
     public:
-        status_t readFromParcel(const Parcel *parcel) override {
+        status_t readFromParcel(Parcel *parcel) {
             /* input arguments*/
             memset(&attr, 0, sizeof(audio_attributes_t));
             if (parcel->read(&attr, sizeof(audio_attributes_t)) != NO_ERROR) {
@@ -64,9 +63,7 @@
             if (parcel->read(&config, sizeof(audio_config_t)) != NO_ERROR) {
                 return DEAD_OBJECT;
             }
-            if (clientInfo.readFromParcel(parcel) != NO_ERROR) {
-                return DEAD_OBJECT;
-            }
+            (void)clientInfo.readFromParcel(parcel);
             if (parcel->readInt32() != 0) {
                 sharedBuffer = interface_cast<IMemory>(parcel->readStrongBinder());
                 if (sharedBuffer == 0 || sharedBuffer->pointer() == NULL) {
@@ -85,7 +82,7 @@
             return NO_ERROR;
         }
 
-        status_t writeToParcel(Parcel *parcel) const override {
+        status_t writeToParcel(Parcel *parcel) const {
             /* input arguments*/
             (void)parcel->write(&attr, sizeof(audio_attributes_t));
             (void)parcel->write(&config, sizeof(audio_config_t));
@@ -128,9 +125,9 @@
      * when calling createTrack() including arguments that were passed as I/O for update by
      * CreateTrackInput.
      */
-    class CreateTrackOutput : public Parcelable {
+    class CreateTrackOutput {
     public:
-        status_t readFromParcel(const Parcel *parcel) override {
+        status_t readFromParcel(Parcel *parcel) {
             /* input/output arguments*/
             (void)parcel->read(&flags, sizeof(audio_output_flags_t));
             frameCount = parcel->readInt64();
@@ -147,7 +144,7 @@
             return NO_ERROR;
         }
 
-        status_t writeToParcel(Parcel *parcel) const override {
+        status_t writeToParcel(Parcel *parcel) const {
             /* input/output arguments*/
             (void)parcel->write(&flags, sizeof(audio_output_flags_t));
             (void)parcel->writeInt64(frameCount);
@@ -179,140 +176,6 @@
         audio_io_handle_t outputId;
     };
 
-    /* CreateRecordInput contains all input arguments sent by AudioRecord to AudioFlinger
-     * when calling createRecord() including arguments that will be updated by AudioFlinger
-     * and returned in CreateRecordOutput object
-     */
-    class CreateRecordInput : public Parcelable {
-    public:
-        status_t readFromParcel(const Parcel *parcel) override {
-            /* input arguments*/
-            memset(&attr, 0, sizeof(audio_attributes_t));
-            if (parcel->read(&attr, sizeof(audio_attributes_t)) != NO_ERROR) {
-                return DEAD_OBJECT;
-            }
-            attr.tags[AUDIO_ATTRIBUTES_TAGS_MAX_SIZE -1] = '\0';
-            memset(&config, 0, sizeof(audio_config_base_t));
-            if (parcel->read(&config, sizeof(audio_config_base_t)) != NO_ERROR) {
-                return DEAD_OBJECT;
-            }
-            if (clientInfo.readFromParcel(parcel) != NO_ERROR) {
-                return DEAD_OBJECT;
-            }
-            opPackageName = parcel->readString16();
-
-            /* input/output arguments*/
-            (void)parcel->read(&flags, sizeof(audio_input_flags_t));
-            frameCount = parcel->readInt64();
-            notificationFrameCount = parcel->readInt64();
-            (void)parcel->read(&selectedDeviceId, sizeof(audio_port_handle_t));
-            (void)parcel->read(&sessionId, sizeof(audio_session_t));
-            return NO_ERROR;
-        }
-
-        status_t writeToParcel(Parcel *parcel) const override {
-            /* input arguments*/
-            (void)parcel->write(&attr, sizeof(audio_attributes_t));
-            (void)parcel->write(&config, sizeof(audio_config_base_t));
-            (void)clientInfo.writeToParcel(parcel);
-            (void)parcel->writeString16(opPackageName);
-
-            /* input/output arguments*/
-            (void)parcel->write(&flags, sizeof(audio_input_flags_t));
-            (void)parcel->writeInt64(frameCount);
-            (void)parcel->writeInt64(notificationFrameCount);
-            (void)parcel->write(&selectedDeviceId, sizeof(audio_port_handle_t));
-            (void)parcel->write(&sessionId, sizeof(audio_session_t));
-            return NO_ERROR;
-        }
-
-        /* input */
-        audio_attributes_t attr;
-        audio_config_base_t config;
-        AudioClient clientInfo;
-        String16 opPackageName;
-
-        /* input/output */
-        audio_input_flags_t flags;
-        size_t frameCount;
-        size_t notificationFrameCount;
-        audio_port_handle_t selectedDeviceId;
-        audio_session_t sessionId;
-    };
-
-    /* CreateRecordOutput contains all output arguments returned by AudioFlinger to AudioRecord
-     * when calling createRecord() including arguments that were passed as I/O for update by
-     * CreateRecordInput.
-     */
-    class CreateRecordOutput : public Parcelable {
-    public:
-        status_t readFromParcel(const Parcel *parcel) override {
-            /* input/output arguments*/
-            (void)parcel->read(&flags, sizeof(audio_input_flags_t));
-            frameCount = parcel->readInt64();
-            notificationFrameCount = parcel->readInt64();
-            (void)parcel->read(&selectedDeviceId, sizeof(audio_port_handle_t));
-            (void)parcel->read(&sessionId, sizeof(audio_session_t));
-
-            /* output arguments*/
-            sampleRate = parcel->readUint32();
-            (void)parcel->read(&inputId, sizeof(audio_io_handle_t));
-            if (parcel->readInt32() != 0) {
-                cblk = interface_cast<IMemory>(parcel->readStrongBinder());
-                if (cblk == 0 || cblk->pointer() == NULL) {
-                    return BAD_VALUE;
-                }
-            }
-            if (parcel->readInt32() != 0) {
-                buffers = interface_cast<IMemory>(parcel->readStrongBinder());
-                if (buffers == 0 || buffers->pointer() == NULL) {
-                    return BAD_VALUE;
-                }
-            }
-            return NO_ERROR;
-        }
-
-        status_t writeToParcel(Parcel *parcel) const override {
-            /* input/output arguments*/
-            (void)parcel->write(&flags, sizeof(audio_input_flags_t));
-            (void)parcel->writeInt64(frameCount);
-            (void)parcel->writeInt64(notificationFrameCount);
-            (void)parcel->write(&selectedDeviceId, sizeof(audio_port_handle_t));
-            (void)parcel->write(&sessionId, sizeof(audio_session_t));
-
-            /* output arguments*/
-            (void)parcel->writeUint32(sampleRate);
-            (void)parcel->write(&inputId, sizeof(audio_io_handle_t));
-            if (cblk != 0) {
-                (void)parcel->writeInt32(1);
-                (void)parcel->writeStrongBinder(IInterface::asBinder(cblk));
-            } else {
-                (void)parcel->writeInt32(0);
-            }
-            if (buffers != 0) {
-                (void)parcel->writeInt32(1);
-                (void)parcel->writeStrongBinder(IInterface::asBinder(buffers));
-            } else {
-                (void)parcel->writeInt32(0);
-            }
-
-            return NO_ERROR;
-        }
-
-        /* input/output */
-        audio_input_flags_t flags;
-        size_t frameCount;
-        size_t notificationFrameCount;
-        audio_port_handle_t selectedDeviceId;
-        audio_session_t sessionId;
-
-        /* output */
-        uint32_t sampleRate;
-        audio_io_handle_t inputId;
-        sp<IMemory> cblk;
-        sp<IMemory> buffers;
-    };
-
     // invariant on exit for all APIs that return an sp<>:
     //   (return value != 0) == (*status == NO_ERROR)
 
@@ -323,9 +186,26 @@
                                         CreateTrackOutput& output,
                                         status_t *status) = 0;
 
-    virtual sp<media::IAudioRecord> createRecord(const CreateRecordInput& input,
-                                        CreateRecordOutput& output,
-                                        status_t *status) = 0;
+    virtual sp<media::IAudioRecord> openRecord(
+                                // On successful return, AudioFlinger takes over the handle
+                                // reference and will release it when the track is destroyed.
+                                // However on failure, the client is responsible for release.
+                                audio_io_handle_t input,
+                                uint32_t sampleRate,
+                                audio_format_t format,
+                                audio_channel_mask_t channelMask,
+                                const String16& callingPackage,
+                                size_t *pFrameCount,
+                                audio_input_flags_t *flags,
+                                pid_t pid,
+                                pid_t tid,  // -1 means unused, otherwise must be valid non-0
+                                int clientUid,
+                                audio_session_t *sessionId,
+                                size_t *notificationFrames,
+                                sp<IMemory>& cblk,
+                                sp<IMemory>& buffers,   // return value 0 means it follows cblk
+                                status_t *status,
+                                audio_port_handle_t portId) = 0;
 
     // FIXME Surprisingly, format/latency don't work for input handles
 
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index aeb32bb..9cb0357 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -674,11 +674,7 @@
     audio_session_t sessionId = input.sessionId;
     if (sessionId == AUDIO_SESSION_ALLOCATE) {
         sessionId = (audio_session_t) newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
-    } else if (audio_unique_id_get_use(sessionId) != AUDIO_UNIQUE_ID_USE_SESSION) {
-        lStatus = BAD_VALUE;
-        goto Exit;
     }
-
     output.sessionId = sessionId;
     output.outputId = AUDIO_IO_HANDLE_NONE;
     output.selectedDeviceId = input.selectedDeviceId;
@@ -1572,144 +1568,120 @@
 
 // ----------------------------------------------------------------------------
 
-sp<media::IAudioRecord> AudioFlinger::createRecord(const CreateRecordInput& input,
-                                                   CreateRecordOutput& output,
-                                                   status_t *status)
+sp<media::IAudioRecord> AudioFlinger::openRecord(
+        audio_io_handle_t input,
+        uint32_t sampleRate,
+        audio_format_t format,
+        audio_channel_mask_t channelMask,
+        const String16& opPackageName,
+        size_t *frameCount,
+        audio_input_flags_t *flags,
+        pid_t pid,
+        pid_t tid,
+        int clientUid,
+        audio_session_t *sessionId,
+        size_t *notificationFrames,
+        sp<IMemory>& cblk,
+        sp<IMemory>& buffers,
+        status_t *status,
+        audio_port_handle_t portId)
 {
     sp<RecordThread::RecordTrack> recordTrack;
     sp<RecordHandle> recordHandle;
     sp<Client> client;
     status_t lStatus;
-    audio_session_t sessionId = input.sessionId;
-    audio_port_handle_t portId;
+    audio_session_t lSessionId;
 
-    output.cblk.clear();
-    output.buffers.clear();
+    cblk.clear();
+    buffers.clear();
 
-    bool updatePid = (input.clientInfo.clientPid == -1);
+    bool updatePid = (pid == -1);
     const uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    uid_t clientUid = input.clientInfo.clientUid;
     if (!isTrustedCallingUid(callingUid)) {
-        ALOGW_IF(clientUid != callingUid,
-                "%s uid %d tried to pass itself off as %d",
-                __FUNCTION__, callingUid, clientUid);
+        ALOGW_IF((uid_t)clientUid != callingUid,
+                "%s uid %d tried to pass itself off as %d", __FUNCTION__, callingUid, clientUid);
         clientUid = callingUid;
         updatePid = true;
     }
-    pid_t clientPid = input.clientInfo.clientPid;
+
     if (updatePid) {
         const pid_t callingPid = IPCThreadState::self()->getCallingPid();
-        ALOGW_IF(clientPid != -1 && clientPid != callingPid,
+        ALOGW_IF(pid != -1 && pid != callingPid,
                  "%s uid %d pid %d tried to pass itself off as pid %d",
-                 __func__, callingUid, callingPid, clientPid);
-        clientPid = callingPid;
+                 __func__, callingUid, callingPid, pid);
+        pid = callingPid;
     }
 
     // check calling permissions
-    if (!recordingAllowed(input.opPackageName, input.clientInfo.clientTid, clientUid)) {
-        ALOGE("createRecord() permission denied: recording not allowed");
+    if (!recordingAllowed(opPackageName, tid, clientUid)) {
+        ALOGE("openRecord() permission denied: recording not allowed");
         lStatus = PERMISSION_DENIED;
         goto Exit;
     }
+
+    // further sample rate checks are performed by createRecordTrack_l()
+    if (sampleRate == 0) {
+        ALOGE("openRecord() invalid sample rate %u", sampleRate);
+        lStatus = BAD_VALUE;
+        goto Exit;
+    }
+
     // we don't yet support anything other than linear PCM
-    if (!audio_is_valid_format(input.config.format) || !audio_is_linear_pcm(input.config.format)) {
-        ALOGE("createRecord() invalid format %#x", input.config.format);
+    if (!audio_is_valid_format(format) || !audio_is_linear_pcm(format)) {
+        ALOGE("openRecord() invalid format %#x", format);
         lStatus = BAD_VALUE;
         goto Exit;
     }
 
     // further channel mask checks are performed by createRecordTrack_l()
-    if (!audio_is_input_channel(input.config.channel_mask)) {
-        ALOGE("createRecord() invalid channel mask %#x", input.config.channel_mask);
+    if (!audio_is_input_channel(channelMask)) {
+        ALOGE("openRecord() invalid channel mask %#x", channelMask);
         lStatus = BAD_VALUE;
         goto Exit;
     }
 
-    if (sessionId == AUDIO_SESSION_ALLOCATE) {
-        sessionId = (audio_session_t) newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
-    } else if (audio_unique_id_get_use(sessionId) != AUDIO_UNIQUE_ID_USE_SESSION) {
-        lStatus = BAD_VALUE;
-        goto Exit;
-    }
-
-    output.sessionId = sessionId;
-    output.inputId = AUDIO_IO_HANDLE_NONE;
-    output.selectedDeviceId = input.selectedDeviceId;
-    output.flags = input.flags;
-
-    client = registerPid(clientPid);
-
-    // 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 via break on no error of got exit on error
-    // The sp<> references will be dropped when re-entering scope.
-    // The lack of indentation is deliberate, to reduce code churn and ease merges.
-    for (;;) {
-    lStatus = AudioSystem::getInputForAttr(&input.attr, &output.inputId,
-                                      sessionId,
-                                    // FIXME compare to AudioTrack
-                                      clientPid,
-                                      clientUid,
-                                      &input.config,
-                                      output.flags, &output.selectedDeviceId, &portId);
-
     {
         Mutex::Autolock _l(mLock);
-        RecordThread *thread = checkRecordThread_l(output.inputId);
+        RecordThread *thread = checkRecordThread_l(input);
         if (thread == NULL) {
-            ALOGE("createRecord() checkRecordThread_l failed");
+            ALOGE("openRecord() checkRecordThread_l failed");
             lStatus = BAD_VALUE;
             goto Exit;
         }
 
-        ALOGV("createRecord() lSessionId: %d input %d", sessionId, output.inputId);
+        client = registerPid(pid);
 
-        output.sampleRate = input.config.sample_rate;
-        output.frameCount = input.frameCount;
-        output.notificationFrameCount = input.notificationFrameCount;
+        if (sessionId != NULL && *sessionId != AUDIO_SESSION_ALLOCATE) {
+            if (audio_unique_id_get_use(*sessionId) != AUDIO_UNIQUE_ID_USE_SESSION) {
+                lStatus = BAD_VALUE;
+                goto Exit;
+            }
+            lSessionId = *sessionId;
+        } else {
+            // if no audio session id is provided, create one here
+            lSessionId = (audio_session_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
+            if (sessionId != NULL) {
+                *sessionId = lSessionId;
+            }
+        }
+        ALOGV("openRecord() lSessionId: %d input %d", lSessionId, input);
 
-        recordTrack = thread->createRecordTrack_l(client, &output.sampleRate,
-                                                  input.config.format, input.config.channel_mask,
-                                                  &output.frameCount, sessionId,
-                                                  &output.notificationFrameCount,
-                                                  clientUid, &output.flags,
-                                                  input.clientInfo.clientTid,
-                                                  &lStatus, portId);
+        recordTrack = thread->createRecordTrack_l(client, sampleRate, format, channelMask,
+                                                  frameCount, lSessionId, notificationFrames,
+                                                  clientUid, flags, tid, &lStatus, portId);
         LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (recordTrack == 0));
 
-        // lStatus == BAD_TYPE means FAST flag was rejected: request a new input from
-        // audio policy manager without FAST constraint
-        if (lStatus == BAD_TYPE) {
-            AudioSystem::releaseInput(output.inputId, sessionId);
-            recordTrack.clear();
-            continue;
+        if (lStatus == NO_ERROR) {
+            // Check if one effect chain was awaiting for an AudioRecord to be created on this
+            // session and move it to this thread.
+            sp<EffectChain> chain = getOrphanEffectChain_l(lSessionId);
+            if (chain != 0) {
+                Mutex::Autolock _l(thread->mLock);
+                thread->addEffectChain_l(chain);
+            }
         }
-
-        if (lStatus != NO_ERROR) {
-            recordTrack.clear();
-            goto Exit;
-        }
-
-        // Check if one effect chain was awaiting for an AudioRecord to be created on this
-        // session and move it to this thread.
-        sp<EffectChain> chain = getOrphanEffectChain_l(sessionId);
-        if (chain != 0) {
-            Mutex::Autolock _l(thread->mLock);
-            thread->addEffectChain_l(chain);
-        }
-        break;
-    }
-    // End of retry loop.
-    // The lack of indentation is deliberate, to reduce code churn and ease merges.
     }
 
-    output.cblk = recordTrack->getCblk();
-    output.buffers = recordTrack->getBuffers();
-
-    // return handle to client
-    recordHandle = new RecordHandle(recordTrack);
-
-Exit:
     if (lStatus != NO_ERROR) {
         // remove local strong reference to Client before deleting the RecordTrack so that the
         // Client destructor is called by the TrackBase destructor with mClientLock held
@@ -1719,8 +1691,17 @@
             Mutex::Autolock _cl(mClientLock);
             client.clear();
         }
+        recordTrack.clear();
+        goto Exit;
     }
 
+    cblk = recordTrack->getCblk();
+    buffers = recordTrack->getBuffers();
+
+    // return handle to client
+    recordHandle = new RecordHandle(recordTrack);
+
+Exit:
     *status = lStatus;
     return recordHandle;
 }
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index bc73ffd..506420c 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -118,9 +118,23 @@
                                         CreateTrackOutput& output,
                                         status_t *status);
 
-    virtual sp<media::IAudioRecord> createRecord(const CreateRecordInput& input,
-                                                 CreateRecordOutput& output,
-                                                 status_t *status);
+    virtual sp<media::IAudioRecord> openRecord(
+                                audio_io_handle_t input,
+                                uint32_t sampleRate,
+                                audio_format_t format,
+                                audio_channel_mask_t channelMask,
+                                const String16& opPackageName,
+                                size_t *pFrameCount,
+                                audio_input_flags_t *flags,
+                                pid_t pid,
+                                pid_t tid,
+                                int clientUid,
+                                audio_session_t *sessionId,
+                                size_t *notificationFrames,
+                                sp<IMemory>& cblk,
+                                sp<IMemory>& buffers,
+                                status_t *status /*non-NULL*/,
+                                audio_port_handle_t portId);
 
     virtual     uint32_t    sampleRate(audio_io_handle_t ioHandle) const;
     virtual     audio_format_t format(audio_io_handle_t output) const;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 7636df6..b2a1e18 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -6708,12 +6708,12 @@
 // RecordThread::createRecordTrack_l() must be called with AudioFlinger::mLock held
 sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRecordTrack_l(
         const sp<AudioFlinger::Client>& client,
-        uint32_t *pSampleRate,
+        uint32_t sampleRate,
         audio_format_t format,
         audio_channel_mask_t channelMask,
         size_t *pFrameCount,
         audio_session_t sessionId,
-        size_t *pNotificationFrameCount,
+        size_t *notificationFrames,
         uid_t uid,
         audio_input_flags_t *flags,
         pid_t tid,
@@ -6721,30 +6721,16 @@
         audio_port_handle_t portId)
 {
     size_t frameCount = *pFrameCount;
-    size_t notificationFrameCount = *pNotificationFrameCount;
     sp<RecordTrack> track;
     status_t lStatus;
     audio_input_flags_t inputFlags = mInput->flags;
-    audio_input_flags_t requestedFlags = *flags;
-    uint32_t sampleRate;
-
-    lStatus = initCheck();
-    if (lStatus != NO_ERROR) {
-        ALOGE("createRecordTrack_l() audio driver not initialized");
-        goto Exit;
-    }
-
-    if (*pSampleRate == 0) {
-        *pSampleRate = mSampleRate;
-    }
-    sampleRate = *pSampleRate;
 
     // special case for FAST flag considered OK if fast capture is present
     if (hasFastCapture()) {
         inputFlags = (audio_input_flags_t)(inputFlags | AUDIO_INPUT_FLAG_FAST);
     }
 
-    // Check if requested flags are compatible with input stream flags
+    // Check if requested flags are compatible with output stream flags
     if ((*flags & inputFlags) != *flags) {
         ALOGW("createRecordTrack_l(): mismatch between requested flags (%08x) and"
                 " input flags (%08x)",
@@ -6799,20 +6785,12 @@
       }
     }
 
-    // If FAST or RAW flags were corrected, ask caller to request new input from audio policy
-    if ((*flags & AUDIO_INPUT_FLAG_FAST) !=
-            (requestedFlags & AUDIO_INPUT_FLAG_FAST)) {
-        *flags = (audio_input_flags_t) (*flags & ~(AUDIO_INPUT_FLAG_FAST | AUDIO_INPUT_FLAG_RAW));
-        lStatus = BAD_TYPE;
-        goto Exit;
-    }
-
     // compute track buffer size in frames, and suggest the notification frame count
     if (*flags & AUDIO_INPUT_FLAG_FAST) {
         // fast track: frame count is exactly the pipe depth
         frameCount = mPipeFramesP2;
         // ignore requested notificationFrames, and always notify exactly once every HAL buffer
-        notificationFrameCount = mFrameCount;
+        *notificationFrames = mFrameCount;
     } else {
         // not fast track: max notification period is resampled equivalent of one HAL buffer time
         //                 or 20 ms if there is a fast capture
@@ -6831,12 +6809,17 @@
         const size_t minFrameCount = maxNotificationFrames *
                 max(kMinNotifications, minNotificationsByMs);
         frameCount = max(frameCount, minFrameCount);
-        if (notificationFrameCount == 0 || notificationFrameCount > maxNotificationFrames) {
-            notificationFrameCount = maxNotificationFrames;
+        if (*notificationFrames == 0 || *notificationFrames > maxNotificationFrames) {
+            *notificationFrames = maxNotificationFrames;
         }
     }
     *pFrameCount = frameCount;
-    *pNotificationFrameCount = notificationFrameCount;
+
+    lStatus = initCheck();
+    if (lStatus != NO_ERROR) {
+        ALOGE("createRecordTrack_l() audio driver not initialized");
+        goto Exit;
+    }
 
     { // scope for mLock
         Mutex::Autolock _l(mLock);
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 17f26c5..c7b60d6 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -1327,12 +1327,12 @@
 
             sp<AudioFlinger::RecordThread::RecordTrack>  createRecordTrack_l(
                     const sp<AudioFlinger::Client>& client,
-                    uint32_t *pSampleRate,
+                    uint32_t sampleRate,
                     audio_format_t format,
                     audio_channel_mask_t channelMask,
                     size_t *pFrameCount,
                     audio_session_t sessionId,
-                    size_t *pNotificationFrameCount,
+                    size_t *notificationFrames,
                     uid_t uid,
                     audio_input_flags_t *flags,
                     pid_t tid,
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index a3ea756..d4ce0b4 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -192,7 +192,7 @@
                                     // where for AudioTrack (but not AudioRecord),
                                     // 8-bit PCM samples are stored as 16-bit
     const size_t        mFrameCount;// size of track buffer given at createTrack() or
-                                    // createRecord(), and then adjusted as needed
+                                    // openRecord(), and then adjusted as needed
 
     const audio_session_t mSessionId;
     uid_t               mUid;
diff --git a/services/mediacodec/Android.mk b/services/mediacodec/Android.mk
index caa0703..9348ecd 100644
--- a/services/mediacodec/Android.mk
+++ b/services/mediacodec/Android.mk
@@ -26,6 +26,10 @@
 LOCAL_32_BIT_ONLY := true
 LOCAL_INIT_RC := android.hardware.media.omx@1.0-service.rc
 
+ifeq ($(PRODUCT_FULL_TREBLE),true)
+LOCAL_CFLAGS += -DUSE_VNDBINDER
+endif
+
 include $(BUILD_EXECUTABLE)
 
 # service seccomp policy
diff --git a/services/mediacodec/main_codecservice.cpp b/services/mediacodec/main_codecservice.cpp
index 701ca6e..6f14a42 100644
--- a/services/mediacodec/main_codecservice.cpp
+++ b/services/mediacodec/main_codecservice.cpp
@@ -40,8 +40,10 @@
     signal(SIGPIPE, SIG_IGN);
     SetUpMinijail(kSystemSeccompPolicyPath, kVendorSeccompPolicyPath);
 
+#ifdef USE_VNDBINDER
     android::ProcessState::initWithDriver("/dev/vndbinder");
     android::ProcessState::self()->startThreadPool();
+#endif // USE_VNDBINDER
 
     ::android::hardware::configureRpcThreadpool(64, false);