/* ** ** 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 <sys/types.h> #include <binder/Parcel.h> #include <media/IAudioPolicyService.h> namespace android { enum { SET_DEVICE_CONNECTION_STATE = IBinder::FIRST_CALL_TRANSACTION, GET_DEVICE_CONNECTION_STATE, SET_PHONE_STATE, SET_RINGER_MODE, SET_FORCE_USE, GET_FORCE_USE, GET_OUTPUT, START_OUTPUT, STOP_OUTPUT, RELEASE_OUTPUT, GET_INPUT, 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 }; class BpAudioPolicyService : public BpInterface<IAudioPolicyService> { public: BpAudioPolicyService(const sp<IBinder>& impl) : BpInterface<IAudioPolicyService>(impl) { } virtual status_t setDeviceConnectionState( AudioSystem::audio_devices device, AudioSystem::device_connection_state state, const char *device_address) { 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); remote()->transact(SET_DEVICE_CONNECTION_STATE, data, &reply); return static_cast <status_t> (reply.readInt32()); } virtual AudioSystem::device_connection_state getDeviceConnectionState( AudioSystem::audio_devices 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 <AudioSystem::device_connection_state>(reply.readInt32()); } virtual status_t setPhoneState(int 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 setRingerMode(uint32_t mode, uint32_t mask) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(mode); data.writeInt32(mask); remote()->transact(SET_RINGER_MODE, data, &reply); return static_cast <status_t> (reply.readInt32()); } virtual status_t setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config 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 AudioSystem::forced_config getForceUse(AudioSystem::force_use 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 <AudioSystem::forced_config> (reply.readInt32()); } virtual audio_io_handle_t getOutput( AudioSystem::stream_type stream, uint32_t samplingRate, uint32_t format, uint32_t channels, AudioSystem::output_flags flags) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(static_cast <uint32_t>(stream)); data.writeInt32(samplingRate); data.writeInt32(static_cast <uint32_t>(format)); data.writeInt32(channels); data.writeInt32(static_cast <uint32_t>(flags)); remote()->transact(GET_OUTPUT, data, &reply); return static_cast <audio_io_handle_t> (reply.readInt32()); } virtual status_t startOutput(audio_io_handle_t output, AudioSystem::stream_type stream, int session) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(output); data.writeInt32(stream); data.writeInt32(session); remote()->transact(START_OUTPUT, data, &reply); return static_cast <status_t> (reply.readInt32()); } virtual status_t stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream, int session) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(output); data.writeInt32(stream); data.writeInt32(session); remote()->transact(STOP_OUTPUT, data, &reply); return static_cast <status_t> (reply.readInt32()); } virtual void releaseOutput(audio_io_handle_t output) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(output); remote()->transact(RELEASE_OUTPUT, data, &reply); } virtual audio_io_handle_t getInput( int inputSource, uint32_t samplingRate, uint32_t format, uint32_t channels, AudioSystem::audio_in_acoustics acoustics) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(inputSource); data.writeInt32(samplingRate); data.writeInt32(static_cast <uint32_t>(format)); data.writeInt32(channels); data.writeInt32(static_cast <uint32_t>(acoustics)); remote()->transact(GET_INPUT, data, &reply); return static_cast <audio_io_handle_t> (reply.readInt32()); } virtual status_t startInput(audio_io_handle_t input) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(input); remote()->transact(START_INPUT, data, &reply); return static_cast <status_t> (reply.readInt32()); } virtual status_t stopInput(audio_io_handle_t input) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(input); remote()->transact(STOP_INPUT, data, &reply); return static_cast <status_t> (reply.readInt32()); } virtual void releaseInput(audio_io_handle_t input) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(input); remote()->transact(RELEASE_INPUT, data, &reply); } virtual status_t initStreamVolume(AudioSystem::stream_type 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(AudioSystem::stream_type stream, int index) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(static_cast <uint32_t>(stream)); data.writeInt32(index); remote()->transact(SET_STREAM_VOLUME, data, &reply); return static_cast <status_t> (reply.readInt32()); } virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int *index) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.writeInt32(static_cast <uint32_t>(stream)); 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(AudioSystem::stream_type 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_io_handle_t getOutputForEffect(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(effect_descriptor_t *desc, audio_io_handle_t output, uint32_t strategy, int session, int id) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.write(desc, sizeof(effect_descriptor_t)); data.writeInt32(output); 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()); } }; IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService"); // ---------------------------------------------------------------------- status_t BnAudioPolicyService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case SET_DEVICE_CONNECTION_STATE: { CHECK_INTERFACE(IAudioPolicyService, data, reply); AudioSystem::audio_devices device = static_cast <AudioSystem::audio_devices>(data.readInt32()); AudioSystem::device_connection_state state = static_cast <AudioSystem::device_connection_state>(data.readInt32()); const char *device_address = data.readCString(); reply->writeInt32(static_cast<uint32_t> (setDeviceConnectionState(device, state, device_address))); return NO_ERROR; } break; case GET_DEVICE_CONNECTION_STATE: { CHECK_INTERFACE(IAudioPolicyService, data, reply); AudioSystem::audio_devices device = static_cast<AudioSystem::audio_devices> (data.readInt32()); const char *device_address = data.readCString(); reply->writeInt32(static_cast<uint32_t> (getDeviceConnectionState(device, device_address))); return NO_ERROR; } break; case SET_PHONE_STATE: { CHECK_INTERFACE(IAudioPolicyService, data, reply); reply->writeInt32(static_cast <uint32_t>(setPhoneState(data.readInt32()))); return NO_ERROR; } break; case SET_RINGER_MODE: { CHECK_INTERFACE(IAudioPolicyService, data, reply); uint32_t mode = data.readInt32(); uint32_t mask = data.readInt32(); reply->writeInt32(static_cast <uint32_t>(setRingerMode(mode, mask))); return NO_ERROR; } break; case SET_FORCE_USE: { CHECK_INTERFACE(IAudioPolicyService, data, reply); AudioSystem::force_use usage = static_cast <AudioSystem::force_use>(data.readInt32()); AudioSystem::forced_config config = static_cast <AudioSystem::forced_config>(data.readInt32()); reply->writeInt32(static_cast <uint32_t>(setForceUse(usage, config))); return NO_ERROR; } break; case GET_FORCE_USE: { CHECK_INTERFACE(IAudioPolicyService, data, reply); AudioSystem::force_use usage = static_cast <AudioSystem::force_use>(data.readInt32()); reply->writeInt32(static_cast <uint32_t>(getForceUse(usage))); return NO_ERROR; } break; case GET_OUTPUT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); AudioSystem::stream_type stream = static_cast <AudioSystem::stream_type>(data.readInt32()); uint32_t samplingRate = data.readInt32(); uint32_t format = data.readInt32(); uint32_t channels = data.readInt32(); AudioSystem::output_flags flags = static_cast <AudioSystem::output_flags>(data.readInt32()); audio_io_handle_t output = getOutput(stream, samplingRate, format, channels, flags); reply->writeInt32(static_cast <int>(output)); return NO_ERROR; } break; case START_OUTPUT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32()); uint32_t stream = data.readInt32(); int session = data.readInt32(); reply->writeInt32(static_cast <uint32_t>(startOutput(output, (AudioSystem::stream_type)stream, session))); return NO_ERROR; } break; case STOP_OUTPUT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32()); uint32_t stream = data.readInt32(); int session = data.readInt32(); reply->writeInt32(static_cast <uint32_t>(stopOutput(output, (AudioSystem::stream_type)stream, session))); return NO_ERROR; } break; case RELEASE_OUTPUT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_io_handle_t output = static_cast <audio_io_handle_t>(data.readInt32()); releaseOutput(output); return NO_ERROR; } break; case GET_INPUT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); int inputSource = data.readInt32(); uint32_t samplingRate = data.readInt32(); uint32_t format = data.readInt32(); uint32_t channels = data.readInt32(); AudioSystem::audio_in_acoustics acoustics = static_cast <AudioSystem::audio_in_acoustics>(data.readInt32()); audio_io_handle_t input = getInput(inputSource, samplingRate, format, channels, acoustics); reply->writeInt32(static_cast <int>(input)); return NO_ERROR; } break; case START_INPUT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_io_handle_t input = static_cast <audio_io_handle_t>(data.readInt32()); reply->writeInt32(static_cast <uint32_t>(startInput(input))); return NO_ERROR; } break; case STOP_INPUT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_io_handle_t input = static_cast <audio_io_handle_t>(data.readInt32()); reply->writeInt32(static_cast <uint32_t>(stopInput(input))); return NO_ERROR; } break; case RELEASE_INPUT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); audio_io_handle_t input = static_cast <audio_io_handle_t>(data.readInt32()); releaseInput(input); return NO_ERROR; } break; case INIT_STREAM_VOLUME: { CHECK_INTERFACE(IAudioPolicyService, data, reply); AudioSystem::stream_type stream = static_cast <AudioSystem::stream_type>(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); AudioSystem::stream_type stream = static_cast <AudioSystem::stream_type>(data.readInt32()); int index = data.readInt32(); reply->writeInt32(static_cast <uint32_t>(setStreamVolumeIndex(stream, index))); return NO_ERROR; } break; case GET_STREAM_VOLUME: { CHECK_INTERFACE(IAudioPolicyService, data, reply); AudioSystem::stream_type stream = static_cast <AudioSystem::stream_type>(data.readInt32()); int index; status_t status = getStreamVolumeIndex(stream, &index); reply->writeInt32(index); reply->writeInt32(static_cast <uint32_t>(status)); return NO_ERROR; } break; case GET_STRATEGY_FOR_STREAM: { CHECK_INTERFACE(IAudioPolicyService, data, reply); AudioSystem::stream_type stream = static_cast <AudioSystem::stream_type>(data.readInt32()); reply->writeInt32(getStrategyForStream(stream)); return NO_ERROR; } break; case GET_OUTPUT_FOR_EFFECT: { CHECK_INTERFACE(IAudioPolicyService, data, reply); effect_descriptor_t desc; data.read(&desc, sizeof(effect_descriptor_t)); 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; data.read(&desc, sizeof(effect_descriptor_t)); audio_io_handle_t output = data.readInt32(); uint32_t strategy = data.readInt32(); int session = data.readInt32(); int id = data.readInt32(); reply->writeInt32(static_cast <int32_t>(registerEffect(&desc, output, 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; default: return BBinder::onTransact(code, data, reply, flags); } } // ---------------------------------------------------------------------------- }; // namespace android