/*
**
** Copyright 2009, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

#define LOG_TAG "IAudioPolicyService"
#include <utils/Log.h>

#include <stdint.h>
#include <math.h>
#include <sys/types.h>

#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include <media/AudioEffect.h>
#include <media/IAudioPolicyService.h>
#include <media/TimeCheck.h>
#include <mediautils/ServiceUtilities.h>
#include <system/audio.h>

namespace android {

enum {
    SET_DEVICE_CONNECTION_STATE = IBinder::FIRST_CALL_TRANSACTION,
    GET_DEVICE_CONNECTION_STATE,
    HANDLE_DEVICE_CONFIG_CHANGE,
    SET_PHONE_STATE,
    SET_RINGER_MODE,    // reserved, no longer used
    SET_FORCE_USE,
    GET_FORCE_USE,
    GET_OUTPUT,
    START_OUTPUT,
    STOP_OUTPUT,
    RELEASE_OUTPUT,
    GET_INPUT_FOR_ATTR,
    START_INPUT,
    STOP_INPUT,
    RELEASE_INPUT,
    INIT_STREAM_VOLUME,
    SET_STREAM_VOLUME,
    GET_STREAM_VOLUME,
    GET_STRATEGY_FOR_STREAM,
    GET_OUTPUT_FOR_EFFECT,
    REGISTER_EFFECT,
    UNREGISTER_EFFECT,
    IS_STREAM_ACTIVE,
    IS_SOURCE_ACTIVE,
    GET_DEVICES_FOR_STREAM,
    QUERY_DEFAULT_PRE_PROCESSING,
    SET_EFFECT_ENABLED,
    IS_STREAM_ACTIVE_REMOTELY,
    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,
    REGISTER_POLICY_MIXES,
    START_AUDIO_SOURCE,
    STOP_AUDIO_SOURCE,
    SET_AUDIO_PORT_CALLBACK_ENABLED,
    SET_MASTER_MONO,
    GET_MASTER_MONO,
    GET_STREAM_VOLUME_DB,
    GET_SURROUND_FORMATS,
    SET_SURROUND_FORMAT_ENABLED
};

#define MAX_ITEMS_PER_LIST 1024

class BpAudioPolicyService : public BpInterface<IAudioPolicyService>
{
public:
    explicit BpAudioPolicyService(const sp<IBinder>& impl)
        : BpInterface<IAudioPolicyService>(impl)
    {
    }

    virtual status_t setDeviceConnectionState(
                                    audio_devices_t device,
                                    audio_policy_dev_state_t state,
                                    const char *device_address,
                                    const char *device_name)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(static_cast <uint32_t>(device));
        data.writeInt32(static_cast <uint32_t>(state));
        data.writeCString(device_address);
        data.writeCString(device_name);
        remote()->transact(SET_DEVICE_CONNECTION_STATE, data, &reply);
        return static_cast <status_t> (reply.readInt32());
    }

    virtual audio_policy_dev_state_t getDeviceConnectionState(
                                    audio_devices_t device,
                                    const char *device_address)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(static_cast <uint32_t>(device));
        data.writeCString(device_address);
        remote()->transact(GET_DEVICE_CONNECTION_STATE, data, &reply);
        return static_cast <audio_policy_dev_state_t>(reply.readInt32());
    }

    virtual status_t handleDeviceConfigChange(audio_devices_t device,
                                              const char *device_address,
                                              const char *device_name)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(static_cast <uint32_t>(device));
        data.writeCString(device_address);
        data.writeCString(device_name);
        remote()->transact(HANDLE_DEVICE_CONFIG_CHANGE, data, &reply);
        return static_cast <status_t> (reply.readInt32());
    }

    virtual status_t setPhoneState(audio_mode_t state)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(state);
        remote()->transact(SET_PHONE_STATE, data, &reply);
        return static_cast <status_t> (reply.readInt32());
    }

    virtual status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(static_cast <uint32_t>(usage));
        data.writeInt32(static_cast <uint32_t>(config));
        remote()->transact(SET_FORCE_USE, data, &reply);
        return static_cast <status_t> (reply.readInt32());
    }

    virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(static_cast <uint32_t>(usage));
        remote()->transact(GET_FORCE_USE, data, &reply);
        return static_cast <audio_policy_forced_cfg_t> (reply.readInt32());
    }

    virtual audio_io_handle_t getOutput(audio_stream_type_t stream)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(static_cast <uint32_t>(stream));
        remote()->transact(GET_OUTPUT, data, &reply);
        return static_cast <audio_io_handle_t> (reply.readInt32());
    }

    virtual status_t getOutputForAttr(const audio_attributes_t *attr,
                                        audio_io_handle_t *output,
                                        audio_session_t session,
                                        audio_stream_type_t *stream,
                                        pid_t pid,
                                        uid_t uid,
                                        const audio_config_t *config,
                                        audio_output_flags_t flags,
                                        audio_port_handle_t *selectedDeviceId,
                                        audio_port_handle_t *portId)
        {
            Parcel data, reply;
            data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
            if (attr == NULL) {
                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 (selectedDeviceId == NULL) {
                ALOGE("getOutputForAttr NULL selectedDeviceId - shouldn't happen");
                return BAD_VALUE;
            }
            if (portId == NULL) {
                ALOGE("getOutputForAttr NULL portId - 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.writeInt32(pid);
            data.writeInt32(uid);
            data.write(config, sizeof(audio_config_t));
            data.writeInt32(static_cast <uint32_t>(flags));
            data.writeInt32(*selectedDeviceId);
            data.writeInt32(*portId);
            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();
            audio_stream_type_t lStream = (audio_stream_type_t)reply.readInt32();
            if (stream != NULL) {
                *stream = lStream;
            }
            *selectedDeviceId = (audio_port_handle_t)reply.readInt32();
            *portId = (audio_port_handle_t)reply.readInt32();
            return status;
        }

    virtual status_t startOutput(audio_port_handle_t portId)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32((int32_t)portId);
        remote()->transact(START_OUTPUT, data, &reply);
        return static_cast <status_t> (reply.readInt32());
    }

    virtual status_t stopOutput(audio_port_handle_t portId)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32((int32_t)portId);
        remote()->transact(STOP_OUTPUT, data, &reply);
        return static_cast <status_t> (reply.readInt32());
    }

    virtual void releaseOutput(audio_port_handle_t portId)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32((int32_t)portId);
        remote()->transact(RELEASE_OUTPUT, data, &reply);
    }

    virtual status_t getInputForAttr(const audio_attributes_t *attr,
                                     audio_io_handle_t *input,
                                     audio_session_t session,
                                     pid_t pid,
                                     uid_t uid,
                                     const String16& opPackageName,
                                     const audio_config_base_t *config,
                                     audio_input_flags_t flags,
                                     audio_port_handle_t *selectedDeviceId,
                                     audio_port_handle_t *portId)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        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;
        }
        if (selectedDeviceId == NULL) {
            ALOGE("getInputForAttr NULL selectedDeviceId - shouldn't happen");
            return BAD_VALUE;
        }
        if (portId == NULL) {
            ALOGE("getInputForAttr NULL portId - shouldn't happen");
            return BAD_VALUE;
        }
        data.write(attr, sizeof(audio_attributes_t));
        data.writeInt32(*input);
        data.writeInt32(session);
        data.writeInt32(pid);
        data.writeInt32(uid);
        data.writeString16(opPackageName);
        data.write(config, sizeof(audio_config_base_t));
        data.writeInt32(flags);
        data.writeInt32(*selectedDeviceId);
        data.writeInt32(*portId);
        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();
        *selectedDeviceId = (audio_port_handle_t)reply.readInt32();
        *portId = (audio_port_handle_t)reply.readInt32();
        return NO_ERROR;
    }

    virtual status_t startInput(audio_port_handle_t portId,
                                bool *silenced)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(portId);
        data.writeInt32(*silenced ? 1 : 0);
        remote()->transact(START_INPUT, data, &reply);
        status_t status = static_cast <status_t> (reply.readInt32());
        *silenced = reply.readInt32() == 1;
        return status;
    }

    virtual status_t stopInput(audio_port_handle_t portId)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(portId);
        remote()->transact(STOP_INPUT, data, &reply);
        return static_cast <status_t> (reply.readInt32());
    }

    virtual void releaseInput(audio_port_handle_t portId)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(portId);
        remote()->transact(RELEASE_INPUT, data, &reply);
    }

    virtual status_t initStreamVolume(audio_stream_type_t stream,
                                    int indexMin,
                                    int indexMax)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(static_cast <uint32_t>(stream));
        data.writeInt32(indexMin);
        data.writeInt32(indexMax);
        remote()->transact(INIT_STREAM_VOLUME, data, &reply);
        return static_cast <status_t> (reply.readInt32());
    }

    virtual status_t setStreamVolumeIndex(audio_stream_type_t stream,
                                          int index,
                                          audio_devices_t device)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(static_cast <uint32_t>(stream));
        data.writeInt32(index);
        data.writeInt32(static_cast <uint32_t>(device));
        remote()->transact(SET_STREAM_VOLUME, data, &reply);
        return static_cast <status_t> (reply.readInt32());
    }

    virtual status_t getStreamVolumeIndex(audio_stream_type_t stream,
                                          int *index,
                                          audio_devices_t device)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(static_cast <uint32_t>(stream));
        data.writeInt32(static_cast <uint32_t>(device));

        remote()->transact(GET_STREAM_VOLUME, data, &reply);
        int lIndex = reply.readInt32();
        if (index) *index = lIndex;
        return static_cast <status_t> (reply.readInt32());
    }

    virtual uint32_t getStrategyForStream(audio_stream_type_t stream)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(static_cast <uint32_t>(stream));
        remote()->transact(GET_STRATEGY_FOR_STREAM, data, &reply);
        return reply.readInt32();
    }

    virtual audio_devices_t getDevicesForStream(audio_stream_type_t stream)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(static_cast <uint32_t>(stream));
        remote()->transact(GET_DEVICES_FOR_STREAM, data, &reply);
        return (audio_devices_t) reply.readInt32();
    }

    virtual audio_io_handle_t getOutputForEffect(const effect_descriptor_t *desc)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.write(desc, sizeof(effect_descriptor_t));
        remote()->transact(GET_OUTPUT_FOR_EFFECT, data, &reply);
        return static_cast <audio_io_handle_t> (reply.readInt32());
    }

    virtual status_t registerEffect(const effect_descriptor_t *desc,
                                        audio_io_handle_t io,
                                        uint32_t strategy,
                                        audio_session_t session,
                                        int id)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.write(desc, sizeof(effect_descriptor_t));
        data.writeInt32(io);
        data.writeInt32(strategy);
        data.writeInt32(session);
        data.writeInt32(id);
        remote()->transact(REGISTER_EFFECT, data, &reply);
        return static_cast <status_t> (reply.readInt32());
    }

    virtual status_t unregisterEffect(int id)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(id);
        remote()->transact(UNREGISTER_EFFECT, data, &reply);
        return static_cast <status_t> (reply.readInt32());
    }

    virtual status_t setEffectEnabled(int id, bool enabled)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(id);
        data.writeInt32(enabled);
        remote()->transact(SET_EFFECT_ENABLED, data, &reply);
        return static_cast <status_t> (reply.readInt32());
    }

    virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32((int32_t) stream);
        data.writeInt32(inPastMs);
        remote()->transact(IS_STREAM_ACTIVE, data, &reply);
        return reply.readInt32();
    }

    virtual bool isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32((int32_t) stream);
        data.writeInt32(inPastMs);
        remote()->transact(IS_STREAM_ACTIVE_REMOTELY, data, &reply);
        return reply.readInt32();
    }

    virtual bool isSourceActive(audio_source_t source) const
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32((int32_t) source);
        remote()->transact(IS_SOURCE_ACTIVE, data, &reply);
        return reply.readInt32();
    }

    virtual status_t queryDefaultPreProcessing(audio_session_t audioSession,
                                               effect_descriptor_t *descriptors,
                                               uint32_t *count)
    {
        if (descriptors == NULL || count == NULL) {
            return BAD_VALUE;
        }
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(audioSession);
        data.writeInt32(*count);
        status_t status = remote()->transact(QUERY_DEFAULT_PRE_PROCESSING, data, &reply);
        if (status != NO_ERROR) {
            return status;
        }
        status = static_cast <status_t> (reply.readInt32());
        uint32_t retCount = reply.readInt32();
        if (retCount != 0) {
            uint32_t numDesc = (retCount < *count) ? retCount : *count;
            reply.read(descriptors, sizeof(effect_descriptor_t) * numDesc);
        }
        *count = retCount;
        return status;
    }

    virtual bool isOffloadSupported(const audio_offload_info_t& info)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.write(&info, sizeof(audio_offload_info_t));
        remote()->transact(IS_OFFLOAD_SUPPORTED, data, &reply);
        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(IInterface::asBinder(client));
        remote()->transact(REGISTER_CLIENT, data, &reply);
    }

    virtual void setAudioPortCallbacksEnabled(bool enabled)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(enabled ? 1 : 0);
        remote()->transact(SET_AUDIO_PORT_CALLBACK_ENABLED, 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();
    }

    virtual status_t registerPolicyMixes(const 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;
    }

    virtual status_t startAudioSource(const struct audio_port_config *source,
                                      const audio_attributes_t *attributes,
                                      audio_patch_handle_t *handle)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        if (source == NULL || attributes == NULL || handle == NULL) {
            return BAD_VALUE;
        }
        data.write(source, sizeof(struct audio_port_config));
        data.write(attributes, sizeof(audio_attributes_t));
        status_t status = remote()->transact(START_AUDIO_SOURCE, data, &reply);
        if (status != NO_ERROR) {
            return status;
        }
        status = (status_t)reply.readInt32();
        if (status != NO_ERROR) {
            return status;
        }
        *handle = (audio_patch_handle_t)reply.readInt32();
        return status;
    }

    virtual status_t stopAudioSource(audio_patch_handle_t handle)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(handle);
        status_t status = remote()->transact(STOP_AUDIO_SOURCE, data, &reply);
        if (status != NO_ERROR) {
            return status;
        }
        status = (status_t)reply.readInt32();
        return status;
    }

    virtual status_t setMasterMono(bool mono)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(static_cast<int32_t>(mono));
        status_t status = remote()->transact(SET_MASTER_MONO, data, &reply);
        if (status != NO_ERROR) {
            return status;
        }
        return static_cast<status_t>(reply.readInt32());
    }

    virtual status_t getMasterMono(bool *mono)
    {
        if (mono == nullptr) {
            return BAD_VALUE;
        }
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());

        status_t status = remote()->transact(GET_MASTER_MONO, data, &reply);
        if (status != NO_ERROR) {
            return status;
        }
        status = static_cast<status_t>(reply.readInt32());
        if (status == NO_ERROR) {
            *mono = static_cast<bool>(reply.readInt32());
        }
        return status;
    }

    virtual float getStreamVolumeDB(audio_stream_type_t stream, int index, audio_devices_t device)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(static_cast <int32_t>(stream));
        data.writeInt32(static_cast <int32_t>(index));
        data.writeUint32(static_cast <uint32_t>(device));
        status_t status = remote()->transact(GET_STREAM_VOLUME_DB, data, &reply);
        if (status != NO_ERROR) {
            return NAN;
        }
        return reply.readFloat();
    }

    virtual status_t getSurroundFormats(unsigned int *numSurroundFormats,
                                        audio_format_t *surroundFormats,
                                        bool *surroundFormatsEnabled,
                                        bool reported)
    {
        if (numSurroundFormats == NULL || (*numSurroundFormats != 0 &&
                (surroundFormats == NULL || surroundFormatsEnabled == NULL))) {
            return BAD_VALUE;
        }
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        unsigned int numSurroundFormatsReq = *numSurroundFormats;
        data.writeUint32(numSurroundFormatsReq);
        data.writeBool(reported);
        status_t status = remote()->transact(GET_SURROUND_FORMATS, data, &reply);
        if (status == NO_ERROR && (status = (status_t)reply.readInt32()) == NO_ERROR) {
            *numSurroundFormats = reply.readUint32();
        }
        if (status == NO_ERROR) {
            if (numSurroundFormatsReq > *numSurroundFormats) {
                numSurroundFormatsReq = *numSurroundFormats;
            }
            if (numSurroundFormatsReq > 0) {
                status = reply.read(surroundFormats,
                                    numSurroundFormatsReq * sizeof(audio_format_t));
                if (status != NO_ERROR) {
                    return status;
                }
                status = reply.read(surroundFormatsEnabled,
                                    numSurroundFormatsReq * sizeof(bool));
            }
        }
        return status;
    }

    virtual status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
        data.writeInt32(audioFormat);
        data.writeBool(enabled);
        status_t status = remote()->transact(SET_SURROUND_FORMAT_ENABLED, data, &reply);
        if (status != NO_ERROR) {
            return status;
        }
        return reply.readInt32();
    }
};

IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");

// ----------------------------------------------------------------------

status_t BnAudioPolicyService::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    // make sure transactions reserved to AudioFlinger do not come from other processes
    switch (code) {
        case START_OUTPUT:
        case STOP_OUTPUT:
        case RELEASE_OUTPUT:
        case GET_INPUT_FOR_ATTR:
        case START_INPUT:
        case STOP_INPUT:
        case RELEASE_INPUT:
        case GET_STRATEGY_FOR_STREAM:
        case GET_OUTPUT_FOR_EFFECT:
        case REGISTER_EFFECT:
        case UNREGISTER_EFFECT:
        case SET_EFFECT_ENABLED:
        case GET_OUTPUT_FOR_ATTR:
        case ACQUIRE_SOUNDTRIGGER_SESSION:
        case RELEASE_SOUNDTRIGGER_SESSION:
            ALOGW("%s: transaction %d received from PID %d",
                  __func__, code, IPCThreadState::self()->getCallingPid());
            // return status only for non void methods
            switch (code) {
                case RELEASE_OUTPUT:
                case RELEASE_INPUT:
                    break;
                default:
                    reply->writeInt32(static_cast<int32_t> (INVALID_OPERATION));
                    break;
            }
            return OK;
        default:
            break;
    }

    // make sure the following transactions come from system components
    switch (code) {
        case SET_DEVICE_CONNECTION_STATE:
        case HANDLE_DEVICE_CONFIG_CHANGE:
        case SET_PHONE_STATE:
//FIXME: Allow SET_FORCE_USE calls from system apps until a better use case routing API is available
//      case SET_FORCE_USE:
        case INIT_STREAM_VOLUME:
        case SET_STREAM_VOLUME:
        case REGISTER_POLICY_MIXES:
        case SET_MASTER_MONO:
        case START_AUDIO_SOURCE:
        case STOP_AUDIO_SOURCE:
        case GET_SURROUND_FORMATS:
        case SET_SURROUND_FORMAT_ENABLED: {
            if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
                ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
                      __func__, code, IPCThreadState::self()->getCallingPid(),
                      IPCThreadState::self()->getCallingUid());
                reply->writeInt32(static_cast<int32_t> (INVALID_OPERATION));
                return OK;
            }
        } break;
        default:
            break;
    }

    TimeCheck check("IAudioPolicyService");

    switch (code) {
        case SET_DEVICE_CONNECTION_STATE: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_devices_t device =
                    static_cast <audio_devices_t>(data.readInt32());
            audio_policy_dev_state_t state =
                    static_cast <audio_policy_dev_state_t>(data.readInt32());
            const char *device_address = data.readCString();
            const char *device_name = data.readCString();
            if (device_address == nullptr || device_name == nullptr) {
                ALOGE("Bad Binder transaction: SET_DEVICE_CONNECTION_STATE for device %u", device);
                reply->writeInt32(static_cast<int32_t> (BAD_VALUE));
            } else {
                reply->writeInt32(static_cast<uint32_t> (setDeviceConnectionState(device,
                                                                                  state,
                                                                                  device_address,
                                                                                  device_name)));
            }
            return NO_ERROR;
        } break;

        case GET_DEVICE_CONNECTION_STATE: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_devices_t device =
                    static_cast<audio_devices_t> (data.readInt32());
            const char *device_address = data.readCString();
            if (device_address == nullptr) {
                ALOGE("Bad Binder transaction: GET_DEVICE_CONNECTION_STATE for device %u", device);
                reply->writeInt32(static_cast<int32_t> (AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
            } else {
                reply->writeInt32(static_cast<uint32_t> (getDeviceConnectionState(device,
                                                                                  device_address)));
            }
            return NO_ERROR;
        } break;

        case HANDLE_DEVICE_CONFIG_CHANGE: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_devices_t device =
                    static_cast <audio_devices_t>(data.readInt32());
            const char *device_address = data.readCString();
            const char *device_name = data.readCString();
            if (device_address == nullptr || device_name == nullptr) {
                ALOGE("Bad Binder transaction: HANDLE_DEVICE_CONFIG_CHANGE for device %u", device);
                reply->writeInt32(static_cast<int32_t> (BAD_VALUE));
            } else {
                reply->writeInt32(static_cast<uint32_t> (handleDeviceConfigChange(device,
                                                                                  device_address,
                                                                                  device_name)));
            }
            return NO_ERROR;
        } break;

        case SET_PHONE_STATE: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            reply->writeInt32(static_cast <uint32_t>(setPhoneState(
                    (audio_mode_t) data.readInt32())));
            return NO_ERROR;
        } break;

        case SET_FORCE_USE: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_policy_force_use_t usage = static_cast <audio_policy_force_use_t>(
                    data.readInt32());
            audio_policy_forced_cfg_t config =
                    static_cast <audio_policy_forced_cfg_t>(data.readInt32());
            reply->writeInt32(static_cast <uint32_t>(setForceUse(usage, config)));
            return NO_ERROR;
        } break;

        case GET_FORCE_USE: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_policy_force_use_t usage = static_cast <audio_policy_force_use_t>(
                    data.readInt32());
            reply->writeInt32(static_cast <uint32_t>(getForceUse(usage)));
            return NO_ERROR;
        } break;

        case GET_OUTPUT: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_stream_type_t stream =
                    static_cast <audio_stream_type_t>(data.readInt32());
            audio_io_handle_t output = getOutput(stream);
            reply->writeInt32(static_cast <int>(output));
            return NO_ERROR;
        } break;

        case GET_OUTPUT_FOR_ATTR: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_attributes_t attr = {};
            bool hasAttributes = data.readInt32() != 0;
            if (hasAttributes) {
                data.read(&attr, sizeof(audio_attributes_t));
                sanetizeAudioAttributes(&attr);
            }
            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();
            }
            pid_t pid = (pid_t)data.readInt32();
            uid_t uid = (uid_t)data.readInt32();
            audio_config_t config;
            memset(&config, 0, sizeof(audio_config_t));
            data.read(&config, sizeof(audio_config_t));
            audio_output_flags_t flags =
                    static_cast <audio_output_flags_t>(data.readInt32());
            audio_port_handle_t selectedDeviceId = data.readInt32();
            audio_port_handle_t portId = (audio_port_handle_t)data.readInt32();
            audio_io_handle_t output = 0;
            status_t status = getOutputForAttr(hasAttributes ? &attr : NULL,
                    &output, session, &stream, pid, uid,
                    &config,
                    flags, &selectedDeviceId, &portId);
            reply->writeInt32(status);
            reply->writeInt32(output);
            reply->writeInt32(stream);
            reply->writeInt32(selectedDeviceId);
            reply->writeInt32(portId);
            return NO_ERROR;
        } break;

        case START_OUTPUT: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            const audio_port_handle_t portId = static_cast <audio_port_handle_t>(data.readInt32());
            reply->writeInt32(static_cast <uint32_t>(startOutput(portId)));
            return NO_ERROR;
        } break;

        case STOP_OUTPUT: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            const audio_port_handle_t portId = static_cast <audio_port_handle_t>(data.readInt32());
            reply->writeInt32(static_cast <uint32_t>(stopOutput(portId)));
            return NO_ERROR;
        } break;

        case RELEASE_OUTPUT: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            const audio_port_handle_t portId = static_cast <audio_port_handle_t>(data.readInt32());
            releaseOutput(portId);
            return NO_ERROR;
        } break;

        case GET_INPUT_FOR_ATTR: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_attributes_t attr = {};
            data.read(&attr, sizeof(audio_attributes_t));
            sanetizeAudioAttributes(&attr);
            audio_io_handle_t input = (audio_io_handle_t)data.readInt32();
            audio_session_t session = (audio_session_t)data.readInt32();
            pid_t pid = (pid_t)data.readInt32();
            uid_t uid = (uid_t)data.readInt32();
            const String16 opPackageName = data.readString16();
            audio_config_base_t config;
            memset(&config, 0, sizeof(audio_config_base_t));
            data.read(&config, sizeof(audio_config_base_t));
            audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
            audio_port_handle_t selectedDeviceId = (audio_port_handle_t) data.readInt32();
            audio_port_handle_t portId = (audio_port_handle_t)data.readInt32();
            status_t status = getInputForAttr(&attr, &input, session, pid, uid,
                                              opPackageName, &config,
                                              flags, &selectedDeviceId, &portId);
            reply->writeInt32(status);
            if (status == NO_ERROR) {
                reply->writeInt32(input);
                reply->writeInt32(selectedDeviceId);
                reply->writeInt32(portId);
            }
            return NO_ERROR;
        } break;

        case START_INPUT: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_port_handle_t portId = static_cast <audio_port_handle_t>(data.readInt32());
            bool silenced = data.readInt32() == 1;
            status_t status = startInput(portId, &silenced);
            reply->writeInt32(static_cast <uint32_t>(status));
            reply->writeInt32(silenced ? 1 : 0);
            return NO_ERROR;
        } break;

        case STOP_INPUT: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_port_handle_t portId = static_cast <audio_port_handle_t>(data.readInt32());
            reply->writeInt32(static_cast <uint32_t>(stopInput(portId)));
            return NO_ERROR;
        } break;

        case RELEASE_INPUT: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_port_handle_t portId = static_cast <audio_port_handle_t>(data.readInt32());
            releaseInput(portId);
            return NO_ERROR;
        } break;

        case INIT_STREAM_VOLUME: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_stream_type_t stream =
                    static_cast <audio_stream_type_t>(data.readInt32());
            int indexMin = data.readInt32();
            int indexMax = data.readInt32();
            reply->writeInt32(static_cast <uint32_t>(initStreamVolume(stream, indexMin,indexMax)));
            return NO_ERROR;
        } break;

        case SET_STREAM_VOLUME: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_stream_type_t stream =
                    static_cast <audio_stream_type_t>(data.readInt32());
            int index = data.readInt32();
            audio_devices_t device = static_cast <audio_devices_t>(data.readInt32());
            reply->writeInt32(static_cast <uint32_t>(setStreamVolumeIndex(stream,
                                                                          index,
                                                                          device)));
            return NO_ERROR;
        } break;

        case GET_STREAM_VOLUME: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_stream_type_t stream =
                    static_cast <audio_stream_type_t>(data.readInt32());
            audio_devices_t device = static_cast <audio_devices_t>(data.readInt32());
            int index = 0;
            status_t status = getStreamVolumeIndex(stream, &index, device);
            reply->writeInt32(index);
            reply->writeInt32(static_cast <uint32_t>(status));
            return NO_ERROR;
        } break;

        case GET_STRATEGY_FOR_STREAM: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_stream_type_t stream =
                    static_cast <audio_stream_type_t>(data.readInt32());
            reply->writeInt32(getStrategyForStream(stream));
            return NO_ERROR;
        } break;

        case GET_DEVICES_FOR_STREAM: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_stream_type_t stream =
                    static_cast <audio_stream_type_t>(data.readInt32());
            reply->writeInt32(static_cast <int>(getDevicesForStream(stream)));
            return NO_ERROR;
        } break;

        case GET_OUTPUT_FOR_EFFECT: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            effect_descriptor_t desc = {};
            if (data.read(&desc, sizeof(desc)) != NO_ERROR) {
                android_errorWriteLog(0x534e4554, "73126106");
            }
            (void)sanitizeEffectDescriptor(&desc);
            audio_io_handle_t output = getOutputForEffect(&desc);
            reply->writeInt32(static_cast <int>(output));
            return NO_ERROR;
        } break;

        case REGISTER_EFFECT: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            effect_descriptor_t desc = {};
            if (data.read(&desc, sizeof(desc)) != NO_ERROR) {
                android_errorWriteLog(0x534e4554, "73126106");
            }
            (void)sanitizeEffectDescriptor(&desc);
            audio_io_handle_t io = data.readInt32();
            uint32_t strategy = data.readInt32();
            audio_session_t session = (audio_session_t) data.readInt32();
            int id = data.readInt32();
            reply->writeInt32(static_cast <int32_t>(registerEffect(&desc,
                                                                   io,
                                                                   strategy,
                                                                   session,
                                                                   id)));
            return NO_ERROR;
        } break;

        case UNREGISTER_EFFECT: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            int id = data.readInt32();
            reply->writeInt32(static_cast <int32_t>(unregisterEffect(id)));
            return NO_ERROR;
        } break;

        case SET_EFFECT_ENABLED: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            int id = data.readInt32();
            bool enabled = static_cast <bool>(data.readInt32());
            reply->writeInt32(static_cast <int32_t>(setEffectEnabled(id, enabled)));
            return NO_ERROR;
        } break;

        case IS_STREAM_ACTIVE: {
            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(stream, inPastMs) );
            return NO_ERROR;
        } break;

        case IS_STREAM_ACTIVE_REMOTELY: {
            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(stream, inPastMs) );
            return NO_ERROR;
        } break;

        case IS_SOURCE_ACTIVE: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_source_t source = (audio_source_t) data.readInt32();
            reply->writeInt32( isSourceActive(source));
            return NO_ERROR;
        }

        case QUERY_DEFAULT_PRE_PROCESSING: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_session_t audioSession = (audio_session_t) data.readInt32();
            uint32_t count = data.readInt32();
            if (count > AudioEffect::kMaxPreProcessing) {
                count = AudioEffect::kMaxPreProcessing;
            }
            uint32_t retCount = count;
            effect_descriptor_t *descriptors = new effect_descriptor_t[count]{};
            status_t status = queryDefaultPreProcessing(audioSession, descriptors, &retCount);
            reply->writeInt32(status);
            if (status != NO_ERROR && status != NO_MEMORY) {
                retCount = 0;
            }
            reply->writeInt32(retCount);
            if (retCount != 0) {
                if (retCount < count) {
                    count = retCount;
                }
                reply->write(descriptors, sizeof(effect_descriptor_t) * count);
            }
            delete[] descriptors;
            return status;
        }

        case IS_OFFLOAD_SUPPORTED: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_offload_info_t info = {};
            data.read(&info, sizeof(audio_offload_info_t));
            bool isSupported = isOffloadSupported(info);
            reply->writeInt32(isSupported);
            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();
            if (numPortsReq > MAX_ITEMS_PER_LIST) {
                numPortsReq = MAX_ITEMS_PER_LIST;
            }
            unsigned int numPorts = numPortsReq;
            struct audio_port *ports =
                    (struct audio_port *)calloc(numPortsReq, sizeof(struct audio_port));
            if (ports == NULL) {
                reply->writeInt32(NO_MEMORY);
                reply->writeInt32(0);
                return NO_ERROR;
            }
            unsigned int generation;
            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 = {};
            if (data.read(&port, sizeof(struct audio_port)) != NO_ERROR) {
                ALOGE("b/23912202");
            }
            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 = AUDIO_PATCH_HANDLE_NONE;
            if (data.read(&handle, sizeof(audio_patch_handle_t)) != NO_ERROR) {
                ALOGE("b/23912202");
            }
            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 = AUDIO_PATCH_HANDLE_NONE;
            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();
            if (numPatchesReq > MAX_ITEMS_PER_LIST) {
                numPatchesReq = MAX_ITEMS_PER_LIST;
            }
            unsigned int numPatches = numPatchesReq;
            struct audio_patch *patches =
                    (struct audio_patch *)calloc(numPatchesReq,
                                                 sizeof(struct audio_patch));
            if (patches == NULL) {
                reply->writeInt32(NO_MEMORY);
                reply->writeInt32(0);
                return NO_ERROR;
            }
            unsigned int generation;
            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));
            (void)sanitizeAudioPortConfig(&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 SET_AUDIO_PORT_CALLBACK_ENABLED: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            setAudioPortCallbacksEnabled(data.readInt32() == 1);
            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_SESSION_NONE;
            audio_io_handle_t ioHandle = AUDIO_IO_HANDLE_NONE;
            audio_devices_t device = AUDIO_DEVICE_NONE;
            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;

        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;

        case START_AUDIO_SOURCE: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            struct audio_port_config source = {};
            data.read(&source, sizeof(struct audio_port_config));
            (void)sanitizeAudioPortConfig(&source);
            audio_attributes_t attributes = {};
            data.read(&attributes, sizeof(audio_attributes_t));
            sanetizeAudioAttributes(&attributes);
            audio_patch_handle_t handle = AUDIO_PATCH_HANDLE_NONE;
            status_t status = startAudioSource(&source, &attributes, &handle);
            reply->writeInt32(status);
            reply->writeInt32(handle);
            return NO_ERROR;
        } break;

        case STOP_AUDIO_SOURCE: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_patch_handle_t handle = (audio_patch_handle_t) data.readInt32();
            status_t status = stopAudioSource(handle);
            reply->writeInt32(status);
            return NO_ERROR;
        } break;

        case SET_MASTER_MONO: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            bool mono = static_cast<bool>(data.readInt32());
            status_t status = setMasterMono(mono);
            reply->writeInt32(status);
            return NO_ERROR;
        } break;

        case GET_MASTER_MONO: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            bool mono;
            status_t status = getMasterMono(&mono);
            reply->writeInt32(status);
            if (status == NO_ERROR) {
                reply->writeInt32(static_cast<int32_t>(mono));
            }
            return NO_ERROR;
        } break;

        case GET_STREAM_VOLUME_DB: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_stream_type_t stream =
                    static_cast <audio_stream_type_t>(data.readInt32());
            int index = static_cast <int>(data.readInt32());
            audio_devices_t device =
                    static_cast <audio_devices_t>(data.readUint32());
            reply->writeFloat(getStreamVolumeDB(stream, index, device));
            return NO_ERROR;
        }

        case GET_SURROUND_FORMATS: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            unsigned int numSurroundFormatsReq = data.readUint32();
            if (numSurroundFormatsReq > MAX_ITEMS_PER_LIST) {
                numSurroundFormatsReq = MAX_ITEMS_PER_LIST;
            }
            bool reported = data.readBool();
            unsigned int numSurroundFormats = numSurroundFormatsReq;
            audio_format_t *surroundFormats = (audio_format_t *)calloc(
                    numSurroundFormats, sizeof(audio_format_t));
            bool *surroundFormatsEnabled = (bool *)calloc(numSurroundFormats, sizeof(bool));
            if (numSurroundFormatsReq > 0 &&
                    (surroundFormats == NULL || surroundFormatsEnabled == NULL)) {
                free(surroundFormats);
                free(surroundFormatsEnabled);
                reply->writeInt32(NO_MEMORY);
                return NO_ERROR;
            }
            status_t status = getSurroundFormats(
                    &numSurroundFormats, surroundFormats, surroundFormatsEnabled, reported);
            reply->writeInt32(status);

            if (status == NO_ERROR) {
                reply->writeUint32(numSurroundFormats);
                if (numSurroundFormatsReq > numSurroundFormats) {
                    numSurroundFormatsReq = numSurroundFormats;
                }
                reply->write(surroundFormats, numSurroundFormatsReq * sizeof(audio_format_t));
                reply->write(surroundFormatsEnabled, numSurroundFormatsReq * sizeof(bool));
            }
            free(surroundFormats);
            free(surroundFormatsEnabled);
            return NO_ERROR;
        }

        case SET_SURROUND_FORMAT_ENABLED: {
            CHECK_INTERFACE(IAudioPolicyService, data, reply);
            audio_format_t audioFormat = (audio_format_t) data.readInt32();
            bool enabled = data.readBool();
            status_t status = setSurroundFormatEnabled(audioFormat, enabled);
            reply->writeInt32(status);
            return NO_ERROR;
        }

        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}

/** returns true if string overflow was prevented by zero termination */
template <size_t size>
static bool preventStringOverflow(char (&s)[size]) {
    if (strnlen(s, size) < size) return false;
    s[size - 1] = '\0';
    return true;
}

