/* ** ** 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, SET_VOLUME_ATTRIBUTES, GET_VOLUME_ATTRIBUTES, GET_MIN_VOLUME_FOR_ATTRIBUTES, GET_MAX_VOLUME_FOR_ATTRIBUTES, 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, IS_DIRECT_OUTPUT_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_AUDIO_VOLUME_GROUP_CALLBACK_ENABLED, SET_MASTER_MONO, GET_MASTER_MONO, GET_STREAM_VOLUME_DB, GET_SURROUND_FORMATS, SET_SURROUND_FORMAT_ENABLED, ADD_STREAM_DEFAULT_EFFECT, REMOVE_STREAM_DEFAULT_EFFECT, ADD_SOURCE_DEFAULT_EFFECT, REMOVE_SOURCE_DEFAULT_EFFECT, SET_ASSISTANT_UID, SET_A11Y_SERVICES_UIDS, IS_HAPTIC_PLAYBACK_SUPPORTED, SET_UID_DEVICE_AFFINITY, REMOVE_UID_DEVICE_AFFINITY, GET_OFFLOAD_FORMATS_A2DP, LIST_AUDIO_PRODUCT_STRATEGIES, GET_STRATEGY_FOR_ATTRIBUTES, LIST_AUDIO_VOLUME_GROUPS, GET_VOLUME_GROUP_FOR_ATTRIBUTES, SET_ALLOWED_CAPTURE_POLICY, MOVE_EFFECTS_TO_IO, SET_RTT_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, audio_format_t encodedFormat) { 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); data.writeInt32(static_cast <uint32_t>(encodedFormat)); 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, audio_format_t encodedFormat) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(static_cast <uint32_t>(device)); data.writeCString(device_address); data.writeCString(device_name); data.writeInt32(static_cast <uint32_t>(encodedFormat)); 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()); } status_t getOutputForAttr(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, std::vector<audio_io_handle_t> *secondaryOutputs) override { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); if (attr == nullptr) { ALOGE("%s NULL audio attributes", __func__); return BAD_VALUE; } if (output == nullptr) { ALOGE("%s NULL output - shouldn't happen", __func__); return BAD_VALUE; } if (selectedDeviceId == nullptr) { ALOGE("%s NULL selectedDeviceId - shouldn't happen", __func__); return BAD_VALUE; } if (portId == nullptr) { ALOGE("%s NULL portId - shouldn't happen", __func__); return BAD_VALUE; } if (secondaryOutputs == nullptr) { ALOGE("%s NULL secondaryOutputs - shouldn't happen", __func__); return BAD_VALUE; } 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; } status = (status_t)reply.read(&attr, sizeof(audio_attributes_t)); 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(); secondaryOutputs->resize(reply.readInt32()); return reply.read(secondaryOutputs->data(), secondaryOutputs->size() * sizeof(audio_io_handle_t)); } 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_unique_id_t riid, 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(riid); 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) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(portId); remote()->transact(START_INPUT, data, &reply); status_t status = static_cast <status_t> (reply.readInt32()); 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 status_t setVolumeIndexForAttributes(const audio_attributes_t &attr, int index, audio_devices_t device) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.write(&attr, sizeof(audio_attributes_t)); data.writeInt32(index); data.writeInt32(static_cast <uint32_t>(device)); status_t status = remote()->transact(SET_VOLUME_ATTRIBUTES, data, &reply); if (status != NO_ERROR) { return status; } return static_cast <status_t> (reply.readInt32()); } virtual status_t getVolumeIndexForAttributes(const audio_attributes_t &attr, int &index, audio_devices_t device) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.write(&attr, sizeof(audio_attributes_t)); data.writeInt32(static_cast <uint32_t>(device)); status_t status = remote()->transact(GET_VOLUME_ATTRIBUTES, data, &reply); if (status != NO_ERROR) { return status; } status = static_cast <status_t> (reply.readInt32()); if (status != NO_ERROR) { return status; } index = reply.readInt32(); return NO_ERROR; } virtual status_t getMinVolumeIndexForAttributes(const audio_attributes_t &attr, int &index) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.write(&attr, sizeof(audio_attributes_t)); status_t status = remote()->transact(GET_MIN_VOLUME_FOR_ATTRIBUTES, data, &reply); if (status != NO_ERROR) { return status; } status = static_cast <status_t> (reply.readInt32()); if (status != NO_ERROR) { return status; } index = reply.readInt32(); return NO_ERROR; } virtual status_t getMaxVolumeIndexForAttributes(const audio_attributes_t &attr, int &index) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.write(&attr, sizeof(audio_attributes_t)); status_t status = remote()->transact(GET_MAX_VOLUME_FOR_ATTRIBUTES, data, &reply); if (status != NO_ERROR) { return status; } status = static_cast <status_t> (reply.readInt32()); if (status != NO_ERROR) { return status; } index = reply.readInt32(); return NO_ERROR; } 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.readUint32(); } 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()); } status_t moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io) override { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(ids.size()); for (auto id : ids) { data.writeInt32(id); } data.writeInt32(io); status_t status = remote()->transact(MOVE_EFFECTS_TO_IO, data, &reply); if (status != NO_ERROR) { return status; } 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; } status_t setAllowedCapturePolicy(uid_t uid, audio_flags_mask_t flags) override { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(uid); data.writeInt32(flags); remote()->transact(SET_ALLOWED_CAPTURE_POLICY, data, &reply); return reply.readInt32(); } 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 bool isDirectOutputSupported(const audio_config_base_t& config, const audio_attributes_t& attributes) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.write(&config, sizeof(audio_config_base_t)); data.write(&attributes, sizeof(audio_attributes_t)); status_t status = remote()->transact(IS_DIRECT_OUTPUT_SUPPORTED, data, &reply); return status == NO_ERROR ? static_cast<bool>(reply.readInt32()) : false; } 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 void setAudioVolumeGroupCallbacksEnabled(bool enabled) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(enabled ? 1 : 0); remote()->transact(SET_AUDIO_VOLUME_GROUP_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_port_handle_t *portId) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); if (source == NULL || attributes == NULL || portId == 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; } *portId = (audio_port_handle_t)reply.readInt32(); return status; } virtual status_t stopAudioSource(audio_port_handle_t portId) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(portId); 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(); } virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP( std::vector<audio_format_t> *formats) { if (formats == NULL) { return BAD_VALUE; } Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); status_t status = remote()->transact(GET_OFFLOAD_FORMATS_A2DP, data, &reply); if (status != NO_ERROR || (status = (status_t)reply.readInt32()) != NO_ERROR) { return status; } size_t list_size = reply.readUint32(); for (size_t i = 0; i < list_size; i++) { formats->push_back(static_cast<audio_format_t>(reply.readInt32())); } return NO_ERROR; } virtual status_t addStreamDefaultEffect(const effect_uuid_t *type, const String16& opPackageName, const effect_uuid_t *uuid, int32_t priority, audio_usage_t usage, audio_unique_id_t* id) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.write(type, sizeof(effect_uuid_t)); data.writeString16(opPackageName); data.write(uuid, sizeof(effect_uuid_t)); data.writeInt32(priority); data.writeInt32((int32_t) usage); status_t status = remote()->transact(ADD_STREAM_DEFAULT_EFFECT, data, &reply); if (status != NO_ERROR) { return status; } status = static_cast <status_t> (reply.readInt32()); *id = reply.readInt32(); return status; } virtual status_t removeStreamDefaultEffect(audio_unique_id_t id) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(id); status_t status = remote()->transact(REMOVE_STREAM_DEFAULT_EFFECT, data, &reply); if (status != NO_ERROR) { return status; } return static_cast <status_t> (reply.readInt32()); } virtual status_t addSourceDefaultEffect(const effect_uuid_t *type, const String16& opPackageName, const effect_uuid_t *uuid, int32_t priority, audio_source_t source, audio_unique_id_t* id) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.write(type, sizeof(effect_uuid_t)); data.writeString16(opPackageName); data.write(uuid, sizeof(effect_uuid_t)); data.writeInt32(priority); data.writeInt32((int32_t) source); status_t status = remote()->transact(ADD_SOURCE_DEFAULT_EFFECT, data, &reply); if (status != NO_ERROR) { return status; } status = static_cast <status_t> (reply.readInt32()); *id = reply.readInt32(); return status; } virtual status_t removeSourceDefaultEffect(audio_unique_id_t id) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(id); status_t status = remote()->transact(REMOVE_SOURCE_DEFAULT_EFFECT, data, &reply); if (status != NO_ERROR) { return status; } return static_cast <status_t> (reply.readInt32()); } virtual status_t setAssistantUid(uid_t uid) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(uid); status_t status = remote()->transact(SET_ASSISTANT_UID, data, &reply); if (status != NO_ERROR) { return status; } return static_cast <status_t> (reply.readInt32()); } virtual status_t setA11yServicesUids(const std::vector<uid_t>& uids) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(uids.size()); for (auto uid : uids) { data.writeInt32(uid); } status_t status = remote()->transact(SET_A11Y_SERVICES_UIDS, data, &reply); if (status != NO_ERROR) { return status; } return static_cast <status_t> (reply.readInt32()); } virtual bool isHapticPlaybackSupported() { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); status_t status = remote()->transact(IS_HAPTIC_PLAYBACK_SUPPORTED, data, &reply); if (status != NO_ERROR) { return false; } return reply.readBool(); } virtual status_t setUidDeviceAffinities(uid_t uid, const Vector<AudioDeviceTypeAddr>& devices) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32((int32_t) uid); size_t size = devices.size(); size_t sizePosition = data.dataPosition(); data.writeInt32((int32_t) size); size_t finalSize = size; for (size_t i = 0; i < size; i++) { size_t position = data.dataPosition(); if (devices[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(SET_UID_DEVICE_AFFINITY, data, &reply); if (status == NO_ERROR) { status = (status_t)reply.readInt32(); } return status; } virtual status_t removeUidDeviceAffinities(uid_t uid) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32((int32_t) uid); status_t status = remote()->transact(REMOVE_UID_DEVICE_AFFINITY, data, &reply); if (status == NO_ERROR) { status = (status_t) reply.readInt32(); } return status; } virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); status_t status = remote()->transact(LIST_AUDIO_PRODUCT_STRATEGIES, data, &reply); if (status != NO_ERROR) { ALOGE("%s: permission denied", __func__); return status; } status = static_cast<status_t>(reply.readInt32()); if (status != NO_ERROR) { return status; } uint32_t numStrategies = static_cast<uint32_t>(reply.readInt32()); for (size_t i = 0; i < numStrategies; i++) { AudioProductStrategy strategy; status = strategy.readFromParcel(&reply); if (status != NO_ERROR) { ALOGE("%s: failed to read strategies", __FUNCTION__); strategies.clear(); return status; } strategies.push_back(strategy); } return NO_ERROR; } virtual status_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa, product_strategy_t &productStrategy) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); status_t status = aa.writeToParcel(&data); if (status != NO_ERROR) { return status; } status = remote()->transact(GET_STRATEGY_FOR_ATTRIBUTES, data, &reply); if (status != NO_ERROR) { return status; } status = static_cast<status_t>(reply.readInt32()); if (status != NO_ERROR) { return status; } productStrategy = static_cast<product_strategy_t>(reply.readInt32()); return NO_ERROR; } virtual status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); status_t status = remote()->transact(LIST_AUDIO_VOLUME_GROUPS, data, &reply); if (status != NO_ERROR) { return status; } status = static_cast<status_t>(reply.readInt32()); if (status != NO_ERROR) { return status; } uint32_t numGroups = static_cast<uint32_t>(reply.readInt32()); for (size_t i = 0; i < numGroups; i++) { AudioVolumeGroup group; status = group.readFromParcel(&reply); if (status != NO_ERROR) { ALOGE("%s: failed to read volume groups", __FUNCTION__); groups.clear(); return status; } groups.push_back(group); } return NO_ERROR; } virtual status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa, volume_group_t &volumeGroup) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); status_t status = aa.writeToParcel(&data); if (status != NO_ERROR) { return status; } status = remote()->transact(GET_VOLUME_GROUP_FOR_ATTRIBUTES, data, &reply); if (status != NO_ERROR) { return status; } status = static_cast<status_t>(reply.readInt32()); if (status != NO_ERROR) { return status; } volumeGroup = static_cast<volume_group_t>(reply.readInt32()); return NO_ERROR; } virtual status_t setRttEnabled(bool enabled) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(static_cast<int32_t>(enabled)); status_t status = remote()->transact(SET_RTT_ENABLED, data, &reply); if (status != NO_ERROR) { return status; } return static_cast<status_t>(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_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: case MOVE_EFFECTS_TO_IO: 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 GET_SURROUND_FORMATS: case SET_SURROUND_FORMAT_ENABLED: case SET_ASSISTANT_UID: case SET_A11Y_SERVICES_UIDS: case SET_UID_DEVICE_AFFINITY: case REMOVE_UID_DEVICE_AFFINITY: case GET_OFFLOAD_FORMATS_A2DP: case LIST_AUDIO_VOLUME_GROUPS: case GET_VOLUME_GROUP_FOR_ATTRIBUTES: case SET_RTT_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; } std::string tag("IAudioPolicyService command " + std::to_string(code)); TimeCheck check(tag.c_str()); 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(); audio_format_t codecFormat = static_cast <audio_format_t>(data.readInt32()); 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, codecFormat))); } 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(); audio_format_t codecFormat = static_cast <audio_format_t>(data.readInt32()); 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, codecFormat))); } 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 = AUDIO_ATTRIBUTES_INITIALIZER; status_t status = data.read(&attr, sizeof(audio_attributes_t)); if (status != NO_ERROR) { return status; } 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; std::vector<audio_io_handle_t> secondaryOutputs; status = getOutputForAttr(&attr, &output, session, &stream, pid, uid, &config, flags, &selectedDeviceId, &portId, &secondaryOutputs); reply->writeInt32(status); status = reply->write(&attr, sizeof(audio_attributes_t)); if (status != NO_ERROR) { return status; } reply->writeInt32(output); reply->writeInt32(stream); reply->writeInt32(selectedDeviceId); reply->writeInt32(portId); reply->writeInt32(secondaryOutputs.size()); return reply->write(secondaryOutputs.data(), secondaryOutputs.size() * sizeof(audio_io_handle_t)); } 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_unique_id_t riid = (audio_unique_id_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, riid, 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()); status_t status = startInput(portId); reply->writeInt32(static_cast <uint32_t>(status)); 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->writeUint32(getStrategyForStream(stream)); return NO_ERROR; } break; case SET_VOLUME_ATTRIBUTES: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_attributes_t attributes = {}; status_t status = data.read(&attributes, sizeof(audio_attributes_t)); if (status != NO_ERROR) { return status; } int index = data.readInt32(); audio_devices_t device = static_cast <audio_devices_t>(data.readInt32()); reply->writeInt32(static_cast <uint32_t>(setVolumeIndexForAttributes(attributes, index, device))); return NO_ERROR; } break; case GET_VOLUME_ATTRIBUTES: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_attributes_t attributes = {}; status_t status = data.read(&attributes, sizeof(audio_attributes_t)); if (status != NO_ERROR) { return status; } audio_devices_t device = static_cast <audio_devices_t>(data.readInt32()); int index = 0; status = getVolumeIndexForAttributes(attributes, index, device); reply->writeInt32(static_cast <uint32_t>(status)); if (status == NO_ERROR) { reply->writeInt32(index); } return NO_ERROR; } break; case GET_MIN_VOLUME_FOR_ATTRIBUTES: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_attributes_t attributes = {}; status_t status = data.read(&attributes, sizeof(audio_attributes_t)); if (status != NO_ERROR) { return status; } int index = 0; status = getMinVolumeIndexForAttributes(attributes, index); reply->writeInt32(static_cast <uint32_t>(status)); if (status == NO_ERROR) { reply->writeInt32(index); } return NO_ERROR; } break; case GET_MAX_VOLUME_FOR_ATTRIBUTES: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_attributes_t attributes = {}; status_t status = data.read(&attributes, sizeof(audio_attributes_t)); if (status != NO_ERROR) { return status; } int index = 0; status = getMaxVolumeIndexForAttributes(attributes, index); reply->writeInt32(static_cast <uint32_t>(status)); if (status == NO_ERROR) { reply->writeInt32(index); } 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 MOVE_EFFECTS_TO_IO: { CHECK_INTERFACE(IAudioPolicyService, data, reply); std::vector<int> ids; int32_t size; status_t status = data.readInt32(&size); if (status != NO_ERROR) { return status; } if (size > MAX_ITEMS_PER_LIST) { return BAD_VALUE; } for (int32_t i = 0; i < size; i++) { int id; status = data.readInt32(&id); if (status != NO_ERROR) { return status; } ids.push_back(id); } audio_io_handle_t io = data.readInt32(); reply->writeInt32(static_cast <int32_t>(moveEffectsToIo(ids, io))); 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 IS_DIRECT_OUTPUT_SUPPORTED: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_config_base_t config = {}; audio_attributes_t attributes = {}; status_t status = data.read(&config, sizeof(audio_config_base_t)); if (status != NO_ERROR) return status; status = data.read(&attributes, sizeof(audio_attributes_t)); if (status != NO_ERROR) return status; reply->writeInt32(isDirectOutputSupported(config, attributes)); 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 SET_AUDIO_VOLUME_GROUP_CALLBACK_ENABLED: { CHECK_INTERFACE(IAudioPolicyService, data, reply); setAudioVolumeGroupCallbacksEnabled(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_port_handle_t portId = AUDIO_PORT_HANDLE_NONE; status_t status = startAudioSource(&source, &attributes, &portId); reply->writeInt32(status); reply->writeInt32(portId); return NO_ERROR; } break; case STOP_AUDIO_SOURCE: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_port_handle_t portId = (audio_port_handle_t) data.readInt32(); status_t status = stopAudioSource(portId); 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; } case GET_OFFLOAD_FORMATS_A2DP: { CHECK_INTERFACE(IAudioPolicyService, data, reply); std::vector<audio_format_t> encodingFormats; status_t status = getHwOffloadEncodingFormatsSupportedForA2DP(&encodingFormats); reply->writeInt32(status); if (status != NO_ERROR) { return NO_ERROR; } reply->writeUint32(static_cast<uint32_t>(encodingFormats.size())); for (size_t i = 0; i < encodingFormats.size(); i++) reply->writeInt32(static_cast<int32_t>(encodingFormats[i])); return NO_ERROR; } case ADD_STREAM_DEFAULT_EFFECT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); effect_uuid_t type; status_t status = data.read(&type, sizeof(effect_uuid_t)); if (status != NO_ERROR) { return status; } String16 opPackageName; status = data.readString16(&opPackageName); if (status != NO_ERROR) { return status; } effect_uuid_t uuid; status = data.read(&uuid, sizeof(effect_uuid_t)); if (status != NO_ERROR) { return status; } int32_t priority = data.readInt32(); audio_usage_t usage = (audio_usage_t) data.readInt32(); audio_unique_id_t id = 0; reply->writeInt32(static_cast <int32_t>(addStreamDefaultEffect(&type, opPackageName, &uuid, priority, usage, &id))); reply->writeInt32(id); return NO_ERROR; } case REMOVE_STREAM_DEFAULT_EFFECT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_unique_id_t id = static_cast<audio_unique_id_t>(data.readInt32()); reply->writeInt32(static_cast <int32_t>(removeStreamDefaultEffect(id))); return NO_ERROR; } case ADD_SOURCE_DEFAULT_EFFECT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); effect_uuid_t type; status_t status = data.read(&type, sizeof(effect_uuid_t)); if (status != NO_ERROR) { return status; } String16 opPackageName; status = data.readString16(&opPackageName); if (status != NO_ERROR) { return status; } effect_uuid_t uuid; status = data.read(&uuid, sizeof(effect_uuid_t)); if (status != NO_ERROR) { return status; } int32_t priority = data.readInt32(); audio_source_t source = (audio_source_t) data.readInt32(); audio_unique_id_t id = 0; reply->writeInt32(static_cast <int32_t>(addSourceDefaultEffect(&type, opPackageName, &uuid, priority, source, &id))); reply->writeInt32(id); return NO_ERROR; } case REMOVE_SOURCE_DEFAULT_EFFECT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_unique_id_t id = static_cast<audio_unique_id_t>(data.readInt32()); reply->writeInt32(static_cast <int32_t>(removeSourceDefaultEffect(id))); return NO_ERROR; } case SET_ASSISTANT_UID: { CHECK_INTERFACE(IAudioPolicyService, data, reply); int32_t uid; status_t status = data.readInt32(&uid); if (status != NO_ERROR) { return status; } status = setAssistantUid(uid); reply->writeInt32(static_cast <int32_t>(status)); return NO_ERROR; } case SET_A11Y_SERVICES_UIDS: { CHECK_INTERFACE(IAudioPolicyService, data, reply); std::vector<uid_t> uids; int32_t size; status_t status = data.readInt32(&size); if (status != NO_ERROR) { return status; } if (size > MAX_ITEMS_PER_LIST) { size = MAX_ITEMS_PER_LIST; } for (int32_t i = 0; i < size; i++) { int32_t uid; status = data.readInt32(&uid); if (status != NO_ERROR) { return status; } uids.push_back(uid); } status = setA11yServicesUids(uids); reply->writeInt32(static_cast <int32_t>(status)); return NO_ERROR; } case IS_HAPTIC_PLAYBACK_SUPPORTED: { CHECK_INTERFACE(IAudioPolicyService, data, reply); bool isSupported = isHapticPlaybackSupported(); reply->writeBool(isSupported); return NO_ERROR; } case SET_UID_DEVICE_AFFINITY: { CHECK_INTERFACE(IAudioPolicyService, data, reply); const uid_t uid = (uid_t) data.readInt32(); Vector<AudioDeviceTypeAddr> devices; size_t size = (size_t)data.readInt32(); for (size_t i = 0; i < size; i++) { AudioDeviceTypeAddr device; if (device.readFromParcel((Parcel*)&data) == NO_ERROR) { devices.add(device); } } status_t status = setUidDeviceAffinities(uid, devices); reply->writeInt32(status); return NO_ERROR; } case REMOVE_UID_DEVICE_AFFINITY: { CHECK_INTERFACE(IAudioPolicyService, data, reply); const uid_t uid = (uid_t) data.readInt32(); status_t status = removeUidDeviceAffinities(uid); reply->writeInt32(status); return NO_ERROR; } case LIST_AUDIO_PRODUCT_STRATEGIES: { CHECK_INTERFACE(IAudioPolicyService, data, reply); AudioProductStrategyVector strategies; status_t status = listAudioProductStrategies(strategies); reply->writeInt32(status); if (status != NO_ERROR) { return NO_ERROR; } size_t size = strategies.size(); size_t sizePosition = reply->dataPosition(); reply->writeInt32(size); size_t finalSize = size; for (size_t i = 0; i < size; i++) { size_t position = reply->dataPosition(); if (strategies[i].writeToParcel(reply) != NO_ERROR) { reply->setDataPosition(position); finalSize--; } } if (size != finalSize) { size_t position = reply->dataPosition(); reply->setDataPosition(sizePosition); reply->writeInt32(finalSize); reply->setDataPosition(position); } return NO_ERROR; } case GET_STRATEGY_FOR_ATTRIBUTES: { CHECK_INTERFACE(IAudioPolicyService, data, reply); AudioAttributes attributes; status_t status = attributes.readFromParcel(&data); if (status != NO_ERROR) { return status; } product_strategy_t strategy; status = getProductStrategyFromAudioAttributes(attributes, strategy); reply->writeInt32(status); if (status != NO_ERROR) { return NO_ERROR; } reply->writeUint32(static_cast<int>(strategy)); return NO_ERROR; } case LIST_AUDIO_VOLUME_GROUPS: { CHECK_INTERFACE(IAudioPolicyService, data, reply); AudioVolumeGroupVector groups; status_t status = listAudioVolumeGroups(groups); reply->writeInt32(status); if (status != NO_ERROR) { return NO_ERROR; } size_t size = groups.size(); size_t sizePosition = reply->dataPosition(); reply->writeInt32(size); size_t finalSize = size; for (size_t i = 0; i < size; i++) { size_t position = reply->dataPosition(); if (groups[i].writeToParcel(reply) != NO_ERROR) { reply->setDataPosition(position); finalSize--; } } if (size != finalSize) { size_t position = reply->dataPosition(); reply->setDataPosition(sizePosition); reply->writeInt32(finalSize); reply->setDataPosition(position); } return NO_ERROR; } case GET_VOLUME_GROUP_FOR_ATTRIBUTES: { CHECK_INTERFACE(IAudioPolicyService, data, reply); AudioAttributes attributes; status_t status = attributes.readFromParcel(&data); if (status != NO_ERROR) { return status; } volume_group_t group; status = getVolumeGroupFromAudioAttributes(attributes, group); reply->writeInt32(status); if (status != NO_ERROR) { return NO_ERROR; } reply->writeUint32(static_cast<int>(group)); return NO_ERROR; } case SET_ALLOWED_CAPTURE_POLICY: { CHECK_INTERFACE(IAudioPolicyService, data, reply); uid_t uid = data.readInt32(); audio_flags_mask_t flags = data.readInt32(); status_t status = setAllowedCapturePolicy(uid, flags); reply->writeInt32(status); return NO_ERROR; } case SET_RTT_ENABLED: { CHECK_INTERFACE(IAudioPolicyService, data, reply); bool enabled = static_cast<bool>(data.readInt32()); status_t status = setRttEnabled(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