From caf7f48a0ef558689d39aafd187c1571ff4128b4 Mon Sep 17 00:00:00 2001
From: Eric Laurent <elaurent@google.com>
Date: Tue, 25 Nov 2014 17:50:47 -0800
Subject: AudioRecord: use audio attributes instead of audio source.

Added AudioRecord constructor with audio attributes.
Replaced AudioPolicymanager::getInput() by getInputForAttr().

No new functionality for now.

Also:

- Fixed warnings in AudioPolicyManager
- Allocate audio session ID before calling getOutputForAttr() in
AudioTrack.

Bug: 16006090.
Change-Id: I15df21e4411db688e3096dd801cf579d76d81711
---
 include/media/AudioRecord.h                        | 11 ++--
 include/media/AudioSystem.h                        |  7 ++-
 include/media/IAudioPolicyService.h                | 13 ++--
 media/libmedia/AudioRecord.cpp                     | 29 ++++++---
 media/libmedia/AudioSystem.cpp                     | 17 +++---
 media/libmedia/AudioTrack.cpp                      |  6 +-
 media/libmedia/IAudioPolicyService.cpp             | 62 ++++++++++++-------
 services/audiopolicy/AudioPolicyInterface.h        | 13 ++--
 services/audiopolicy/AudioPolicyInterfaceImpl.cpp  | 45 +++++++-------
 .../audiopolicy/AudioPolicyInterfaceImplLegacy.cpp | 38 ++++++------
 services/audiopolicy/AudioPolicyManager.cpp        | 71 +++++++++++-----------
 services/audiopolicy/AudioPolicyManager.h          | 13 ++--
 services/audiopolicy/AudioPolicyService.h          | 13 ++--
 13 files changed, 192 insertions(+), 146 deletions(-)

diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index 4edc1bf..f70d981 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -152,6 +152,7 @@ public:
      * transferType:       How data is transferred from AudioRecord.
      * flags:              See comments on audio_input_flags_t in <system/audio.h>
      * threadCanCallJava:  Not present in parameter list, and so is fixed at false.