void BnAudioPolicyService::sanetizeAudioAttributes(audio_attributes_t* attr)
{
    const size_t tagsMaxSize = AUDIO_ATTRIBUTES_TAGS_MAX_SIZE;
    if (strnlen(attr->tags, tagsMaxSize) >= tagsMaxSize) {
        android_errorWriteLog(0x534e4554, "68953950"); // SafetyNet logging
    }
    attr->tags[tagsMaxSize - 1] = '\0';
}

/** returns BAD_VALUE if sanitization was required. */
status_t BnAudioPolicyService::sanitizeEffectDescriptor(effect_descriptor_t* desc)
{
    if (preventStringOverflow(desc->name)
        | /* always */ preventStringOverflow(desc->implementor)) {
        android_errorWriteLog(0x534e4554, "73126106"); // SafetyNet logging
        return BAD_VALUE;
    }
    return NO_ERROR;
}

/** returns BAD_VALUE if sanitization was required. */
status_t BnAudioPolicyService::sanitizeAudioPortConfig(struct audio_port_config* config)
{
    if (config->type == AUDIO_PORT_TYPE_DEVICE &&
        preventStringOverflow(config->ext.device.address)) {
        return BAD_VALUE;
    }
    return NO_ERROR;
}

// ----------------------------------------------------------------------------

} // namespace android
