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
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 @@
         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 @@
         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 @@
     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 @@
         }
     }
 
-    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 @@
     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 @@
     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 @@
     START_OUTPUT,
     STOP_OUTPUT,
     RELEASE_OUTPUT,
-    GET_INPUT,
+    GET_INPUT_FOR_ATTR,
     START_INPUT,
     STOP_INPUT,
     RELEASE_INPUT,
@@ -263,24 +263,40 @@
         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 @@
             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;