OSDN Git Service

IAudioPolicyService interface extension for patch panel
authorEric Laurent <elaurent@google.com>
Tue, 1 Apr 2014 17:34:16 +0000 (10:34 -0700)
committerEric Laurent <elaurent@google.com>
Tue, 27 May 2014 17:54:00 +0000 (10:54 -0700)
Change-Id: I0a62e5416edc41c3a0e816275085ab18a23066f1

include/media/AudioSystem.h
include/media/IAudioPolicyService.h
media/libmedia/AudioSystem.cpp
media/libmedia/IAudioPolicyService.cpp
services/audiopolicy/AudioPolicyInterfaceImpl.cpp
services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
services/audiopolicy/AudioPolicyService.h

index 402b479..a79a9ff 100644 (file)
@@ -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:
index 09b9ea6..6b6df6e 100644 (file)
@@ -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;
+
 };
 
 
index 2f16444..845ee20 100644 (file)
@@ -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<IAudioPolicyService>& 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<IAudioPolicyService>& 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<IAudioPolicyService>& 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<IAudioPolicyService>& 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<IAudioPolicyService>& 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<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    return aps->setAudioPortConfig(config);
+}
+
 // ---------------------------------------------------------------------------
 
 void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who __unused)
index 9bb4a49..ad2d4eb 100644 (file)
@@ -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<IAudioPolicyService>
@@ -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);
     }
index c57c4fa..7cd253b 100644 (file)
@@ -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
index bb62ab3..0bf4982 100644 (file)
@@ -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
index a7ed9e8..9f88b1e 100644 (file)
@@ -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);