diff options
Diffstat (limited to 'media/libmedia/IAudioPolicyService.cpp')
-rw-r--r-- | media/libmedia/IAudioPolicyService.cpp | 423 |
1 files changed, 407 insertions, 16 deletions
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp index 4be3c09..256cb3f 100644 --- a/media/libmedia/IAudioPolicyService.cpp +++ b/media/libmedia/IAudioPolicyService.cpp @@ -57,7 +57,18 @@ enum { QUERY_DEFAULT_PRE_PROCESSING, SET_EFFECT_ENABLED, IS_STREAM_ACTIVE_REMOTELY, - IS_OFFLOAD_SUPPORTED + IS_OFFLOAD_SUPPORTED, + LIST_AUDIO_PORTS, + GET_AUDIO_PORT, + CREATE_AUDIO_PATCH, + RELEASE_AUDIO_PATCH, + LIST_AUDIO_PATCHES, + SET_AUDIO_PORT_CONFIG, + REGISTER_CLIENT, + GET_OUTPUT_FOR_ATTR, + ACQUIRE_SOUNDTRIGGER_SESSION, + RELEASE_SOUNDTRIGGER_SESSION, + GET_PHONE_STATE }; class BpAudioPolicyService : public BpInterface<IAudioPolicyService> @@ -137,6 +148,7 @@ public: data.writeInt32(static_cast <uint32_t>(format)); data.writeInt32(channelMask); data.writeInt32(static_cast <uint32_t>(flags)); + // hasOffloadInfo if (offloadInfo == NULL) { data.writeInt32(0); } else { @@ -147,6 +159,36 @@ 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) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + if (attr == NULL) { + ALOGE("Writing NULL audio attributes - shouldn't happen"); + return (audio_io_handle_t) 0; + } + data.write(attr, sizeof(audio_attributes_t)); + data.writeInt32(samplingRate); + data.writeInt32(static_cast <uint32_t>(format)); + data.writeInt32(channelMask); + data.writeInt32(static_cast <uint32_t>(flags)); + // hasOffloadInfo + if (offloadInfo == NULL) { + data.writeInt32(0); + } else { + 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()); + } + virtual status_t startOutput(audio_io_handle_t output, audio_stream_type_t stream, int session) @@ -186,7 +228,8 @@ public: uint32_t samplingRate, audio_format_t format, audio_channel_mask_t channelMask, - int audioSession) + int audioSession, + audio_input_flags_t flags) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); @@ -195,33 +238,40 @@ public: 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()); } - virtual status_t startInput(audio_io_handle_t input) + virtual status_t startInput(audio_io_handle_t input, + audio_session_t session) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(input); + data.writeInt32(session); remote()->transact(START_INPUT, data, &reply); return static_cast <status_t> (reply.readInt32()); } - virtual status_t stopInput(audio_io_handle_t input) + virtual status_t stopInput(audio_io_handle_t input, + audio_session_t session) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(input); + data.writeInt32(session); remote()->transact(STOP_INPUT, data, &reply); return static_cast <status_t> (reply.readInt32()); } - virtual void releaseInput(audio_io_handle_t input) + virtual void releaseInput(audio_io_handle_t input, + audio_session_t session) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(input); + data.writeInt32(session); remote()->transact(RELEASE_INPUT, data, &reply); } @@ -389,7 +439,186 @@ public: data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.write(&info, sizeof(audio_offload_info_t)); remote()->transact(IS_OFFLOAD_SUPPORTED, data, &reply); - return reply.readInt32(); } + return reply.readInt32(); + } + + virtual status_t listAudioPorts(audio_port_role_t role, + audio_port_type_t type, + unsigned int *num_ports, + struct audio_port *ports, + unsigned int *generation) + { + if (num_ports == NULL || (*num_ports != 0 && ports == NULL) || + generation == NULL) { + return BAD_VALUE; + } + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + unsigned int numPortsReq = (ports == NULL) ? 0 : *num_ports; + data.writeInt32(role); + data.writeInt32(type); + data.writeInt32(numPortsReq); + status_t status = remote()->transact(LIST_AUDIO_PORTS, data, &reply); + if (status == NO_ERROR) { + status = (status_t)reply.readInt32(); + *num_ports = (unsigned int)reply.readInt32(); + } + if (status == NO_ERROR) { + if (numPortsReq > *num_ports) { + numPortsReq = *num_ports; + } + if (numPortsReq > 0) { + reply.read(ports, numPortsReq * sizeof(struct audio_port)); + } + *generation = reply.readInt32(); + } + return status; + } + + virtual status_t getAudioPort(struct audio_port *port) + { + if (port == NULL) { + return BAD_VALUE; + } + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + data.write(port, sizeof(struct audio_port)); + status_t status = remote()->transact(GET_AUDIO_PORT, data, &reply); + if (status != NO_ERROR || + (status = (status_t)reply.readInt32()) != NO_ERROR) { + return status; + } + reply.read(port, sizeof(struct audio_port)); + return status; + } + + virtual status_t createAudioPatch(const struct audio_patch *patch, + audio_patch_handle_t *handle) + { + if (patch == NULL || handle == NULL) { + return BAD_VALUE; + } + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + data.write(patch, sizeof(struct audio_patch)); + data.write(handle, sizeof(audio_patch_handle_t)); + status_t status = remote()->transact(CREATE_AUDIO_PATCH, data, &reply); + if (status != NO_ERROR || + (status = (status_t)reply.readInt32()) != NO_ERROR) { + return status; + } + reply.read(handle, sizeof(audio_patch_handle_t)); + return status; + } + + virtual status_t releaseAudioPatch(audio_patch_handle_t handle) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + data.write(&handle, sizeof(audio_patch_handle_t)); + status_t status = remote()->transact(RELEASE_AUDIO_PATCH, data, &reply); + if (status != NO_ERROR) { + status = (status_t)reply.readInt32(); + } + return status; + } + + virtual status_t listAudioPatches(unsigned int *num_patches, + struct audio_patch *patches, + unsigned int *generation) + { + if (num_patches == NULL || (*num_patches != 0 && patches == NULL) || + generation == NULL) { + return BAD_VALUE; + } + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + unsigned int numPatchesReq = (patches == NULL) ? 0 : *num_patches; + data.writeInt32(numPatchesReq); + status_t status = remote()->transact(LIST_AUDIO_PATCHES, data, &reply); + if (status == NO_ERROR) { + status = (status_t)reply.readInt32(); + *num_patches = (unsigned int)reply.readInt32(); + } + if (status == NO_ERROR) { + if (numPatchesReq > *num_patches) { + numPatchesReq = *num_patches; + } + if (numPatchesReq > 0) { + reply.read(patches, numPatchesReq * sizeof(struct audio_patch)); + } + *generation = reply.readInt32(); + } + return status; + } + + virtual status_t setAudioPortConfig(const struct audio_port_config *config) + { + if (config == NULL) { + return BAD_VALUE; + } + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + data.write(config, sizeof(struct audio_port_config)); + status_t status = remote()->transact(SET_AUDIO_PORT_CONFIG, data, &reply); + if (status != NO_ERROR) { + status = (status_t)reply.readInt32(); + } + return status; + } + + virtual void registerClient(const sp<IAudioPolicyServiceClient>& client) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + data.writeStrongBinder(client->asBinder()); + remote()->transact(REGISTER_CLIENT, data, &reply); + } + + virtual status_t acquireSoundTriggerSession(audio_session_t *session, + audio_io_handle_t *ioHandle, + audio_devices_t *device) + { + if (session == NULL || ioHandle == NULL || device == NULL) { + return BAD_VALUE; + } + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + status_t status = remote()->transact(ACQUIRE_SOUNDTRIGGER_SESSION, data, &reply); + if (status != NO_ERROR) { + return status; + } + status = (status_t)reply.readInt32(); + if (status == NO_ERROR) { + *session = (audio_session_t)reply.readInt32(); + *ioHandle = (audio_io_handle_t)reply.readInt32(); + *device = (audio_devices_t)reply.readInt32(); + } + return status; + } + + virtual status_t releaseSoundTriggerSession(audio_session_t session) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + data.writeInt32(session); + status_t status = remote()->transact(RELEASE_SOUNDTRIGGER_SESSION, data, &reply); + if (status != NO_ERROR) { + return status; + } + return (status_t)reply.readInt32(); + } + + virtual audio_mode_t getPhoneState() + { + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + status_t status = remote()->transact(GET_PHONE_STATE, data, &reply); + if (status != NO_ERROR) { + return AUDIO_MODE_INVALID; + } + return (audio_mode_t)reply.readInt32(); + } }; IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService"); @@ -473,13 +702,38 @@ status_t BnAudioPolicyService::onTransact( return NO_ERROR; } break; + 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)); + uint32_t samplingRate = data.readInt32(); + audio_format_t format = (audio_format_t) data.readInt32(); + audio_channel_mask_t channelMask = data.readInt32(); + audio_output_flags_t flags = + static_cast <audio_output_flags_t>(data.readInt32()); + bool hasOffloadInfo = data.readInt32() != 0; + audio_offload_info_t offloadInfo; + 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)); + return NO_ERROR; + } break; + case START_OUTPUT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32()); - uint32_t stream = data.readInt32(); + audio_stream_type_t stream = + static_cast <audio_stream_type_t>(data.readInt32()); int session = data.readInt32(); reply->writeInt32(static_cast <uint32_t>(startOutput(output, - (audio_stream_type_t)stream, + stream, session))); return NO_ERROR; } break; @@ -487,10 +741,11 @@ status_t BnAudioPolicyService::onTransact( case STOP_OUTPUT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32()); - uint32_t stream = data.readInt32(); + audio_stream_type_t stream = + static_cast <audio_stream_type_t>(data.readInt32()); int session = data.readInt32(); reply->writeInt32(static_cast <uint32_t>(stopOutput(output, - (audio_stream_type_t)stream, + stream, session))); return NO_ERROR; } break; @@ -509,11 +764,13 @@ status_t BnAudioPolicyService::onTransact( 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); + audioSession, + flags); reply->writeInt32(static_cast <int>(input)); return NO_ERROR; } break; @@ -521,21 +778,24 @@ status_t BnAudioPolicyService::onTransact( case START_INPUT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_io_handle_t input = static_cast <audio_io_handle_t>(data.readInt32()); - reply->writeInt32(static_cast <uint32_t>(startInput(input))); + audio_session_t session = static_cast <audio_session_t>(data.readInt32()); + reply->writeInt32(static_cast <uint32_t>(startInput(input, session))); return NO_ERROR; } break; case STOP_INPUT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_io_handle_t input = static_cast <audio_io_handle_t>(data.readInt32()); - reply->writeInt32(static_cast <uint32_t>(stopInput(input))); + audio_session_t session = static_cast <audio_session_t>(data.readInt32()); + reply->writeInt32(static_cast <uint32_t>(stopInput(input, session))); return NO_ERROR; } break; case RELEASE_INPUT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_io_handle_t input = static_cast <audio_io_handle_t>(data.readInt32()); - releaseInput(input); + audio_session_t session = static_cast <audio_session_t>(data.readInt32()); + releaseInput(input, session); return NO_ERROR; } break; @@ -633,7 +893,7 @@ status_t BnAudioPolicyService::onTransact( CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_stream_type_t stream = (audio_stream_type_t) data.readInt32(); uint32_t inPastMs = (uint32_t)data.readInt32(); - reply->writeInt32( isStreamActive((audio_stream_type_t) stream, inPastMs) ); + reply->writeInt32( isStreamActive(stream, inPastMs) ); return NO_ERROR; } break; @@ -641,7 +901,7 @@ status_t BnAudioPolicyService::onTransact( CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_stream_type_t stream = (audio_stream_type_t) data.readInt32(); uint32_t inPastMs = (uint32_t)data.readInt32(); - reply->writeInt32( isStreamActiveRemotely((audio_stream_type_t) stream, inPastMs) ); + reply->writeInt32( isStreamActiveRemotely(stream, inPastMs) ); return NO_ERROR; } break; @@ -684,6 +944,137 @@ status_t BnAudioPolicyService::onTransact( return NO_ERROR; } + case LIST_AUDIO_PORTS: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + audio_port_role_t role = (audio_port_role_t)data.readInt32(); + audio_port_type_t type = (audio_port_type_t)data.readInt32(); + unsigned int numPortsReq = data.readInt32(); + unsigned int numPorts = numPortsReq; + unsigned int generation; + struct audio_port *ports = + (struct audio_port *)calloc(numPortsReq, sizeof(struct audio_port)); + status_t status = listAudioPorts(role, type, &numPorts, ports, &generation); + reply->writeInt32(status); + reply->writeInt32(numPorts); + + if (status == NO_ERROR) { + if (numPortsReq > numPorts) { + numPortsReq = numPorts; + } + reply->write(ports, numPortsReq * sizeof(struct audio_port)); + reply->writeInt32(generation); + } + free(ports); + return NO_ERROR; + } + + case GET_AUDIO_PORT: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + struct audio_port port; + data.read(&port, sizeof(struct audio_port)); + status_t status = getAudioPort(&port); + reply->writeInt32(status); + if (status == NO_ERROR) { + reply->write(&port, sizeof(struct audio_port)); + } + return NO_ERROR; + } + + case CREATE_AUDIO_PATCH: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + struct audio_patch patch; + data.read(&patch, sizeof(struct audio_patch)); + audio_patch_handle_t handle; + data.read(&handle, sizeof(audio_patch_handle_t)); + status_t status = createAudioPatch(&patch, &handle); + reply->writeInt32(status); + if (status == NO_ERROR) { + reply->write(&handle, sizeof(audio_patch_handle_t)); + } + return NO_ERROR; + } + + case RELEASE_AUDIO_PATCH: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + audio_patch_handle_t handle; + data.read(&handle, sizeof(audio_patch_handle_t)); + status_t status = releaseAudioPatch(handle); + reply->writeInt32(status); + return NO_ERROR; + } + + case LIST_AUDIO_PATCHES: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + unsigned int numPatchesReq = data.readInt32(); + unsigned int numPatches = numPatchesReq; + unsigned int generation; + struct audio_patch *patches = + (struct audio_patch *)calloc(numPatchesReq, + sizeof(struct audio_patch)); + status_t status = listAudioPatches(&numPatches, patches, &generation); + reply->writeInt32(status); + reply->writeInt32(numPatches); + if (status == NO_ERROR) { + if (numPatchesReq > numPatches) { + numPatchesReq = numPatches; + } + reply->write(patches, numPatchesReq * sizeof(struct audio_patch)); + reply->writeInt32(generation); + } + free(patches); + return NO_ERROR; + } + + case SET_AUDIO_PORT_CONFIG: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + struct audio_port_config config; + data.read(&config, sizeof(struct audio_port_config)); + status_t status = setAudioPortConfig(&config); + reply->writeInt32(status); + return NO_ERROR; + } + + case REGISTER_CLIENT: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + sp<IAudioPolicyServiceClient> client = interface_cast<IAudioPolicyServiceClient>( + data.readStrongBinder()); + registerClient(client); + return NO_ERROR; + } break; + + case ACQUIRE_SOUNDTRIGGER_SESSION: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + sp<IAudioPolicyServiceClient> client = interface_cast<IAudioPolicyServiceClient>( + data.readStrongBinder()); + audio_session_t session; + audio_io_handle_t ioHandle; + audio_devices_t device; + status_t status = acquireSoundTriggerSession(&session, &ioHandle, &device); + reply->writeInt32(status); + if (status == NO_ERROR) { + reply->writeInt32(session); + reply->writeInt32(ioHandle); + reply->writeInt32(device); + } + return NO_ERROR; + } break; + + case RELEASE_SOUNDTRIGGER_SESSION: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + sp<IAudioPolicyServiceClient> client = interface_cast<IAudioPolicyServiceClient>( + data.readStrongBinder()); + audio_session_t session = (audio_session_t)data.readInt32(); + status_t status = releaseSoundTriggerSession(session); + reply->writeInt32(status); + return NO_ERROR; + } break; + + case GET_PHONE_STATE: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + reply->writeInt32((int32_t)getPhoneState()); + return NO_ERROR; + } break; + default: return BBinder::onTransact(code, data, reply, flags); } |