From 8670c31fddbeadcf9627aa970c69a823f13939ff Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Tue, 1 Apr 2014 10:34:16 -0700 Subject: [PATCH] IAudioPolicyService interface extension for patch panel Change-Id: I0a62e5416edc41c3a0e816275085ab18a23066f1 --- include/media/AudioSystem.h | 25 +++ include/media/IAudioPolicyService.h | 25 +++ media/libmedia/AudioSystem.cpp | 49 +++++ media/libmedia/IAudioPolicyService.cpp | 228 ++++++++++++++++++++- services/audiopolicy/AudioPolicyInterfaceImpl.cpp | 38 ++++ .../audiopolicy/AudioPolicyInterfaceImplLegacy.cpp | 38 ++++ services/audiopolicy/AudioPolicyService.h | 14 ++ 7 files changed, 415 insertions(+), 2 deletions(-) diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index 402b479f68..a79a9ff254 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -274,6 +274,31 @@ public: // check presence of audio flinger service. // returns NO_ERROR if binding to service succeeds, DEAD_OBJECT otherwise static status_t checkAudioFlinger(); + + /* List available audio ports and their attributes */ + static status_t listAudioPorts(audio_port_role_t role, + audio_port_type_t type, + unsigned int *num_ports, + struct audio_port *ports, + unsigned int *generation); + + /* Get attributes for a given audio port */ + static status_t getAudioPort(struct audio_port *port); + + /* Create an audio patch between several source and sink ports */ + static status_t createAudioPatch(const struct audio_patch *patch, + audio_patch_handle_t *handle); + + /* Release an audio patch */ + static status_t releaseAudioPatch(audio_patch_handle_t handle); + + /* List existing audio patches */ + static status_t listAudioPatches(unsigned int *num_patches, + struct audio_patch *patches, + unsigned int *generation); + /* Set audio port configuration */ + static status_t setAudioPortConfig(const struct audio_port_config *config); + // ---------------------------------------------------------------------------- private: diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h index 09b9ea69bd..6b6df6efbd 100644 --- a/include/media/IAudioPolicyService.h +++ b/include/media/IAudioPolicyService.h @@ -99,6 +99,31 @@ public: // Check if offload is possible for given format, stream type, sample rate, // bit rate, duration, video and streaming or offload property is enabled virtual bool isOffloadSupported(const audio_offload_info_t& info) = 0; + + /* List available audio ports and their attributes */ + 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) = 0; + + /* Get attributes for a given audio port */ + virtual status_t getAudioPort(struct audio_port *port) = 0; + + /* Create an audio patch between several source and sink ports */ + virtual status_t createAudioPatch(const struct audio_patch *patch, + audio_patch_handle_t *handle) = 0; + + /* Release an audio patch */ + virtual status_t releaseAudioPatch(audio_patch_handle_t handle) = 0; + + /* List existing audio patches */ + virtual status_t listAudioPatches(unsigned int *num_patches, + struct audio_patch *patches, + unsigned int *generation) = 0; + /* Set audio port configuration */ + virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0; + }; diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index 2f164445e9..845ee20554 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -831,6 +831,55 @@ bool AudioSystem::isOffloadSupported(const audio_offload_info_t& info) return aps->isOffloadSupported(info); } +status_t AudioSystem::listAudioPorts(audio_port_role_t role, + audio_port_type_t type, + unsigned int *num_ports, + struct audio_port *ports, + unsigned int *generation) +{ + const sp& aps = AudioSystem::get_audio_policy_service(); + if (aps == 0) return PERMISSION_DENIED; + return aps->listAudioPorts(role, type, num_ports, ports, generation); +} + +status_t AudioSystem::getAudioPort(struct audio_port *port) +{ + const sp& aps = AudioSystem::get_audio_policy_service(); + if (aps == 0) return PERMISSION_DENIED; + return aps->getAudioPort(port); +} + +status_t AudioSystem::createAudioPatch(const struct audio_patch *patch, + audio_patch_handle_t *handle) +{ + const sp& aps = AudioSystem::get_audio_policy_service(); + if (aps == 0) return PERMISSION_DENIED; + return aps->createAudioPatch(patch, handle); +} + +status_t AudioSystem::releaseAudioPatch(audio_patch_handle_t handle) +{ + const sp& aps = AudioSystem::get_audio_policy_service(); + if (aps == 0) return PERMISSION_DENIED; + return aps->releaseAudioPatch(handle); +} + +status_t AudioSystem::listAudioPatches(unsigned int *num_patches, + struct audio_patch *patches, + unsigned int *generation) +{ + const sp& aps = AudioSystem::get_audio_policy_service(); + if (aps == 0) return PERMISSION_DENIED; + return aps->listAudioPatches(num_patches, patches, generation); +} + +status_t AudioSystem::setAudioPortConfig(const struct audio_port_config *config) +{ + const sp& aps = AudioSystem::get_audio_policy_service(); + if (aps == 0) return PERMISSION_DENIED; + return aps->setAudioPortConfig(config); +} + // --------------------------------------------------------------------------- void AudioSystem::AudioPolicyServiceClient::binderDied(const wp& who __unused) diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp index 9bb4a49509..ad2d4eb22c 100644 --- a/media/libmedia/IAudioPolicyService.cpp +++ b/media/libmedia/IAudioPolicyService.cpp @@ -57,7 +57,13 @@ 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 }; class BpAudioPolicyService : public BpInterface @@ -390,7 +396,134 @@ 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(); + } + ALOGI("listAudioPorts() status %d got *num_ports %d", status, *num_ports); + 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; + } }; IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService"); @@ -687,6 +820,97 @@ 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); + ALOGI("LIST_AUDIO_PORTS status %d got numPorts %d", status, 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; + } + default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp index c57c4fab21..7cd253b720 100644 --- a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp +++ b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp @@ -463,5 +463,43 @@ bool AudioPolicyService::isOffloadSupported(const audio_offload_info_t& info) return mAudioPolicyManager->isOffloadSupported(info); } +status_t AudioPolicyService::listAudioPorts(audio_port_role_t role __unused, + audio_port_type_t type __unused, + unsigned int *num_ports, + struct audio_port *ports __unused, + unsigned int *generation __unused) +{ + *num_ports = 0; + return INVALID_OPERATION; +} + +status_t AudioPolicyService::getAudioPort(struct audio_port *port __unused) +{ + return INVALID_OPERATION; +} + +status_t AudioPolicyService::createAudioPatch(const struct audio_patch *patch __unused, + audio_patch_handle_t *handle __unused) +{ + return INVALID_OPERATION; +} + +status_t AudioPolicyService::releaseAudioPatch(audio_patch_handle_t handle __unused) +{ + return INVALID_OPERATION; +} + +status_t AudioPolicyService::listAudioPatches(unsigned int *num_patches, + struct audio_patch *patches __unused, + unsigned int *generation __unused) +{ + *num_patches = 0; + return INVALID_OPERATION; +} + +status_t AudioPolicyService::setAudioPortConfig(const struct audio_port_config *config __unused) +{ + return INVALID_OPERATION; +} }; // namespace android diff --git a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp index bb62ab3fd6..0bf49826fd 100644 --- a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp +++ b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp @@ -485,5 +485,43 @@ bool AudioPolicyService::isOffloadSupported(const audio_offload_info_t& info) return mpAudioPolicy->is_offload_supported(mpAudioPolicy, &info); } +status_t AudioPolicyService::listAudioPorts(audio_port_role_t role __unused, + audio_port_type_t type __unused, + unsigned int *num_ports, + struct audio_port *ports __unused, + unsigned int *generation __unused) +{ + *num_ports = 0; + return INVALID_OPERATION; +} + +status_t AudioPolicyService::getAudioPort(struct audio_port *port __unused) +{ + return INVALID_OPERATION; +} + +status_t AudioPolicyService::createAudioPatch(const struct audio_patch *patch __unused, + audio_patch_handle_t *handle __unused) +{ + return INVALID_OPERATION; +} + +status_t AudioPolicyService::releaseAudioPatch(audio_patch_handle_t handle __unused) +{ + return INVALID_OPERATION; +} + +status_t AudioPolicyService::listAudioPatches(unsigned int *num_patches, + struct audio_patch *patches __unused, + unsigned int *generation __unused) +{ + *num_patches = 0; + return INVALID_OPERATION; +} + +status_t AudioPolicyService::setAudioPortConfig(const struct audio_port_config *config __unused) +{ + return INVALID_OPERATION; +} }; // namespace android diff --git a/services/audiopolicy/AudioPolicyService.h b/services/audiopolicy/AudioPolicyService.h index a7ed9e8737..9f88b1e188 100644 --- a/services/audiopolicy/AudioPolicyService.h +++ b/services/audiopolicy/AudioPolicyService.h @@ -140,6 +140,20 @@ public: virtual status_t setVoiceVolume(float volume, int delayMs = 0); virtual bool isOffloadSupported(const audio_offload_info_t &config); + 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); + virtual status_t getAudioPort(struct audio_port *port); + virtual status_t createAudioPatch(const struct audio_patch *patch, + audio_patch_handle_t *handle); + virtual status_t releaseAudioPatch(audio_patch_handle_t handle); + virtual status_t listAudioPatches(unsigned int *num_patches, + struct audio_patch *patches, + unsigned int *generation); + virtual status_t setAudioPortConfig(const struct audio_port_config *config); + status_t doStopOutput(audio_io_handle_t output, audio_stream_type_t stream, int session = 0); -- 2.11.0