diff options
Diffstat (limited to 'media/libmedia/IAudioPolicyService.cpp')
-rw-r--r-- | media/libmedia/IAudioPolicyService.cpp | 225 |
1 files changed, 173 insertions, 52 deletions
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp index e840956..56c8f3d 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, @@ -69,7 +69,8 @@ enum { GET_OUTPUT_FOR_ATTR, ACQUIRE_SOUNDTRIGGER_SESSION, RELEASE_SOUNDTRIGGER_SESSION, - GET_PHONE_STATE + GET_PHONE_STATE, + REGISTER_POLICY_MIXES, }; #define MAX_ITEMS_PER_LIST 1024 @@ -162,21 +163,45 @@ public: return static_cast <audio_io_handle_t> (reply.readInt32()); } - virtual audio_io_handle_t getOutputForAttr( - const audio_attributes_t *attr, - uint32_t samplingRate, - audio_format_t format, - audio_channel_mask_t channelMask, - audio_output_flags_t flags, - const audio_offload_info_t *offloadInfo) + virtual status_t getOutputForAttr(const audio_attributes_t *attr, + audio_io_handle_t *output, + audio_session_t session, + audio_stream_type_t *stream, + uint32_t samplingRate, + audio_format_t format, + audio_channel_mask_t channelMask, + audio_output_flags_t flags, + const audio_offload_info_t *offloadInfo) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); if (attr == NULL) { - ALOGE("Writing NULL audio attributes - shouldn't happen"); - return (audio_io_handle_t) 0; + if (stream == NULL) { + ALOGE("getOutputForAttr(): NULL audio attributes and stream type"); + return BAD_VALUE; + } + if (*stream == AUDIO_STREAM_DEFAULT) { + ALOGE("getOutputForAttr unspecified stream type"); + return BAD_VALUE; + } + } + if (output == NULL) { + ALOGE("getOutputForAttr NULL output - shouldn't happen"); + return BAD_VALUE; + } + if (attr == NULL) { + data.writeInt32(0); + } else { + data.writeInt32(1); + data.write(attr, sizeof(audio_attributes_t)); + } + data.writeInt32(session); + if (stream == NULL) { + data.writeInt32(0); + } else { + data.writeInt32(1); + data.writeInt32(*stream); } - data.write(attr, sizeof(audio_attributes_t)); data.writeInt32(samplingRate); data.writeInt32(static_cast <uint32_t>(format)); data.writeInt32(channelMask); @@ -188,62 +213,93 @@ public: data.writeInt32(1); data.write(offloadInfo, sizeof(audio_offload_info_t)); } - remote()->transact(GET_OUTPUT_FOR_ATTR, data, &reply); - return static_cast <audio_io_handle_t> (reply.readInt32()); + status_t status = remote()->transact(GET_OUTPUT_FOR_ATTR, data, &reply); + if (status != NO_ERROR) { + return status; + } + status = (status_t)reply.readInt32(); + if (status != NO_ERROR) { + return status; + } + *output = (audio_io_handle_t)reply.readInt32(); + if (stream != NULL) { + *stream = (audio_stream_type_t)reply.readInt32(); + } + return status; } virtual status_t startOutput(audio_io_handle_t output, audio_stream_type_t stream, - int session) + audio_session_t session) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(output); data.writeInt32((int32_t) stream); - data.writeInt32(session); + data.writeInt32((int32_t)session); remote()->transact(START_OUTPUT, data, &reply); return static_cast <status_t> (reply.readInt32()); } virtual status_t stopOutput(audio_io_handle_t output, audio_stream_type_t stream, - int session) + audio_session_t session) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(output); data.writeInt32((int32_t) stream); - data.writeInt32(session); + data.writeInt32((int32_t)session); remote()->transact(STOP_OUTPUT, data, &reply); return static_cast <status_t> (reply.readInt32()); } - virtual void releaseOutput(audio_io_handle_t output) + virtual void releaseOutput(audio_io_handle_t output, + audio_stream_type_t stream, + audio_session_t session) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(output); + data.writeInt32((int32_t)stream); + data.writeInt32((int32_t)session); 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, - int 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(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, @@ -622,6 +678,38 @@ public: } return (audio_mode_t)reply.readInt32(); } + + virtual status_t registerPolicyMixes(Vector<AudioMix> mixes, bool registration) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + data.writeInt32(registration ? 1 : 0); + size_t size = mixes.size(); + if (size > MAX_MIXES_PER_POLICY) { + size = MAX_MIXES_PER_POLICY; + } + size_t sizePosition = data.dataPosition(); + data.writeInt32(size); + size_t finalSize = size; + for (size_t i = 0; i < size; i++) { + size_t position = data.dataPosition(); + if (mixes[i].writeToParcel(&data) != NO_ERROR) { + data.setDataPosition(position); + finalSize--; + } + } + if (size != finalSize) { + size_t position = data.dataPosition(); + data.setDataPosition(sizePosition); + data.writeInt32(finalSize); + data.setDataPosition(position); + } + status_t status = remote()->transact(REGISTER_POLICY_MIXES, data, &reply); + if (status == NO_ERROR) { + status = (status_t)reply.readInt32(); + } + return status; + } }; IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService"); @@ -707,8 +795,17 @@ status_t BnAudioPolicyService::onTransact( case GET_OUTPUT_FOR_ATTR: { CHECK_INTERFACE(IAudioPolicyService, data, reply); - audio_attributes_t *attr = (audio_attributes_t *) calloc(1, sizeof(audio_attributes_t)); - data.read(attr, sizeof(audio_attributes_t)); + audio_attributes_t attr; + bool hasAttributes = data.readInt32() != 0; + if (hasAttributes) { + data.read(&attr, sizeof(audio_attributes_t)); + } + audio_session_t session = (audio_session_t)data.readInt32(); + audio_stream_type_t stream = AUDIO_STREAM_DEFAULT; + bool hasStream = data.readInt32() != 0; + if (hasStream) { + stream = (audio_stream_type_t)data.readInt32(); + } uint32_t samplingRate = data.readInt32(); audio_format_t format = (audio_format_t) data.readInt32(); audio_channel_mask_t channelMask = data.readInt32(); @@ -719,13 +816,14 @@ status_t BnAudioPolicyService::onTransact( if (hasOffloadInfo) { data.read(&offloadInfo, sizeof(audio_offload_info_t)); } - audio_io_handle_t output = getOutputForAttr(attr, - samplingRate, - format, - channelMask, - flags, - hasOffloadInfo ? &offloadInfo : NULL); - reply->writeInt32(static_cast <int>(output)); + audio_io_handle_t output = 0; + status_t status = getOutputForAttr(hasAttributes ? &attr : NULL, + &output, session, &stream, + samplingRate, format, channelMask, + flags, hasOffloadInfo ? &offloadInfo : NULL); + reply->writeInt32(status); + reply->writeInt32(output); + reply->writeInt32(stream); return NO_ERROR; } break; @@ -734,7 +832,7 @@ status_t BnAudioPolicyService::onTransact( audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32()); audio_stream_type_t stream = static_cast <audio_stream_type_t>(data.readInt32()); - int session = data.readInt32(); + audio_session_t session = (audio_session_t)data.readInt32(); reply->writeInt32(static_cast <uint32_t>(startOutput(output, stream, session))); @@ -746,7 +844,7 @@ status_t BnAudioPolicyService::onTransact( audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32()); audio_stream_type_t stream = static_cast <audio_stream_type_t>(data.readInt32()); - int session = data.readInt32(); + audio_session_t session = (audio_session_t)data.readInt32(); reply->writeInt32(static_cast <uint32_t>(stopOutput(output, stream, session))); @@ -756,25 +854,29 @@ status_t BnAudioPolicyService::onTransact( case RELEASE_OUTPUT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32()); - releaseOutput(output); + audio_stream_type_t stream = (audio_stream_type_t)data.readInt32(); + audio_session_t session = (audio_session_t)data.readInt32(); + releaseOutput(output, stream, session); 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(); - int audioSession = 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; @@ -1100,6 +1202,25 @@ status_t BnAudioPolicyService::onTransact( return NO_ERROR; } break; + case REGISTER_POLICY_MIXES: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + bool registration = data.readInt32() == 1; + Vector<AudioMix> mixes; + size_t size = (size_t)data.readInt32(); + if (size > MAX_MIXES_PER_POLICY) { + size = MAX_MIXES_PER_POLICY; + } + for (size_t i = 0; i < size; i++) { + AudioMix mix; + if (mix.readFromParcel((Parcel*)&data) == NO_ERROR) { + mixes.add(mix); + } + } + status_t status = registerPolicyMixes(mixes, registration); + reply->writeInt32(status); + return NO_ERROR; + } break; + default: return BBinder::onTransact(code, data, reply, flags); } |