+     * pAttributes:        if not NULL, supersedes inputSource for use case selection
      */
 
                         AudioRecord(audio_source_t inputSource,
@@ -164,7 +165,8 @@ public:
                                     uint32_t notificationFrames = 0,
                                     int sessionId = AUDIO_SESSION_ALLOCATE,
                                     transfer_type transferType = TRANSFER_DEFAULT,
-                                    audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE);
+                                    audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE,
+                                    const audio_attributes_t* pAttributes = NULL);
 
     /* Terminates the AudioRecord and unregisters it from AudioFlinger.
      * Also destroys all resources associated with the AudioRecord.
@@ -198,7 +200,8 @@ public:
                             bool threadCanCallJava = false,
                             int sessionId = AUDIO_SESSION_ALLOCATE,
                             transfer_type transferType = TRANSFER_DEFAULT,
-                            audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE);
+                            audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE,
+                            const audio_attributes_t* pAttributes = NULL);
 
     /* Result of constructing the AudioRecord. This must be checked for successful initialization
      * before using any AudioRecord API (except for set()), because using
@@ -219,7 +222,7 @@ public:
             uint32_t    channelCount() const    { return mChannelCount; }
             size_t      frameCount() const  { return mFrameCount; }
             size_t      frameSize() const   { return mFrameSize; }
-            audio_source_t inputSource() const  { return mInputSource; }
+            audio_source_t inputSource() const  { return mAttributes.source; }
 
     /* After it's created the track is not active. Call start() to
      * make it active. If set, the callback will start being called.
@@ -489,7 +492,6 @@ private:
     audio_format_t          mFormat;
     uint32_t                mChannelCount;
     size_t                  mFrameSize;         // app-level frame size == AudioFlinger frame size
-    audio_source_t          mInputSource;
     uint32_t                mLatency;           // in ms
     audio_channel_mask_t    mChannelMask;
     audio_input_flags_t     mFlags;
@@ -529,6 +531,7 @@ private:
 
     sp<DeathNotifier>       mDeathNotifier;
     uint32_t                mSequence;              // incremented for each new IAudioRecord attempt
+    audio_attributes_t      mAttributes;
 };
 
 }; // namespace android
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 7f1afb3..bf1fc1c 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -236,12 +236,13 @@ public:
 
     // Client must successfully hand off the handle reference to AudioFlinger via openRecord(),
     // or release it with releaseInput().
-    static audio_io_handle_t getInput(audio_source_t inputSource,
+    static status_t getInputForAttr(const audio_attributes_t *attr,
+                                    audio_io_handle_t *input,
+                                    audio_session_t session,
                                     uint32_t samplingRate,
                                     audio_format_t format,
                                     audio_channel_mask_t channelMask,
-                                    audio_session_t sessionId,
-                                    audio_input_flags_t);
+                                    audio_input_flags_t flags);
 
     static status_t startInput(audio_io_handle_t input,
                                audio_session_t session);
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 2f30304..3e4b873 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -74,12 +74,13 @@ public:
     virtual void releaseOutput(audio_io_handle_t output,
                                audio_stream_type_t stream,
                                audio_session_t session) = 0;
-    virtual audio_io_handle_t getInput(audio_source_t inputSource,
-                                    uint32_t samplingRate,
-                                    audio_format_t format,
-                                    audio_channel_mask_t channelMask,
-                                    audio_session_t audioSession,
-                                    audio_input_flags_t flags) = 0;
+    virtual status_t  getInputForAttr(const audio_attributes_t *attr,
+                                      audio_io_handle_t *input,
+                                      audio_session_t session,
+                                      uint32_t samplingRate,
+                                      audio_format_t format,
+                                      audio_channel_mask_t channelMask,
+                                      audio_input_flags_t flags) = 0;
     virtual status_t startInput(audio_io_handle_t input,
                                 audio_session_t session) = 0;
     virtual status_t stopInput(audio_io_handle_t input,
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 77437d1..d9646d9 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -82,14 +82,16 @@ AudioRecord::AudioRecord(
         uint32_t notificationFrames,
         int sessionId,
         transfer_type transferType,
-        audio_input_flags_t flags)
+        audio_input_flags_t flags,
+        const audio_attributes_t* pAttributes)
     : mStatus(NO_INIT), mSessionId(AUDIO_SESSION_ALLOCATE),
       mPreviousPriority(ANDROID_PRIORITY_NORMAL),
       mPreviousSchedulingGroup(SP_DEFAULT),
       mProxy(NULL)
 {
     mStatus = set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user,
-            notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags);
+            notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags,
+            pAttributes);
 }
 
 AudioRecord::~AudioRecord()
@@ -126,7 +128,8 @@ status_t AudioRecord::set(
         bool threadCanCallJava,
         int sessionId,
         transfer_type transferType,
-        audio_input_flags_t flags)
+        audio_input_flags_t flags,
+        const audio_attributes_t* pAttributes)
 {
     ALOGV("set(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
           "notificationFrames %u, sessionId %d, transferType %d, flags %#x",
@@ -168,7 +171,15 @@ status_t AudioRecord::set(
     if (inputSource == AUDIO_SOURCE_DEFAULT) {
         inputSource = AUDIO_SOURCE_MIC;
     }
-    mInputSource = inputSource;
+    if (pAttributes == NULL) {
+        memset(&mAttributes, 0, sizeof(audio_attributes_t));
+        mAttributes.source = inputSource;
+    } else {
+        // stream type shouldn't be looked at, this track has audio attributes
+        memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t));
+        ALOGV("Building AudioRecord with attributes: source=%d flags=0x%x tags=[%s]",
+              mAttributes.source, mAttributes.flags, mAttributes.tags);
+    }
 
     if (sampleRate == 0) {
         ALOGE("Invalid sample rate %u", sampleRate);
@@ -444,12 +455,14 @@ status_t AudioRecord::openRecord_l(size_t epoch)
         }
     }
 
-    audio_io_handle_t input = AudioSystem::getInput(mInputSource, mSampleRate, mFormat,
-            mChannelMask, (audio_session_t)mSessionId, mFlags);
-    if (input == AUDIO_IO_HANDLE_NONE) {
+    audio_io_handle_t input;
+    status = AudioSystem::getInputForAttr(&mAttributes, &input, (audio_session_t)mSessionId,
+                                        mSampleRate, mFormat, mChannelMask, mFlags);
+
+    if (status != NO_ERROR) {
         ALOGE("Could not get audio input for record source %d, sample rate %u, format %#x, "
               "channel mask %#x, session %d, flags %#x",
-              mInputSource, mSampleRate, mFormat, mChannelMask, mSessionId, mFlags);
+              mAttributes.source, mSampleRate, mFormat, mChannelMask, mSessionId, mFlags);
         return BAD_VALUE;
     }
     {
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 5f42f25..96f1ade 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -693,16 +693,17 @@ void AudioSystem::releaseOutput(audio_io_handle_t output,
     aps->releaseOutput(output, stream, session);
 }
 
-audio_io_handle_t AudioSystem::getInput(audio_source_t inputSource,
-                                    uint32_t samplingRate,
-                                    audio_format_t format,
-                                    audio_channel_mask_t channelMask,
-                                    audio_session_t sessionId,
-                                    audio_input_flags_t flags)
+status_t AudioSystem::getInputForAttr(const audio_attributes_t *attr,
+                                audio_io_handle_t *input,
+                                audio_session_t session,
+                                uint32_t samplingRate,
+                                audio_format_t format,
+                                audio_channel_mask_t channelMask,
+                                audio_input_flags_t flags)
 {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
-    if (aps == 0) return 0;
-    return aps->getInput(inputSource, samplingRate, format, channelMask, sessionId, flags);
+    if (aps == 0) return NO_INIT;
+    return aps->getInputForAttr(attr, input, session, samplingRate, format, channelMask, flags);
 }
 
 status_t AudioSystem::startInput(audio_io_handle_t input,
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 569eb5c..4a6df6d 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -374,7 +374,11 @@ status_t AudioTrack::set(
     mReqFrameCount = frameCount;
     mNotificationFramesReq = notificationFrames;
     mNotificationFramesAct = 0;
-    mSessionId = sessionId;
+    if (sessionId == AUDIO_SESSION_ALLOCATE) {
+        mSessionId = AudioSystem::newAudioUniqueId();
+    } else {
+        mSessionId = sessionId;
+    }
     int callingpid = IPCThreadState::self()->getCallingPid();
     int mypid = getpid();
     if (uid == -1 || (callingpid != mypid)) {
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 5f83a0d..5873a30 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -41,7 +41,7 @@ enum {
     START_OUTPUT,
     STOP_OUTPUT,
     RELEASE_OUTPUT,
-    GET_INPUT,
+    GET_INPUT_FOR_ATTR,
     START_INPUT,
     STOP_INPUT,
     RELEASE_INPUT,
@@ -263,24 +263,40 @@ public:
         remote()->transact(RELEASE_OUTPUT, data, &reply);
     }
 
-    virtual audio_io_handle_t getInput(
-                                    audio_source_t inputSource,
-                                    uint32_t samplingRate,
-                                    audio_format_t format,
-                                    audio_channel_mask_t channelMask,
-                                    audio_session_t audioSession,
-                                    audio_input_flags_t flags)
+    virtual status_t getInputForAttr(const audio_attributes_t *attr,
+                                     audio_io_handle_t *input,
+                                     audio_session_t session,
+                                     uint32_t samplingRate,
+                                     audio_format_t format,
+                                     audio_channel_mask_t channelMask,
+                                     audio_input_flags_t flags)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
-        data.writeInt32((int32_t) inputSource);
+        if (attr == NULL) {
+            ALOGE("getInputForAttr NULL attr - shouldn't happen");
+            return BAD_VALUE;
+        }
+        if (input == NULL) {
+            ALOGE("getInputForAttr NULL input - shouldn't happen");
+            return BAD_VALUE;
+        }
+        data.write(attr, sizeof(audio_attributes_t));
+        data.writeInt32(session);
         data.writeInt32(samplingRate);
         data.writeInt32(static_cast <uint32_t>(format));
         data.writeInt32(channelMask);
-        data.writeInt32((int32_t)audioSession);
         data.writeInt32(flags);
-        remote()->transact(GET_INPUT, data, &reply);
-        return static_cast <audio_io_handle_t> (reply.readInt32());
+        status_t status = remote()->transact(GET_INPUT_FOR_ATTR, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        status = reply.readInt32();
+        if (status != NO_ERROR) {
+            return status;
+        }
+        *input = (audio_io_handle_t)reply.readInt32();
+        return NO_ERROR;
     }
 
     virtual status_t startInput(audio_io_handle_t input,
@@ -809,21 +825,23 @@ status_t BnAudioPolicyService::onTransact(
             return NO_ERROR;
         } break;
 
-        case GET_INPUT: {
+        case GET_INPUT_FOR_ATTR: {
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
-            audio_source_t inputSource = (audio_source_t) data.readInt32();
+            audio_attributes_t attr;
+            data.read(&attr, sizeof(audio_attributes_t));
+            audio_session_t session = (audio_session_t)data.readInt32();
             uint32_t samplingRate = data.readInt32();
             audio_format_t format = (audio_format_t) data.readInt32();
             audio_channel_mask_t channelMask = data.readInt32();
-            audio_session_t audioSession = (audio_session_t)data.readInt32();
             audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
-            audio_io_handle_t input = getInput(inputSource,
-                                               samplingRate,
-                                               format,
-                                               channelMask,
-                                               audioSession,
-                                               flags);
-            reply->writeInt32(static_cast <int>(input));
+            audio_io_handle_t input;
+            status_t status = getInputForAttr(&attr, &input, session,
+                                              samplingRate, format, channelMask,
+                                              flags);
+            reply->writeInt32(status);
+            if (status == NO_ERROR) {
+                reply->writeInt32(input);
+            }
             return NO_ERROR;
         } break;
 
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index f7ffb6d..5bcbca8 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -113,12 +113,13 @@ public:
                                audio_session_t session) = 0;
 
     // request an input appropriate for record from the supplied device with supplied parameters.
-    virtual audio_io_handle_t getInput(audio_source_t inputSource,
-                                    uint32_t samplingRate,
-                                    audio_format_t format,
-                                    audio_channel_mask_t channelMask,
-                                    audio_session_t session,
-                                    audio_input_flags_t flags) = 0;
+    virtual status_t getInputForAttr(const audio_attributes_t *attr,
+                                     audio_io_handle_t *input,
+                                     audio_session_t session,
+                                     uint32_t samplingRate,
+                                     audio_format_t format,
+                                     audio_channel_mask_t channelMask,
+                                     audio_input_flags_t flags) = 0;
     // indicates to the audio policy manager that the input starts being used.
     virtual status_t startInput(audio_io_handle_t input,
                                 audio_session_t session) = 0;
diff --git a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
index 8b64d5b..abb1b21 100644
--- a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
@@ -243,47 +243,48 @@ void AudioPolicyService::doReleaseOutput(audio_io_handle_t output,
     mAudioPolicyManager->releaseOutput(output, stream, session);
 }
 
-audio_io_handle_t AudioPolicyService::getInput(audio_source_t inputSource,
-                                    uint32_t samplingRate,
-                                    audio_format_t format,
-                                    audio_channel_mask_t channelMask,
-                                    audio_session_t audioSession,
-                                    audio_input_flags_t flags)
+status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
+                                             audio_io_handle_t *input,
+                                             audio_session_t session,
+                                             uint32_t samplingRate,
+                                             audio_format_t format,
+                                             audio_channel_mask_t channelMask,
+                                             audio_input_flags_t flags)
 {
     if (mAudioPolicyManager == NULL) {
-        return 0;
+        return NO_INIT;
     }
     // already checked by client, but double-check in case the client wrapper is bypassed
-    if (inputSource >= AUDIO_SOURCE_CNT && inputSource != AUDIO_SOURCE_HOTWORD &&
-        inputSource != AUDIO_SOURCE_FM_TUNER) {
-        return 0;
+    if (attr->source >= AUDIO_SOURCE_CNT && attr->source != AUDIO_SOURCE_HOTWORD &&
+        attr->source != AUDIO_SOURCE_FM_TUNER) {
+        return BAD_VALUE;
     }
 
-    if (((inputSource == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) ||
-        ((inputSource == AUDIO_SOURCE_FM_TUNER) && !captureFmTunerAllowed())) {
-        return 0;
+    if (((attr->source == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) ||
+        ((attr->source == AUDIO_SOURCE_FM_TUNER) && !captureFmTunerAllowed())) {
+        return BAD_VALUE;
     }
-    audio_io_handle_t input;
     sp<AudioPolicyEffects>audioPolicyEffects;
+    status_t status;
     {
         Mutex::Autolock _l(mLock);
         // the audio_in_acoustics_t parameter is ignored by get_input()
-        input = mAudioPolicyManager->getInput(inputSource, samplingRate,
-                                                       format, channelMask,
-                                                       audioSession, flags);
+        status = mAudioPolicyManager->getInputForAttr(attr, input, session,
+                                                     samplingRate, format, channelMask,
+                                                     flags);
         audioPolicyEffects = mAudioPolicyEffects;
     }
-    if (input == 0) {
-        return input;
+    if (status != NO_ERROR) {
+        return status;
     }
     if (audioPolicyEffects != 0) {
         // create audio pre processors according to input source
-        status_t status = audioPolicyEffects->addInputEffects(input, inputSource, audioSession);
+        status_t status = audioPolicyEffects->addInputEffects(*input, attr->source, session);
         if (status != NO_ERROR && status != ALREADY_EXISTS) {
-            ALOGW("Failed to add effects on input %d", input);
+            ALOGW("Failed to add effects on input %d", *input);
         }
     }
-    return input;
+    return NO_ERROR;
 }
 
 status_t AudioPolicyService::startInput(audio_io_handle_t input,
diff --git a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
index 694dea3..4e42b25 100644
--- a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
@@ -230,48 +230,48 @@ void AudioPolicyService::doReleaseOutput(audio_io_handle_t output,
     mpAudioPolicy->release_output(mpAudioPolicy, output);
 }
 
-audio_io_handle_t AudioPolicyService::getInput(audio_source_t inputSource,
-                                    uint32_t samplingRate,
-                                    audio_format_t format,
-                                    audio_channel_mask_t channelMask,
-                                    audio_session_t audioSession,
-                                    audio_input_flags_t flags __unused)
+status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
+                                             audio_io_handle_t *input,
+                                             audio_session_t session,
+                                             uint32_t samplingRate,
+                                             audio_format_t format,
+                                             audio_channel_mask_t channelMask,
+                                             audio_input_flags_t flags __unused)
 {
     if (mpAudioPolicy == NULL) {
-        return 0;
+        return NO_INIT;
     }
     // already checked by client, but double-check in case the client wrapper is bypassed
-    if (inputSource >= AUDIO_SOURCE_CNT && inputSource != AUDIO_SOURCE_HOTWORD &&
-        inputSource != AUDIO_SOURCE_FM_TUNER) {
-        return 0;
+    if (attr->source >= AUDIO_SOURCE_CNT && attr->source != AUDIO_SOURCE_HOTWORD &&
+        attr->source != AUDIO_SOURCE_FM_TUNER) {
+        return BAD_VALUE;
     }
 
-    if (((inputSource == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) ||
-        ((inputSource == AUDIO_SOURCE_FM_TUNER) && !captureFmTunerAllowed())) {
-        return 0;
+    if (((attr->source == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) ||
+        ((attr->source == AUDIO_SOURCE_FM_TUNER) && !captureFmTunerAllowed())) {
+        return BAD_VALUE;
     }
 
-    audio_io_handle_t input;
     sp<AudioPolicyEffects>audioPolicyEffects;
     {
         Mutex::Autolock _l(mLock);
         // the audio_in_acoustics_t parameter is ignored by get_input()
-        input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate,
+        *input = mpAudioPolicy->get_input(mpAudioPolicy, attr->source, samplingRate,
                                              format, channelMask, (audio_in_acoustics_t) 0);
         audioPolicyEffects = mAudioPolicyEffects;
     }
-    if (input == 0) {
-        return input;
+    if (*input == AUDIO_IO_HANDLE_NONE) {
+        return INVALID_OPERATION;
     }
 
     if (audioPolicyEffects != 0) {
         // create audio pre processors according to input source
-        status_t status = audioPolicyEffects->addInputEffects(input, inputSource, audioSession);
+        status_t status = audioPolicyEffects->addInputEffects(*input, attr->source, session);
         if (status != NO_ERROR && status != ALREADY_EXISTS) {
             ALOGW("Failed to add effects on input %d", input);
         }
     }
-    return input;
+    return NO_ERROR;
 }
 
 status_t AudioPolicyService::startInput(audio_io_handle_t input,
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index cd8df2f..b5a3d5b 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -900,7 +900,7 @@ status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
 
 audio_io_handle_t AudioPolicyManager::getOutputForDevice(
         audio_devices_t device,
-        audio_session_t session,
+        audio_session_t session __unused,
         audio_stream_type_t stream,
         uint32_t samplingRate,
         audio_format_t format,
@@ -1294,8 +1294,8 @@ status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
 }
 
 void AudioPolicyManager::releaseOutput(audio_io_handle_t output,
-                                       audio_stream_type_t stream,
-                                       audio_session_t session)
+                                       audio_stream_type_t stream __unused,
+                                       audio_session_t session __unused)
 {
     ALOGV("releaseOutput() %d", output);
     ssize_t index = mOutputs.indexOfKey(output);
@@ -1338,26 +1338,27 @@ void AudioPolicyManager::releaseOutput(audio_io_handle_t output,
 }
 
 
-audio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource,
-                                    uint32_t samplingRate,
-                                    audio_format_t format,
-                                    audio_channel_mask_t channelMask,
-                                    audio_session_t session,
-                                    audio_input_flags_t flags)
+status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
+                                             audio_io_handle_t *input,
+                                             audio_session_t session,
+                                             uint32_t samplingRate,
+                                             audio_format_t format,
+                                             audio_channel_mask_t channelMask,
+                                             audio_input_flags_t flags)
 {
-    ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, session %d, "
-          "flags %#x",
-          inputSource, samplingRate, format, channelMask, session, flags);
+    ALOGV("getInputForAttr() source %d, samplingRate %d, format %d, channelMask %x,"
+            "session %d, flags %#x",
+          attr->source, samplingRate, format, channelMask, session, flags);
 
-    audio_devices_t device = getDeviceForInputSource(inputSource);
+    audio_devices_t device = getDeviceForInputSource(attr->source);
 
     if (device == AUDIO_DEVICE_NONE) {
-        ALOGW("getInput() could not find device for inputSource %d", inputSource);
-        return AUDIO_IO_HANDLE_NONE;
+        ALOGW("getInputForAttr() could not find device for source %d", attr->source);
+        return BAD_VALUE;
     }
 
     // adapt channel selection to input source
-    switch (inputSource) {
+    switch (attr->source) {
     case AUDIO_SOURCE_VOICE_UPLINK:
         channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK;
         break;
@@ -1371,16 +1372,16 @@ audio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource,
         break;
     }
 
-    audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
+    *input = AUDIO_IO_HANDLE_NONE;
     bool isSoundTrigger = false;
-    audio_source_t halInputSource = inputSource;
-    if (inputSource == AUDIO_SOURCE_HOTWORD) {
+    audio_source_t halInputSource = attr->source;
+    if (attr->source == AUDIO_SOURCE_HOTWORD) {
         ssize_t index = mSoundTriggerSessions.indexOfKey(session);
         if (index >= 0) {
-            input = mSoundTriggerSessions.valueFor(session);
+            *input = mSoundTriggerSessions.valueFor(session);
             isSoundTrigger = true;
             flags = (audio_input_flags_t)(flags | AUDIO_INPUT_FLAG_HW_HOTWORD);
-            ALOGV("SoundTrigger capture on session %d input %d", session, input);
+            ALOGV("SoundTrigger capture on session %d input %d", session, *input);
         } else {
             halInputSource = AUDIO_SOURCE_VOICE_RECOGNITION;
         }
@@ -1401,16 +1402,16 @@ audio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource,
                                  channelMask,
                                  flags);
         if (profile == 0) {
-            ALOGW("getInput() could not find profile for device 0x%X, samplingRate %u, format %#x, "
-                    "channelMask 0x%X, flags %#x",
+            ALOGW("getInputForAttr() could not find profile for device 0x%X, samplingRate %u,"
+                    "format %#x, channelMask 0x%X, flags %#x",
                     device, samplingRate, format, channelMask, log_flags);
-            return AUDIO_IO_HANDLE_NONE;
+            return BAD_VALUE;
         }
     }
 
     if (profile->mModule->mHandle == 0) {
-        ALOGE("getInput(): HW module %s not opened", profile->mModule->mName);
-        return AUDIO_IO_HANDLE_NONE;
+        ALOGE("getInputForAttr(): HW module %s not opened", profile->mModule->mName);
+        return NO_INIT;
     }
 
     audio_config_t config = AUDIO_CONFIG_INITIALIZER;
@@ -1422,7 +1423,7 @@ audio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource,
     String8 address = deviceDistinguishesOnAddress(device) ? String8("0") : String8("");
 
     status_t status = mpClientInterface->openInput(profile->mModule->mHandle,
-                                                   &input,
+                                                   input,
                                                    &config,
                                                    &device,
                                                    address,
@@ -1430,20 +1431,20 @@ audio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource,
                                                    flags);
 
     // only accept input with the exact requested set of parameters
-    if (status != NO_ERROR ||
+    if (status != NO_ERROR || *input == AUDIO_IO_HANDLE_NONE ||
         (samplingRate != config.sample_rate) ||
         (format != config.format) ||
         (channelMask != config.channel_mask)) {
-        ALOGW("getInput() failed opening input: samplingRate %d, format %d, channelMask %x",
+        ALOGW("getInputForAttr() failed opening input: samplingRate %d, format %d, channelMask %x",
                 samplingRate, format, channelMask);
-        if (input != AUDIO_IO_HANDLE_NONE) {
-            mpClientInterface->closeInput(input);
+        if (*input != AUDIO_IO_HANDLE_NONE) {
+            mpClientInterface->closeInput(*input);
         }
-        return AUDIO_IO_HANDLE_NONE;
+        return BAD_VALUE;
     }
 
     sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile);
-    inputDesc->mInputSource = inputSource;
+    inputDesc->mInputSource = attr->source;
     inputDesc->mRefCount = 0;
     inputDesc->mOpenRefCount = 1;
     inputDesc->mSamplingRate = samplingRate;
@@ -1453,9 +1454,9 @@ audio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource,
     inputDesc->mSessions.add(session);
     inputDesc->mIsSoundTrigger = isSoundTrigger;
 
-    addInput(input, inputDesc);
+    addInput(*input, inputDesc);
     mpClientInterface->onAudioPortListUpdate();
-    return input;
+    return NO_ERROR;
 }
 
 status_t AudioPolicyManager::startInput(audio_io_handle_t input,
diff --git a/services/audiopolicy/AudioPolicyManager.h b/services/audiopolicy/AudioPolicyManager.h
index 6eb2163..e2b6480 100644
--- a/services/audiopolicy/AudioPolicyManager.h
+++ b/services/audiopolicy/AudioPolicyManager.h
@@ -105,12 +105,13 @@ public:
         virtual void releaseOutput(audio_io_handle_t output,
                                    audio_stream_type_t stream,
                                    audio_session_t session);
-        virtual audio_io_handle_t getInput(audio_source_t inputSource,
-                                            uint32_t samplingRate,
-                                            audio_format_t format,
-                                            audio_channel_mask_t channelMask,
-                                            audio_session_t session,
-                                            audio_input_flags_t flags);
+        virtual status_t getInputForAttr(const audio_attributes_t *attr,
+                                         audio_io_handle_t *input,
+                                         audio_session_t session,
+                                         uint32_t samplingRate,
+                                         audio_format_t format,
+                                         audio_channel_mask_t channelMask,
+                                         audio_input_flags_t flags);
 
         // indicates to the audio policy manager that the input starts being used.
         virtual status_t startInput(audio_io_handle_t input,
diff --git a/services/audiopolicy/AudioPolicyService.h b/services/audiopolicy/AudioPolicyService.h
index b8171d6..da17728 100644
--- a/services/audiopolicy/AudioPolicyService.h
+++ b/services/audiopolicy/AudioPolicyService.h
@@ -90,12 +90,13 @@ public:
     virtual void releaseOutput(audio_io_handle_t output,
                                audio_stream_type_t stream,
                                audio_session_t session);
-    virtual audio_io_handle_t getInput(audio_source_t inputSource,
-                                    uint32_t samplingRate,
-                                    audio_format_t format,
-                                    audio_channel_mask_t channelMask,
-                                    audio_session_t audioSession,
-                                    audio_input_flags_t flags);
+    virtual status_t getInputForAttr(const audio_attributes_t *attr,
+                                     audio_io_handle_t *input,
+                                     audio_session_t session,
+                                     uint32_t samplingRate,
+                                     audio_format_t format,
+                                     audio_channel_mask_t channelMask,
+                                     audio_input_flags_t flags);
     virtual status_t startInput(audio_io_handle_t input,
                                 audio_session_t session);
     virtual status_t stopInput(audio_io_handle_t input,
-- 
cgit v1.1