diff options
author | Eric Laurent <elaurent@google.com> | 2009-07-17 12:17:14 -0700 |
---|---|---|
committer | Eric Laurent <elaurent@google.com> | 2009-07-23 06:03:39 -0700 |
commit | c2f1f07084818942352c6bbfb36af9b6b330eb4e (patch) | |
tree | 88ac93be41edadd8cbfe6448e1421d5165883f59 /media/libmedia/IAudioPolicyService.cpp | |
parent | a64c8c79af1a15911c55306d83a797fa50969f77 (diff) | |
download | frameworks_av-c2f1f07084818942352c6bbfb36af9b6b330eb4e.zip frameworks_av-c2f1f07084818942352c6bbfb36af9b6b330eb4e.tar.gz frameworks_av-c2f1f07084818942352c6bbfb36af9b6b330eb4e.tar.bz2 |
Fix issue 1795088 Improve audio routing code
Initial commit for review.
Integrated comments after patch set 1 review.
Fixed lockup in AudioFlinger::ThreadBase::exit()
Fixed lockup when playing tone with AudioPlocyService startTone()
Diffstat (limited to 'media/libmedia/IAudioPolicyService.cpp')
-rw-r--r-- | media/libmedia/IAudioPolicyService.cpp | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp new file mode 100644 index 0000000..0d8a329 --- /dev/null +++ b/media/libmedia/IAudioPolicyService.cpp @@ -0,0 +1,423 @@ +/* +** +** 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 +}; + +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); + audio_io_handle_t output; + reply.read(&output, sizeof(audio_io_handle_t)); + return output; + } + + virtual status_t startOutput(audio_io_handle_t output, AudioSystem::stream_type stream) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + data.write(&output, sizeof(audio_io_handle_t)); + data.writeInt32(stream); + 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) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + data.write(&output, sizeof(audio_io_handle_t)); + data.writeInt32(stream); + 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.write(&output, sizeof(audio_io_handle_t)); + 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); + audio_io_handle_t input; + reply.read(&input, sizeof(audio_io_handle_t)); + return input; + } + + virtual status_t startInput(audio_io_handle_t input) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + data.write(&input, sizeof(audio_io_handle_t)); + 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.write(&input, sizeof(audio_io_handle_t)); + 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.write(&input, sizeof(audio_io_handle_t)); + 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()); + } +}; + +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->write(&output, sizeof(audio_io_handle_t)); + return NO_ERROR; + } break; + + case START_OUTPUT: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + audio_io_handle_t output; + data.read(&output, sizeof(audio_io_handle_t)); + uint32_t stream = data.readInt32(); + reply->writeInt32(static_cast <uint32_t>(startOutput(output, (AudioSystem::stream_type)stream))); + return NO_ERROR; + } break; + + case STOP_OUTPUT: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + audio_io_handle_t output; + data.read(&output, sizeof(audio_io_handle_t)); + uint32_t stream = data.readInt32(); + reply->writeInt32(static_cast <uint32_t>(stopOutput(output, (AudioSystem::stream_type)stream))); + return NO_ERROR; + } break; + + case RELEASE_OUTPUT: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + audio_io_handle_t output; + data.read(&output, sizeof(audio_io_handle_t)); + 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->write(&input, sizeof(audio_io_handle_t)); + return NO_ERROR; + } break; + + case START_INPUT: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + audio_io_handle_t input; + data.read(&input, sizeof(audio_io_handle_t)); + 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; + data.read(&input, sizeof(audio_io_handle_t)); + 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; + data.read(&input, sizeof(audio_io_handle_t)); + 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; + + default: + return BBinder::onTransact(code, data, reply, flags); + } +} + +// ---------------------------------------------------------------------------- + +}; // namespace android |