diff options
| author | Dima Zavin <dima@android.com> | 2011-04-19 16:53:42 -0700 |
|---|---|---|
| committer | Dima Zavin <dima@android.com> | 2011-04-27 10:48:25 -0700 |
| commit | e81531e91ecae92aff471dbff9cbeb0f95ff4a80 (patch) | |
| tree | 203c16c95e297163138f465e3a2a60c827873ce6 | |
| parent | f01215993dda68b6b52111d754bd0c7c2d5bcfa3 (diff) | |
| download | hardware_libhardware_legacy-e81531e91ecae92aff471dbff9cbeb0f95ff4a80.tar.gz hardware_libhardware_legacy-e81531e91ecae92aff471dbff9cbeb0f95ff4a80.tar.bz2 hardware_libhardware_legacy-e81531e91ecae92aff471dbff9cbeb0f95ff4a80.zip | |
hardware_legacy: provide HAL helpers for legacy audio users
This doesn't actually create a HAL, but rather a set of helper static
libraries that device specific libraries (i.e. the old libaudio pieces)
can link against to create a proper audio HAL module.
We provide an audio_policy static wrapper and audio hardware interface
static wrapper.
Change-Id: Ie56195447ad24b83888f752dca24674b0afd8a76
Signed-off-by: Dima Zavin <dima@android.com>
| -rw-r--r-- | audio/A2dpAudioInterface.cpp | 3 | ||||
| -rw-r--r-- | audio/A2dpAudioInterface.h | 3 | ||||
| -rw-r--r-- | audio/AudioHardwareGeneric.cpp | 4 | ||||
| -rw-r--r-- | audio/AudioHardwareGeneric.h | 5 | ||||
| -rw-r--r-- | audio/AudioHardwareInterface.cpp | 43 | ||||
| -rw-r--r-- | audio/AudioHardwareStub.cpp | 2 | ||||
| -rw-r--r-- | audio/AudioHardwareStub.h | 2 | ||||
| -rw-r--r-- | audio/AudioPolicyCompatClient.cpp | 142 | ||||
| -rw-r--r-- | audio/AudioPolicyCompatClient.h | 79 | ||||
| -rw-r--r-- | audio/AudioPolicyManagerBase.cpp | 12 | ||||
| -rw-r--r-- | audio/audio_hw_hal.cpp | 577 | ||||
| -rw-r--r-- | audio/audio_policy_hal.cpp | 419 | ||||
| -rw-r--r-- | include/hardware_legacy/AudioHardwareBase.h | 5 | ||||
| -rw-r--r-- | include/hardware_legacy/AudioHardwareInterface.h | 13 | ||||
| -rw-r--r-- | include/hardware_legacy/AudioPolicyInterface.h | 6 | ||||
| -rw-r--r-- | include/hardware_legacy/AudioPolicyManagerBase.h | 3 | ||||
| -rw-r--r-- | include/hardware_legacy/AudioSystemLegacy.h | 336 |
17 files changed, 1593 insertions, 61 deletions
diff --git a/audio/A2dpAudioInterface.cpp b/audio/A2dpAudioInterface.cpp index d926cb1..2d78858 100644 --- a/audio/A2dpAudioInterface.cpp +++ b/audio/A2dpAudioInterface.cpp @@ -25,7 +25,8 @@ #include "audio/liba2dp.h" #include <hardware_legacy/power.h> -namespace android { + +namespace android_audio_legacy { static const char *sA2dpWakeLock = "A2dpOutputStream"; #define MAX_WRITE_RETRIES 5 diff --git a/audio/A2dpAudioInterface.h b/audio/A2dpAudioInterface.h index dbe2c6a..8fe9745 100644 --- a/audio/A2dpAudioInterface.h +++ b/audio/A2dpAudioInterface.h @@ -25,7 +25,8 @@ #include <hardware_legacy/AudioHardwareBase.h> -namespace android { +namespace android_audio_legacy { + using android::Mutex; class A2dpAudioInterface : public AudioHardwareBase { diff --git a/audio/AudioHardwareGeneric.cpp b/audio/AudioHardwareGeneric.cpp index d63c031..61286e4 100644 --- a/audio/AudioHardwareGeneric.cpp +++ b/audio/AudioHardwareGeneric.cpp @@ -32,7 +32,9 @@ #include "AudioHardwareGeneric.h" #include <media/AudioRecord.h> -namespace android { +#include <hardware_legacy/AudioSystemLegacy.h> + +namespace android_audio_legacy { // ---------------------------------------------------------------------------- diff --git a/audio/AudioHardwareGeneric.h b/audio/AudioHardwareGeneric.h index aa4e78d..7b41e95 100644 --- a/audio/AudioHardwareGeneric.h +++ b/audio/AudioHardwareGeneric.h @@ -23,9 +23,12 @@ #include <utils/threads.h> +#include <hardware_legacy/AudioSystemLegacy.h> #include <hardware_legacy/AudioHardwareBase.h> -namespace android { +namespace android_audio_legacy { + using android::Mutex; + using android::AutoMutex; // ---------------------------------------------------------------------------- diff --git a/audio/AudioHardwareInterface.cpp b/audio/AudioHardwareInterface.cpp index f58e4c0..9cec267 100644 --- a/audio/AudioHardwareInterface.cpp +++ b/audio/AudioHardwareInterface.cpp @@ -38,7 +38,7 @@ // change to 1 to log routing calls #define LOG_ROUTING_CALLS 1 -namespace android { +namespace android_audio_legacy { #if LOG_ROUTING_CALLS static const char* routingModeStrings[] = @@ -66,46 +66,7 @@ static const char* displayMode(int mode) AudioHardwareInterface* AudioHardwareInterface::create() { - /* - * FIXME: This code needs to instantiate the correct audio device - * interface. For now - we use compile-time switches. - */ - AudioHardwareInterface* hw = 0; - char value[PROPERTY_VALUE_MAX]; - -#ifdef GENERIC_AUDIO - hw = new AudioHardwareGeneric(); -#else - // if running in emulation - use the emulator driver - if (property_get("ro.kernel.qemu", value, 0)) { - LOGD("Running in emulation - using generic audio driver"); - hw = new AudioHardwareGeneric(); - } - else { - LOGV("Creating Vendor Specific AudioHardware"); - hw = createAudioHardware(); - } -#endif - if (hw->initCheck() != NO_ERROR) { - LOGW("Using stubbed audio hardware. No sound will be produced."); - delete hw; - hw = new AudioHardwareStub(); - } - -#ifdef WITH_A2DP - hw = new A2dpAudioInterface(hw); -#endif - -#ifdef ENABLE_AUDIO_DUMP - // This code adds a record of buffers in a file to write calls made by AudioFlinger. - // It replaces the current AudioHardwareInterface object by an intermediate one which - // will record buffers in a file (after sending them to hardware) for testing purpose. - // This feature is enabled by defining symbol ENABLE_AUDIO_DUMP. - // The output file is set with setParameters("test_cmd_file_name=<name>"). Pause are not recorded in the file. - LOGV("opening PCM dump interface"); - hw = new AudioDumpInterface(hw); // replace interface -#endif - return hw; + return NULL; } AudioStreamOut::~AudioStreamOut() diff --git a/audio/AudioHardwareStub.cpp b/audio/AudioHardwareStub.cpp index d481150..70a8309 100644 --- a/audio/AudioHardwareStub.cpp +++ b/audio/AudioHardwareStub.cpp @@ -25,7 +25,7 @@ #include "AudioHardwareStub.h" #include <media/AudioRecord.h> -namespace android { +namespace android_audio_legacy { // ---------------------------------------------------------------------------- diff --git a/audio/AudioHardwareStub.h b/audio/AudioHardwareStub.h index 06a29de..0858f37 100644 --- a/audio/AudioHardwareStub.h +++ b/audio/AudioHardwareStub.h @@ -23,7 +23,7 @@ #include <hardware_legacy/AudioHardwareBase.h> -namespace android { +namespace android_audio_legacy { // ---------------------------------------------------------------------------- diff --git a/audio/AudioPolicyCompatClient.cpp b/audio/AudioPolicyCompatClient.cpp new file mode 100644 index 0000000..a685594 --- /dev/null +++ b/audio/AudioPolicyCompatClient.cpp @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2011 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 "AudioPolicyCompatClient" +//#define LOG_NDEBUG 0 + +#include <stdint.h> + +#include <hardware/hardware.h> +#include <hardware/audio.h> +#include <hardware/audio_policy.h> +#include <hardware/audio_policy_hal.h> + +#include <hardware_legacy/AudioSystemLegacy.h> + +#include "AudioPolicyCompatClient.h" + +namespace android_audio_legacy { + +audio_io_handle_t AudioPolicyCompatClient::openOutput(uint32_t *pDevices, + uint32_t *pSamplingRate, + uint32_t *pFormat, + uint32_t *pChannels, + uint32_t *pLatencyMs, + AudioSystem::output_flags flags) +{ + return mServiceOps->open_output(mService, pDevices, pSamplingRate, pFormat, + pChannels, pLatencyMs, + (audio_policy_output_flags_t)flags); +} + +audio_io_handle_t AudioPolicyCompatClient::openDuplicateOutput(audio_io_handle_t output1, + audio_io_handle_t output2) +{ + return mServiceOps->open_duplicate_output(mService, output1, output2); +} + +status_t AudioPolicyCompatClient::closeOutput(audio_io_handle_t output) +{ + return mServiceOps->close_output(mService, output); +} + +status_t AudioPolicyCompatClient::suspendOutput(audio_io_handle_t output) +{ + return mServiceOps->suspend_output(mService, output); +} + +status_t AudioPolicyCompatClient::restoreOutput(audio_io_handle_t output) +{ + return mServiceOps->restore_output(mService, output); +} + +audio_io_handle_t AudioPolicyCompatClient::openInput(uint32_t *pDevices, + uint32_t *pSamplingRate, + uint32_t *pFormat, + uint32_t *pChannels, + uint32_t acoustics) +{ + return mServiceOps->open_input(mService, pDevices, pSamplingRate, pFormat, + pChannels, acoustics); +} + +status_t AudioPolicyCompatClient::closeInput(audio_io_handle_t input) +{ + return mServiceOps->close_input(mService, input); +} + +status_t AudioPolicyCompatClient::setStreamOutput(AudioSystem::stream_type stream, + audio_io_handle_t output) +{ + return mServiceOps->set_stream_output(mService, (audio_stream_type_t)stream, + output); +} + +status_t AudioPolicyCompatClient::moveEffects(int session, audio_io_handle_t srcOutput, + audio_io_handle_t dstOutput) +{ + return mServiceOps->move_effects(mService, session, srcOutput, dstOutput); +} + +String8 AudioPolicyCompatClient::getParameters(audio_io_handle_t ioHandle, const String8& keys) +{ + char *str; + String8 out_str8; + + str = mServiceOps->get_parameters(mService, ioHandle, keys.string()); + out_str8 = String8(str); + free(str); + + return out_str8; +} + +void AudioPolicyCompatClient::setParameters(audio_io_handle_t ioHandle, + const String8& keyValuePairs, + int delayMs) +{ + mServiceOps->set_parameters(mService, ioHandle, keyValuePairs.string(), + delayMs); +} + +status_t AudioPolicyCompatClient::setStreamVolume( + AudioSystem::stream_type stream, + float volume, + audio_io_handle_t output, + int delayMs) +{ + return mServiceOps->set_stream_volume(mService, (audio_stream_type_t)stream, + volume, output, delayMs); +} + +status_t AudioPolicyCompatClient::startTone(ToneGenerator::tone_type tone, + AudioSystem::stream_type stream) +{ + return mServiceOps->start_tone(mService, + AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION, + (audio_stream_type_t)stream); +} + +status_t AudioPolicyCompatClient::stopTone() +{ + return mServiceOps->stop_tone(mService); +} + +status_t AudioPolicyCompatClient::setVoiceVolume(float volume, int delayMs) +{ + return mServiceOps->set_voice_volume(mService, volume, delayMs); +} + +}; // namespace android_audio_legacy diff --git a/audio/AudioPolicyCompatClient.h b/audio/AudioPolicyCompatClient.h new file mode 100644 index 0000000..073d379 --- /dev/null +++ b/audio/AudioPolicyCompatClient.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2011 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. + */ + +#ifndef ANDROID_AUDIOPOLICYCLIENTLEGACY_H +#define ANDROID_AUDIOPOLICYCLIENTLEGACY_H + +#include <hardware/audio.h> +#include <hardware/audio_policy.h> +#include <hardware/audio_policy_hal.h> + +#include <hardware_legacy/AudioSystemLegacy.h> +#include <hardware_legacy/AudioPolicyInterface.h> + +/************************************/ +/* FOR BACKWARDS COMPATIBILITY ONLY */ +/************************************/ +namespace android_audio_legacy { + +class AudioPolicyCompatClient : public AudioPolicyClientInterface { +public: + AudioPolicyCompatClient(struct audio_policy_service_ops *serviceOps, + void *service) : + mServiceOps(serviceOps) , mService(service) {} + + virtual audio_io_handle_t openOutput(uint32_t *pDevices, + uint32_t *pSamplingRate, + uint32_t *pFormat, + uint32_t *pChannels, + uint32_t *pLatencyMs, + AudioSystem::output_flags flags); + virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, + audio_io_handle_t output2); + virtual status_t closeOutput(audio_io_handle_t output); + virtual status_t suspendOutput(audio_io_handle_t output); + virtual status_t restoreOutput(audio_io_handle_t output); + virtual audio_io_handle_t openInput(uint32_t *pDevices, + uint32_t *pSamplingRate, + uint32_t *pFormat, + uint32_t *pChannels, + uint32_t acoustics); + virtual status_t closeInput(audio_io_handle_t input); + virtual status_t setStreamOutput(AudioSystem::stream_type stream, audio_io_handle_t output); + virtual status_t moveEffects(int session, + audio_io_handle_t srcOutput, + audio_io_handle_t dstOutput); + + virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys); + virtual void setParameters(audio_io_handle_t ioHandle, + const String8& keyValuePairs, + int delayMs = 0); + virtual status_t setStreamVolume(AudioSystem::stream_type stream, + float volume, + audio_io_handle_t output, + int delayMs = 0); + virtual status_t startTone(ToneGenerator::tone_type tone, AudioSystem::stream_type stream); + virtual status_t stopTone(); + virtual status_t setVoiceVolume(float volume, int delayMs = 0); + +private: + struct audio_policy_service_ops* mServiceOps; + void* mService; +}; + +}; // namespace android_audio_legacy + +#endif // ANDROID_AUDIOPOLICYCLIENTLEGACY_H diff --git a/audio/AudioPolicyManagerBase.cpp b/audio/AudioPolicyManagerBase.cpp index 32d92dc..6cdcec4 100644 --- a/audio/AudioPolicyManagerBase.cpp +++ b/audio/AudioPolicyManagerBase.cpp @@ -21,8 +21,7 @@ #include <media/mediarecorder.h> #include <math.h> -namespace android { - +namespace android_audio_legacy { // ---------------------------------------------------------------------------- // AudioPolicyInterface implementation @@ -542,7 +541,7 @@ audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type str } - LOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d, format %d, channels %x, flags %x", + LOGW_IF((output ==0), "getOutput() could not find output for stream %d, samplingRate %d, format %d, channels %x, flags %x", stream, samplingRate, format, channels, flags); return output; @@ -2114,7 +2113,7 @@ bool AudioPolicyManagerBase::needsDirectOuput(AudioSystem::stream_type stream, uint32_t device) { return ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) || - (format != 0 && !AudioSystem::isLinearPCM(format))); + (format !=0 && !AudioSystem::isLinearPCM(format))); } uint32_t AudioPolicyManagerBase::getMaxEffectsCpuLoad() @@ -2166,7 +2165,7 @@ void AudioPolicyManagerBase::AudioOutputDescriptor::changeRefCount(AudioSystem:: return; } mRefCount[stream] += delta; - LOGV("changeRefCount() delta %d, stream %d, refCount %d", delta, stream, mRefCount[stream]); + LOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]); } uint32_t AudioPolicyManagerBase::AudioOutputDescriptor::refCount() @@ -2222,8 +2221,7 @@ status_t AudioPolicyManagerBase::AudioOutputDescriptor::dump(int fd) AudioPolicyManagerBase::AudioInputDescriptor::AudioInputDescriptor() : mSamplingRate(0), mFormat(0), mChannels(0), - mAcoustics((AudioSystem::audio_in_acoustics)0), mDevice(0), mRefCount(0), - mInputSource(0) + mAcoustics((AudioSystem::audio_in_acoustics)0), mDevice(0), mRefCount(0) { } diff --git a/audio/audio_hw_hal.cpp b/audio/audio_hw_hal.cpp new file mode 100644 index 0000000..deb943d --- /dev/null +++ b/audio/audio_hw_hal.cpp @@ -0,0 +1,577 @@ +/* + * Copyright (C) 2011 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 "legacy_audio_hw_hal" +//#define LOG_NDEBUG 0 + +#include <stdint.h> + +#include <hardware/hardware.h> +#include <hardware/audio.h> +#include <hardware/audio_hal.h> + +#include <hardware_legacy/AudioHardwareInterface.h> +#include <hardware_legacy/AudioSystemLegacy.h> + +namespace android_audio_legacy { + +extern "C" { + +struct legacy_audio_module { + struct audio_module module; +}; + +struct legacy_audio_device { + struct audio_hw_device device; + + struct AudioHardwareInterface *hwif; +}; + +struct legacy_stream_out { + struct audio_stream_out stream; + + AudioStreamOut *legacy_out; +}; + +struct legacy_stream_in { + struct audio_stream_in stream; + + AudioStreamIn *legacy_in; +}; + +/** audio_stream_out implementation **/ +static uint32_t out_get_sample_rate(const struct audio_stream *stream) +{ + const struct legacy_stream_out *out = + reinterpret_cast<const struct legacy_stream_out *>(stream); + return out->legacy_out->sampleRate(); +} + +static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) +{ + struct legacy_stream_out *out = + reinterpret_cast<struct legacy_stream_out *>(stream); + + LOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); + /* TODO: implement this */ + return 0; +} + +static size_t out_get_buffer_size(const struct audio_stream *stream) +{ + const struct legacy_stream_out *out = + reinterpret_cast<const struct legacy_stream_out *>(stream); + return out->legacy_out->bufferSize(); +} + +static uint32_t out_get_channels(const struct audio_stream *stream) +{ + const struct legacy_stream_out *out = + reinterpret_cast<const struct legacy_stream_out *>(stream); + return out->legacy_out->channels(); +} + +static int out_get_format(const struct audio_stream *stream) +{ + const struct legacy_stream_out *out = + reinterpret_cast<const struct legacy_stream_out *>(stream); + return out->legacy_out->format(); +} + +static int out_set_format(struct audio_stream *stream, int format) +{ + struct legacy_stream_out *out = + reinterpret_cast<struct legacy_stream_out *>(stream); + LOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); + /* TODO: implement me */ + return 0; +} + +static int out_standby(struct audio_stream *stream) +{ + struct legacy_stream_out *out = + reinterpret_cast<struct legacy_stream_out *>(stream); + return out->legacy_out->standby(); +} + +static int out_dump(const struct audio_stream *stream, int fd) +{ + const struct legacy_stream_out *out = + reinterpret_cast<const struct legacy_stream_out *>(stream); + Vector<String16> args; + return out->legacy_out->dump(fd, args); +} + +static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) +{ + struct legacy_stream_out *out = + reinterpret_cast<struct legacy_stream_out *>(stream); + return out->legacy_out->setParameters(String8(kvpairs)); +} + +static char * out_get_parameters(const struct audio_stream *stream, const char *keys) +{ + const struct legacy_stream_out *out = + reinterpret_cast<const struct legacy_stream_out *>(stream); + String8 s8; + s8 = out->legacy_out->getParameters(String8(keys)); + return strdup(s8.string()); +} + +static uint32_t out_get_latency(const struct audio_stream_out *stream) +{ + const struct legacy_stream_out *out = + reinterpret_cast<const struct legacy_stream_out *>(stream); + return out->legacy_out->latency(); +} + +static int out_set_volume(struct audio_stream_out *stream, float left, + float right) +{ + struct legacy_stream_out *out = + reinterpret_cast<struct legacy_stream_out *>(stream); + return out->legacy_out->setVolume(left, right); +} + +static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, + size_t bytes) +{ + struct legacy_stream_out *out = + reinterpret_cast<struct legacy_stream_out *>(stream); + return out->legacy_out->write(buffer, bytes); +} + +static int out_get_render_position(const struct audio_stream_out *stream, + uint32_t *dsp_frames) +{ + const struct legacy_stream_out *out = + reinterpret_cast<const struct legacy_stream_out *>(stream); + return out->legacy_out->getRenderPosition(dsp_frames); +} + +/** audio_stream_in implementation **/ +static uint32_t in_get_sample_rate(const struct audio_stream *stream) +{ + const struct legacy_stream_in *in = + reinterpret_cast<const struct legacy_stream_in *>(stream); + return in->legacy_in->sampleRate(); +} + +static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate) +{ + struct legacy_stream_in *in = + reinterpret_cast<struct legacy_stream_in *>(stream); + + LOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); + /* TODO: implement this */ + return 0; +} + +static size_t in_get_buffer_size(const struct audio_stream *stream) +{ + const struct legacy_stream_in *in = + reinterpret_cast<const struct legacy_stream_in *>(stream); + return in->legacy_in->bufferSize(); +} + +static uint32_t in_get_channels(const struct audio_stream *stream) +{ + const struct legacy_stream_in *in = + reinterpret_cast<const struct legacy_stream_in *>(stream); + return in->legacy_in->channels(); +} + +static int in_get_format(const struct audio_stream *stream) +{ + const struct legacy_stream_in *in = + reinterpret_cast<const struct legacy_stream_in *>(stream); + return in->legacy_in->format(); +} + +static int in_set_format(struct audio_stream *stream, int format) +{ + struct legacy_stream_in *in = + reinterpret_cast<struct legacy_stream_in *>(stream); + LOGE("(%s:%d) %s: Implement me!", __FILE__, __LINE__, __func__); + /* TODO: implement me */ + return 0; +} + +static int in_standby(struct audio_stream *stream) +{ + struct legacy_stream_in *in = reinterpret_cast<struct legacy_stream_in *>(stream); + return in->legacy_in->standby(); +} + +static int in_dump(const struct audio_stream *stream, int fd) +{ + const struct legacy_stream_in *in = + reinterpret_cast<const struct legacy_stream_in *>(stream); + Vector<String16> args; + return in->legacy_in->dump(fd, args); +} + +static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) +{ + struct legacy_stream_in *in = + reinterpret_cast<struct legacy_stream_in *>(stream); + return in->legacy_in->setParameters(String8(kvpairs)); +} + +static char * in_get_parameters(const struct audio_stream *stream, + const char *keys) +{ + const struct legacy_stream_in *in = + reinterpret_cast<const struct legacy_stream_in *>(stream); + String8 s8; + s8 = in->legacy_in->getParameters(String8(keys)); + return strdup(s8.string()); +} + +static int in_set_gain(struct audio_stream_in *stream, float gain) +{ + struct legacy_stream_in *in = + reinterpret_cast<struct legacy_stream_in *>(stream); + return in->legacy_in->setGain(gain); +} + +static ssize_t in_read(struct audio_stream_in *stream, void* buffer, + size_t bytes) +{ + struct legacy_stream_in *in = + reinterpret_cast<struct legacy_stream_in *>(stream); + return in->legacy_in->read(buffer, bytes); +} + +static uint32_t in_get_input_frames_lost(struct audio_stream_in *stream) +{ + struct legacy_stream_in *in = + reinterpret_cast<struct legacy_stream_in *>(stream); + return in->legacy_in->getInputFramesLost(); +} + +/** audio_hw_device implementation **/ +static inline struct legacy_audio_device * to_ladev(struct audio_hw_device *dev) +{ + return reinterpret_cast<struct legacy_audio_device *>(dev); +} + +static inline const struct legacy_audio_device * to_cladev(const struct audio_hw_device *dev) +{ + return reinterpret_cast<const struct legacy_audio_device *>(dev); +} + +static uint32_t adev_get_supported_devices(const struct audio_hw_device *dev) +{ + /* XXX: The old AudioHardwareInterface interface is not smart enough to + * tell us this, so we'll lie and basically tell AF that we support the + * below input/output devices and cross our fingers. To do things properly, + * audio hardware interfaces that need advanced features (like this) should + * convert to the new HAL interface and not use this wrapper. */ + + return (/* OUT */ + AUDIO_DEVICE_OUT_EARPIECE | + AUDIO_DEVICE_OUT_SPEAKER | + AUDIO_DEVICE_OUT_WIRED_HEADSET | + AUDIO_DEVICE_OUT_WIRED_HEADPHONE | + AUDIO_DEVICE_OUT_AUX_DIGITAL | + AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET | + AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET | + AUDIO_DEVICE_OUT_ALL_SCO | + AUDIO_DEVICE_OUT_DEFAULT | + /* IN */ + AUDIO_DEVICE_IN_COMMUNICATION | + AUDIO_DEVICE_IN_AMBIENT | + AUDIO_DEVICE_IN_BUILTIN_MIC | + AUDIO_DEVICE_IN_WIRED_HEADSET | + AUDIO_DEVICE_IN_AUX_DIGITAL | + AUDIO_DEVICE_IN_BACK_MIC | + AUDIO_DEVICE_IN_ALL_SCO | + AUDIO_DEVICE_IN_DEFAULT); +} + +static int adev_init_check(const struct audio_hw_device *dev) +{ + const struct legacy_audio_device *ladev = to_cladev(dev); + + return ladev->hwif->initCheck(); +} + +static int adev_set_voice_volume(struct audio_hw_device *dev, float volume) +{ + struct legacy_audio_device *ladev = to_ladev(dev); + return ladev->hwif->setVoiceVolume(volume); +} + +static int adev_set_master_volume(struct audio_hw_device *dev, float volume) +{ + struct legacy_audio_device *ladev = to_ladev(dev); + return ladev->hwif->setMasterVolume(volume); +} + +static int adev_set_mode(struct audio_hw_device *dev, int mode) +{ + struct legacy_audio_device *ladev = to_ladev(dev); + return ladev->hwif->setMode(mode); +} + +static int adev_set_mic_mute(struct audio_hw_device *dev, bool state) +{ + struct legacy_audio_device *ladev = to_ladev(dev); + return ladev->hwif->setMicMute(state); +} + +static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) +{ + const struct legacy_audio_device *ladev = to_cladev(dev); + return ladev->hwif->getMicMute(state); +} + +static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs) +{ + struct legacy_audio_device *ladev = to_ladev(dev); + return ladev->hwif->setParameters(String8(kvpairs)); +} + +static char * adev_get_parameters(const struct audio_hw_device *dev, + const char *keys) +{ + const struct legacy_audio_device *ladev = to_cladev(dev); + String8 s8; + + s8 = ladev->hwif->getParameters(String8(keys)); + return strdup(s8.string()); +} + +static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, + uint32_t sample_rate, int format, + int channel_count) +{ + const struct legacy_audio_device *ladev = to_cladev(dev); + return ladev->hwif->getInputBufferSize(sample_rate, format, channel_count); +} + +static int adev_open_output_stream(struct audio_hw_device *dev, + uint32_t devices, + int *format, + uint32_t *channels, + uint32_t *sample_rate, + struct audio_stream_out **stream_out) +{ + struct legacy_audio_device *ladev = to_ladev(dev); + status_t status; + struct legacy_stream_out *out; + int ret; + + out = (struct legacy_stream_out *)calloc(1, sizeof(*out)); + if (!out) + return -ENOMEM; + + out->legacy_out = ladev->hwif->openOutputStream(devices, format, channels, + sample_rate, &status); + if (!out->legacy_out) { + ret = status; + goto err_open; + } + + out->stream.common.get_sample_rate = out_get_sample_rate; + out->stream.common.set_sample_rate = out_set_sample_rate; + out->stream.common.get_buffer_size = out_get_buffer_size; + out->stream.common.get_channels = out_get_channels; + out->stream.common.get_format = out_get_format; + out->stream.common.set_format = out_set_format; + out->stream.common.standby = out_standby; + out->stream.common.dump = out_dump; + out->stream.common.set_parameters = out_set_parameters; + out->stream.common.get_parameters = out_get_parameters; + out->stream.get_latency = out_get_latency; + out->stream.set_volume = out_set_volume; + out->stream.write = out_write; + out->stream.get_render_position = out_get_render_position; + + *stream_out = &out->stream; + return 0; + +err_open: + free(out); + *stream_out = NULL; + return ret; +} + +static void adev_close_output_stream(struct audio_hw_device *dev, + struct audio_stream_out* stream) +{ + struct legacy_audio_device *ladev = to_ladev(dev); + struct legacy_stream_out *out = reinterpret_cast<struct legacy_stream_out *>(stream); + + ladev->hwif->closeOutputStream(out->legacy_out); + free(out); +} + +/** This method creates and opens the audio hardware input stream */ +static int adev_open_input_stream(struct audio_hw_device *dev, + uint32_t devices, int *format, + uint32_t *channels, uint32_t *sample_rate, + audio_in_acoustics_t acoustics, + struct audio_stream_in **stream_in) +{ + struct legacy_audio_device *ladev = to_ladev(dev); + status_t status; + struct legacy_stream_in *in; + int ret; + + in = (struct legacy_stream_in *)calloc(1, sizeof(*in)); + if (!in) + return -ENOMEM; + + in->legacy_in = ladev->hwif->openInputStream(devices, format, channels, + sample_rate, &status, + (AudioSystem::audio_in_acoustics)acoustics); + if (!in->legacy_in) { + ret = status; + goto err_open; + } + + in->stream.common.get_sample_rate = in_get_sample_rate; + in->stream.common.set_sample_rate = in_set_sample_rate; + in->stream.common.get_buffer_size = in_get_buffer_size; + in->stream.common.get_channels = in_get_channels; + in->stream.common.get_format = in_get_format; + in->stream.common.set_format = in_set_format; + in->stream.common.standby = in_standby; + in->stream.common.dump = in_dump; + in->stream.common.set_parameters = in_set_parameters; + in->stream.common.get_parameters = in_get_parameters; + in->stream.set_gain = in_set_gain; + in->stream.read = in_read; + in->stream.get_input_frames_lost = in_get_input_frames_lost; + + *stream_in = &in->stream; + return 0; + +err_open: + free(in); + *stream_in = NULL; + return ret; +} + +static void adev_close_input_stream(struct audio_hw_device *dev, + struct audio_stream_in *stream) +{ + struct legacy_audio_device *ladev = to_ladev(dev); + struct legacy_stream_in *in = + reinterpret_cast<struct legacy_stream_in *>(stream); + + ladev->hwif->closeInputStream(in->legacy_in); + free(in); +} + +static int adev_dump(const struct audio_hw_device *dev, int fd) +{ + const struct legacy_audio_device *ladev = to_cladev(dev); + Vector<String16> args; + + return ladev->hwif->dumpState(fd, args); +} + +static int legacy_adev_close(hw_device_t* device) +{ + struct audio_hw_device *hwdev = + reinterpret_cast<struct audio_hw_device *>(device); + struct legacy_audio_device *ladev = to_ladev(hwdev); + + if (!ladev) + return 0; + + if (ladev->hwif) + delete ladev->hwif; + + free(ladev); + return 0; +} + +static int legacy_adev_open(const hw_module_t* module, const char* name, + hw_device_t** device) +{ + struct legacy_audio_device *ladev; + int ret; + + if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) + return -EINVAL; + + ladev = (struct legacy_audio_device *)calloc(1, sizeof(*ladev)); + if (!ladev) + return -ENOMEM; + + ladev->device.common.tag = HARDWARE_DEVICE_TAG; + ladev->device.common.version = 0; + ladev->device.common.module = const_cast<hw_module_t*>(module); + ladev->device.common.close = legacy_adev_close; + + ladev->device.get_supported_devices = adev_get_supported_devices; + ladev->device.init_check = adev_init_check; + ladev->device.set_voice_volume = adev_set_voice_volume; + ladev->device.set_master_volume = adev_set_master_volume; + ladev->device.set_mode = adev_set_mode; + ladev->device.set_mic_mute = adev_set_mic_mute; + ladev->device.get_mic_mute = adev_get_mic_mute; + ladev->device.set_parameters = adev_set_parameters; + ladev->device.get_parameters = adev_get_parameters; + ladev->device.get_input_buffer_size = adev_get_input_buffer_size; + ladev->device.open_output_stream = adev_open_output_stream; + ladev->device.close_output_stream = adev_close_output_stream; + ladev->device.open_input_stream = adev_open_input_stream; + ladev->device.close_input_stream = adev_close_input_stream; + ladev->device.dump = adev_dump; + + ladev->hwif = createAudioHardware(); + if (!ladev->hwif) { + ret = -EIO; + goto err_create_audio_hw; + } + + *device = &ladev->device.common; + + return 0; + +err_create_audio_hw: + free(ladev); + return ret; +} + +static struct hw_module_methods_t legacy_audio_module_methods = { + open: legacy_adev_open +}; + +struct legacy_audio_module HAL_MODULE_INFO_SYM = { + module: { + common: { + tag: HARDWARE_MODULE_TAG, + version_major: 1, + version_minor: 0, + id: AUDIO_HARDWARE_MODULE_ID, + name: "LEGACY Audio HW HAL", + author: "The Android Open Source Project", + methods: &legacy_audio_module_methods, + dso : NULL, + reserved : {0}, + }, + }, +}; + +}; // extern "C" + +}; // namespace android_audio_legacy diff --git a/audio/audio_policy_hal.cpp b/audio/audio_policy_hal.cpp new file mode 100644 index 0000000..f115861 --- /dev/null +++ b/audio/audio_policy_hal.cpp @@ -0,0 +1,419 @@ +/* + * Copyright (C) 2011 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 "legacy_audio_policy_hal" +//#define LOG_NDEBUG 0 + +#include <stdint.h> + +#include <hardware/hardware.h> +#include <hardware/audio.h> +#include <hardware/audio_policy.h> +#include <hardware/audio_policy_hal.h> + +#include <hardware_legacy/AudioPolicyInterface.h> +#include <hardware_legacy/AudioSystemLegacy.h> + +#include "AudioPolicyCompatClient.h" + +namespace android_audio_legacy { + +extern "C" { + +struct legacy_ap_module { + struct audio_policy_module module; +}; + +struct legacy_ap_device { + struct audio_policy_device device; +}; + +struct legacy_audio_policy { + struct audio_policy policy; + + void *service; + struct audio_policy_service_ops *aps_ops; + AudioPolicyCompatClient *service_client; + AudioPolicyInterface *apm; +}; + +static inline struct legacy_audio_policy * to_lap(struct audio_policy *pol) +{ + return reinterpret_cast<struct legacy_audio_policy *>(pol); +} + +static inline const struct legacy_audio_policy * to_clap(const struct audio_policy *pol) +{ + return reinterpret_cast<const struct legacy_audio_policy *>(pol); +} + + +static int ap_set_device_connection_state(struct audio_policy *pol, + audio_devices_t device, + audio_policy_dev_state_t state, + const char *device_address) +{ + struct legacy_audio_policy *lap = to_lap(pol); + return lap->apm->setDeviceConnectionState( + (AudioSystem::audio_devices)device, + (AudioSystem::device_connection_state)state, + device_address); +} + +static audio_policy_dev_state_t ap_get_device_connection_state( + const struct audio_policy *pol, + audio_devices_t device, + const char *device_address) +{ + const struct legacy_audio_policy *lap = to_clap(pol); + return (audio_policy_dev_state_t)lap->apm->getDeviceConnectionState( + (AudioSystem::audio_devices)device, + device_address); +} + +static void ap_set_phone_state(struct audio_policy *pol, int state) +{ + struct legacy_audio_policy *lap = to_lap(pol); + lap->apm->setPhoneState(state); +} + + /* indicate a change in ringer mode */ +static void ap_set_ringer_mode(struct audio_policy *pol, uint32_t mode, + uint32_t mask) +{ + struct legacy_audio_policy *lap = to_lap(pol); + lap->apm->setRingerMode(mode, mask); +} + + /* force using a specific device category for the specified usage */ +static void ap_set_force_use(struct audio_policy *pol, + audio_policy_force_use_t usage, + audio_policy_forced_cfg_t config) +{ + struct legacy_audio_policy *lap = to_lap(pol); + lap->apm->setForceUse((AudioSystem::force_use)usage, + (AudioSystem::forced_config)config); +} + + /* retreive current device category forced for a given usage */ +static audio_policy_forced_cfg_t ap_get_force_use( + const struct audio_policy *pol, + audio_policy_force_use_t usage) +{ + const struct legacy_audio_policy *lap = to_clap(pol); + return (audio_policy_forced_cfg_t)lap->apm->getForceUse( + (AudioSystem::force_use)usage); +} + +/* if can_mute is true, then audio streams that are marked ENFORCED_AUDIBLE + * can still be muted. */ +static void ap_set_can_mute_enforced_audible(struct audio_policy *pol, + bool can_mute) +{ + struct legacy_audio_policy *lap = to_lap(pol); + lap->apm->setSystemProperty("ro.camera.sound.forced", can_mute ? "0" : "1"); +} + +static int ap_init_check(const struct audio_policy *pol) +{ + const struct legacy_audio_policy *lap = to_clap(pol); + return lap->apm->initCheck(); +} + +static audio_io_handle_t ap_get_output(struct audio_policy *pol, + audio_stream_type_t stream, + uint32_t sampling_rate, + uint32_t format, + uint32_t channels, + audio_policy_output_flags_t flags) +{ + struct legacy_audio_policy *lap = to_lap(pol); + + LOGV("%s: tid %d", __func__, gettid()); + return lap->apm->getOutput((AudioSystem::stream_type)stream, + sampling_rate, format, channels, + (AudioSystem::output_flags)flags); +} + +static int ap_start_output(struct audio_policy *pol, audio_io_handle_t output, + audio_stream_type_t stream, int session) +{ + struct legacy_audio_policy *lap = to_lap(pol); + return lap->apm->startOutput(output, (AudioSystem::stream_type)stream, + session); +} + +static int ap_stop_output(struct audio_policy *pol, audio_io_handle_t output, + audio_stream_type_t stream, int session) +{ + struct legacy_audio_policy *lap = to_lap(pol); + return lap->apm->stopOutput(output, (AudioSystem::stream_type)stream, + session); +} + +static void ap_release_output(struct audio_policy *pol, + audio_io_handle_t output) +{ + struct legacy_audio_policy *lap = to_lap(pol); + lap->apm->releaseOutput(output); +} + +static audio_io_handle_t ap_get_input(struct audio_policy *pol, int inputSource, + uint32_t sampling_rate, + uint32_t format, + uint32_t channels, + audio_in_acoustics_t acoustics) +{ + struct legacy_audio_policy *lap = to_lap(pol); + return lap->apm->getInput(inputSource, sampling_rate, format, channels, + (AudioSystem::audio_in_acoustics)acoustics); +} + +static int ap_start_input(struct audio_policy *pol, audio_io_handle_t input) +{ + struct legacy_audio_policy *lap = to_lap(pol); + return lap->apm->startInput(input); +} + +static int ap_stop_input(struct audio_policy *pol, audio_io_handle_t input) +{ + struct legacy_audio_policy *lap = to_lap(pol); + return lap->apm->stopInput(input); +} + +static void ap_release_input(struct audio_policy *pol, audio_io_handle_t input) +{ + struct legacy_audio_policy *lap = to_lap(pol); + lap->apm->releaseInput(input); +} + +static void ap_init_stream_volume(struct audio_policy *pol, + audio_stream_type_t stream, int index_min, + int index_max) +{ + struct legacy_audio_policy *lap = to_lap(pol); + lap->apm->initStreamVolume((AudioSystem::stream_type)stream, index_min, + index_max); +} + +static int ap_set_stream_volume_index(struct audio_policy *pol, + audio_stream_type_t stream, + int index) +{ + struct legacy_audio_policy *lap = to_lap(pol); + return lap->apm->setStreamVolumeIndex((AudioSystem::stream_type)stream, + index); +} + +static int ap_get_stream_volume_index(const struct audio_policy *pol, + audio_stream_type_t stream, + int *index) +{ + const struct legacy_audio_policy *lap = to_clap(pol); + return lap->apm->getStreamVolumeIndex((AudioSystem::stream_type)stream, + index); +} + +static uint32_t ap_get_strategy_for_stream(const struct audio_policy *pol, + audio_stream_type_t stream) +{ + const struct legacy_audio_policy *lap = to_clap(pol); + return lap->apm->getStrategyForStream((AudioSystem::stream_type)stream); +} + +static uint32_t ap_get_devices_for_stream(const struct audio_policy *pol, + audio_stream_type_t stream) +{ + const struct legacy_audio_policy *lap = to_clap(pol); + return lap->apm->getDevicesForStream((AudioSystem::stream_type)stream); +} + +static audio_io_handle_t ap_get_output_for_effect(struct audio_policy *pol, + struct effect_descriptor_s *desc) +{ + struct legacy_audio_policy *lap = to_lap(pol); + return lap->apm->getOutputForEffect(desc); +} + +static int ap_register_effect(struct audio_policy *pol, + struct effect_descriptor_s *desc, + audio_io_handle_t output, + uint32_t strategy, + int session, + int id) +{ + struct legacy_audio_policy *lap = to_lap(pol); + return lap->apm->registerEffect(desc, output, strategy, session, id); +} + +static int ap_unregister_effect(struct audio_policy *pol, int id) +{ + struct legacy_audio_policy *lap = to_lap(pol); + return lap->apm->unregisterEffect(id); +} + +static bool ap_is_stream_active(const struct audio_policy *pol, int stream, + uint32_t in_past_ms) +{ + const struct legacy_audio_policy *lap = to_clap(pol); + return lap->apm->isStreamActive(stream, in_past_ms); +} + +static int ap_dump(const struct audio_policy *pol, int fd) +{ + const struct legacy_audio_policy *lap = to_clap(pol); + return lap->apm->dump(fd); +} + +static int create_legacy_ap(const struct audio_policy_device *device, + struct audio_policy_service_ops *aps_ops, + void *service, + struct audio_policy **ap) +{ + struct legacy_audio_policy *lap; + int ret; + + if (!service || !aps_ops) + return -EINVAL; + + lap = (struct legacy_audio_policy *)calloc(1, sizeof(*lap)); + if (!lap) + return -ENOMEM; + + lap->policy.set_device_connection_state = ap_set_device_connection_state; + lap->policy.get_device_connection_state = ap_get_device_connection_state; + lap->policy.set_phone_state = ap_set_phone_state; + lap->policy.set_ringer_mode = ap_set_ringer_mode; + lap->policy.set_force_use = ap_set_force_use; + lap->policy.get_force_use = ap_get_force_use; + lap->policy.set_can_mute_enforced_audible = + ap_set_can_mute_enforced_audible; + lap->policy.init_check = ap_init_check; + lap->policy.get_output = ap_get_output; + lap->policy.start_output = ap_start_output; + lap->policy.stop_output = ap_stop_output; + lap->policy.release_output = ap_release_output; + lap->policy.get_input = ap_get_input; + lap->policy.start_input = ap_start_input; + lap->policy.stop_input = ap_stop_input; + lap->policy.release_input = ap_release_input; + lap->policy.init_stream_volume = ap_init_stream_volume; + lap->policy.set_stream_volume_index = ap_set_stream_volume_index; + lap->policy.get_stream_volume_index = ap_get_stream_volume_index; + lap->policy.get_strategy_for_stream = ap_get_strategy_for_stream; + lap->policy.get_devices_for_stream = ap_get_devices_for_stream; + lap->policy.get_output_for_effect = ap_get_output_for_effect; + lap->policy.register_effect = ap_register_effect; + lap->policy.unregister_effect = ap_unregister_effect; + lap->policy.is_stream_active = ap_is_stream_active; + lap->policy.dump = ap_dump; + + lap->service = service; + lap->aps_ops = aps_ops; + lap->service_client = + new AudioPolicyCompatClient(aps_ops, service); + if (!lap->service_client) { + ret = -ENOMEM; + goto err_new_compat_client; + } + + lap->apm = createAudioPolicyManager(lap->service_client); + if (!lap->apm) { + ret = -ENOMEM; + goto err_create_apm; + } + + *ap = &lap->policy; + return 0; + +err_create_apm: + delete lap->service_client; +err_new_compat_client: + free(lap); + *ap = NULL; + return ret; +} + +static int destroy_legacy_ap(const struct audio_policy_device *ap_dev, + struct audio_policy *ap) +{ + struct legacy_audio_policy *lap = to_lap(ap); + + if (!lap) + return 0; + + if (lap->apm) + destroyAudioPolicyManager(lap->apm); + if (lap->service_client) + delete lap->service_client; + free(lap); + return 0; +} + +static int legacy_ap_dev_close(hw_device_t* device) +{ + if (device) + free(device); + return 0; +} + +static int legacy_ap_dev_open(const hw_module_t* module, const char* name, + hw_device_t** device) +{ + struct legacy_ap_device *dev; + + if (strcmp(name, AUDIO_POLICY_INTERFACE) != 0) + return -EINVAL; + + dev = (struct legacy_ap_device *)calloc(1, sizeof(*dev)); + if (!dev) + return -ENOMEM; + + dev->device.common.tag = HARDWARE_DEVICE_TAG; + dev->device.common.version = 0; + dev->device.common.module = const_cast<hw_module_t*>(module); + dev->device.common.close = legacy_ap_dev_close; + dev->device.create_audio_policy = create_legacy_ap; + dev->device.destroy_audio_policy = destroy_legacy_ap; + + *device = &dev->device.common; + + return 0; +} + +static struct hw_module_methods_t legacy_ap_module_methods = { + open: legacy_ap_dev_open +}; + +struct legacy_ap_module HAL_MODULE_INFO_SYM = { + module: { + common: { + tag: HARDWARE_MODULE_TAG, + version_major: 1, + version_minor: 0, + id: AUDIO_POLICY_HARDWARE_MODULE_ID, + name: "LEGACY Audio Policy HAL", + author: "The Android Open Source Project", + methods: &legacy_ap_module_methods, + dso : NULL, + reserved : {0}, + }, + }, +}; + +}; // extern "C" + +}; // namespace android_audio_legacy diff --git a/include/hardware_legacy/AudioHardwareBase.h b/include/hardware_legacy/AudioHardwareBase.h index c34135f..f8e5b8f 100644 --- a/include/hardware_legacy/AudioHardwareBase.h +++ b/include/hardware_legacy/AudioHardwareBase.h @@ -17,10 +17,11 @@ #ifndef ANDROID_AUDIO_HARDWARE_BASE_H #define ANDROID_AUDIO_HARDWARE_BASE_H -#include "hardware_legacy/AudioHardwareInterface.h" +#include <hardware_legacy/AudioHardwareInterface.h> +#include <hardware/audio.h> -namespace android { +namespace android_audio_legacy { // ---------------------------------------------------------------------------- diff --git a/include/hardware_legacy/AudioHardwareInterface.h b/include/hardware_legacy/AudioHardwareInterface.h index ba65d9a..198cff3 100644 --- a/include/hardware_legacy/AudioHardwareInterface.h +++ b/include/hardware_legacy/AudioHardwareInterface.h @@ -26,10 +26,17 @@ #include <utils/String8.h> #include <media/IAudioFlinger.h> -#include "media/AudioSystem.h" +#include <hardware_legacy/AudioSystemLegacy.h> +#include <hardware/audio.h> +#include <hardware/audio_hal.h> -namespace android { +#include <cutils/bitops.h> + +namespace android_audio_legacy { + using android::Vector; + using android::String16; + using android::String8; // ---------------------------------------------------------------------------- @@ -62,7 +69,7 @@ public: /** * return the frame size (number of bytes per sample). */ - uint32_t frameSize() const { return AudioSystem::popCount(channels())*((format()==AudioSystem::PCM_16_BIT)?sizeof(int16_t):sizeof(int8_t)); } + uint32_t frameSize() const { return popcount(channels())*((format()==AUDIO_FORMAT_PCM_16_BIT)?sizeof(int16_t):sizeof(int8_t)); } /** * return the audio hardware driver latency in milli seconds. diff --git a/include/hardware_legacy/AudioPolicyInterface.h b/include/hardware_legacy/AudioPolicyInterface.h index 76f9c7a..7b9fb94 100644 --- a/include/hardware_legacy/AudioPolicyInterface.h +++ b/include/hardware_legacy/AudioPolicyInterface.h @@ -21,8 +21,12 @@ #include <media/ToneGenerator.h> #include <utils/String8.h> -namespace android { +#include <hardware_legacy/AudioSystemLegacy.h> +namespace android_audio_legacy { + using android::Vector; + using android::String8; + using android::ToneGenerator; // ---------------------------------------------------------------------------- diff --git a/include/hardware_legacy/AudioPolicyManagerBase.h b/include/hardware_legacy/AudioPolicyManagerBase.h index 1b03267..2ad1710 100644 --- a/include/hardware_legacy/AudioPolicyManagerBase.h +++ b/include/hardware_legacy/AudioPolicyManagerBase.h @@ -23,7 +23,8 @@ #include <hardware_legacy/AudioPolicyInterface.h> -namespace android { +namespace android_audio_legacy { + using android::KeyedVector; // ---------------------------------------------------------------------------- diff --git a/include/hardware_legacy/AudioSystemLegacy.h b/include/hardware_legacy/AudioSystemLegacy.h new file mode 100644 index 0000000..e72bb93 --- /dev/null +++ b/include/hardware_legacy/AudioSystemLegacy.h @@ -0,0 +1,336 @@ +/* + * Copyright (C) 2008 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. + */ + +#ifndef ANDROID_AUDIOSYSTEM_LEGACY_H_ +#define ANDROID_AUDIOSYSTEM_LEGACY_H_ + +#include <utils/Errors.h> +#include <media/AudioParameter.h> + +#include <hardware/audio.h> +#include <hardware/audio_policy.h> + +namespace android_audio_legacy { + +using android::status_t; +using android::AudioParameter; + +enum { + OK = android::OK, + NO_ERROR = android::NO_ERROR, + + UNKNOWN_ERROR = android::UNKNOWN_ERROR, + + NO_MEMORY = android::NO_MEMORY, + INVALID_OPERATION = android::INVALID_OPERATION, + BAD_VALUE = android::BAD_VALUE, + BAD_TYPE = android::BAD_TYPE, + NAME_NOT_FOUND = android::NAME_NOT_FOUND, + PERMISSION_DENIED = android::PERMISSION_DENIED, + NO_INIT = android::NO_INIT, + ALREADY_EXISTS = android::ALREADY_EXISTS, + DEAD_OBJECT = android::DEAD_OBJECT, + FAILED_TRANSACTION = android::FAILED_TRANSACTION, + JPARKS_BROKE_IT = android::JPARKS_BROKE_IT, + BAD_INDEX = android::BAD_INDEX, + NOT_ENOUGH_DATA = android::NOT_ENOUGH_DATA, + WOULD_BLOCK = android::WOULD_BLOCK, + TIMED_OUT = android::TIMED_OUT, + UNKNOWN_TRANSACTION = android::UNKNOWN_TRANSACTION, +}; + +enum audio_source { + AUDIO_SOURCE_DEFAULT = 0, + AUDIO_SOURCE_MIC = 1, + AUDIO_SOURCE_VOICE_UPLINK = 2, + AUDIO_SOURCE_VOICE_DOWNLINK = 3, + AUDIO_SOURCE_VOICE_CALL = 4, + AUDIO_SOURCE_CAMCORDER = 5, + AUDIO_SOURCE_VOICE_RECOGNITION = 6, + AUDIO_SOURCE_VOICE_COMMUNICATION = 7, + AUDIO_SOURCE_MAX = AUDIO_SOURCE_VOICE_COMMUNICATION, + + AUDIO_SOURCE_LIST_END // must be last - used to validate audio source type +}; + +class AudioSystem { +public: +#if 1 + enum stream_type { + DEFAULT =-1, + VOICE_CALL = 0, + SYSTEM = 1, + RING = 2, + MUSIC = 3, + ALARM = 4, + NOTIFICATION = 5, + BLUETOOTH_SCO = 6, + ENFORCED_AUDIBLE = 7, // Sounds that cannot be muted by user and must be routed to speaker + DTMF = 8, + TTS = 9, + NUM_STREAM_TYPES + }; + + // Audio sub formats (see AudioSystem::audio_format). + enum pcm_sub_format { + PCM_SUB_16_BIT = 0x1, // must be 1 for backward compatibility + PCM_SUB_8_BIT = 0x2, // must be 2 for backward compatibility + }; + + enum audio_sessions { + SESSION_OUTPUT_STAGE = AUDIO_SESSION_OUTPUT_STAGE, + SESSION_OUTPUT_MIX = AUDIO_SESSION_OUTPUT_MIX, + }; + + // MP3 sub format field definition : can use 11 LSBs in the same way as MP3 frame header to specify + // bit rate, stereo mode, version... + enum mp3_sub_format { + //TODO + }; + + // AMR NB/WB sub format field definition: specify frame block interleaving, bandwidth efficient or octet aligned, + // encoding mode for recording... + enum amr_sub_format { + //TODO + }; + + // AAC sub format field definition: specify profile or bitrate for recording... + enum aac_sub_format { + //TODO + }; + + // VORBIS sub format field definition: specify quality for recording... + enum vorbis_sub_format { + //TODO + }; + + // Audio format consists in a main format field (upper 8 bits) and a sub format field (lower 24 bits). + // The main format indicates the main codec type. The sub format field indicates options and parameters + // for each format. The sub format is mainly used for record to indicate for instance the requested bitrate + // or profile. It can also be used for certain formats to give informations not present in the encoded + // audio stream (e.g. octet alignement for AMR). + enum audio_format { + INVALID_FORMAT = -1, + FORMAT_DEFAULT = 0, + PCM = 0x00000000, // must be 0 for backward compatibility + MP3 = 0x01000000, + AMR_NB = 0x02000000, + AMR_WB = 0x03000000, + AAC = 0x04000000, + HE_AAC_V1 = 0x05000000, + HE_AAC_V2 = 0x06000000, + VORBIS = 0x07000000, + MAIN_FORMAT_MASK = 0xFF000000, + SUB_FORMAT_MASK = 0x00FFFFFF, + // Aliases + PCM_16_BIT = (PCM|PCM_SUB_16_BIT), + PCM_8_BIT = (PCM|PCM_SUB_8_BIT) + }; + + + // Channel mask definitions must be kept in sync with JAVA values in /media/java/android/media/AudioFormat.java + enum audio_channels { + // output channels + CHANNEL_OUT_FRONT_LEFT = 0x4, + CHANNEL_OUT_FRONT_RIGHT = 0x8, + CHANNEL_OUT_FRONT_CENTER = 0x10, + CHANNEL_OUT_LOW_FREQUENCY = 0x20, + CHANNEL_OUT_BACK_LEFT = 0x40, + CHANNEL_OUT_BACK_RIGHT = 0x80, + CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x100, + CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x200, + CHANNEL_OUT_BACK_CENTER = 0x400, + CHANNEL_OUT_MONO = CHANNEL_OUT_FRONT_LEFT, + CHANNEL_OUT_STEREO = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT), + CHANNEL_OUT_QUAD = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | + CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT), + CHANNEL_OUT_SURROUND = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | + CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_BACK_CENTER), + CHANNEL_OUT_5POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | + CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT), + CHANNEL_OUT_7POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | + CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT | + CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER), + CHANNEL_OUT_ALL = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | + CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT | + CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER | CHANNEL_OUT_BACK_CENTER), + + // input channels + CHANNEL_IN_LEFT = 0x4, + CHANNEL_IN_RIGHT = 0x8, + CHANNEL_IN_FRONT = 0x10, + CHANNEL_IN_BACK = 0x20, + CHANNEL_IN_LEFT_PROCESSED = 0x40, + CHANNEL_IN_RIGHT_PROCESSED = 0x80, + CHANNEL_IN_FRONT_PROCESSED = 0x100, + CHANNEL_IN_BACK_PROCESSED = 0x200, + CHANNEL_IN_PRESSURE = 0x400, + CHANNEL_IN_X_AXIS = 0x800, + CHANNEL_IN_Y_AXIS = 0x1000, + CHANNEL_IN_Z_AXIS = 0x2000, + CHANNEL_IN_VOICE_UPLINK = 0x4000, + CHANNEL_IN_VOICE_DNLINK = 0x8000, + CHANNEL_IN_MONO = CHANNEL_IN_FRONT, + CHANNEL_IN_STEREO = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT), + CHANNEL_IN_ALL = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT | CHANNEL_IN_FRONT | CHANNEL_IN_BACK| + CHANNEL_IN_LEFT_PROCESSED | CHANNEL_IN_RIGHT_PROCESSED | CHANNEL_IN_FRONT_PROCESSED | CHANNEL_IN_BACK_PROCESSED| + CHANNEL_IN_PRESSURE | CHANNEL_IN_X_AXIS | CHANNEL_IN_Y_AXIS | CHANNEL_IN_Z_AXIS | + CHANNEL_IN_VOICE_UPLINK | CHANNEL_IN_VOICE_DNLINK) + }; + + enum audio_mode { + MODE_INVALID = -2, + MODE_CURRENT = -1, + MODE_NORMAL = 0, + MODE_RINGTONE, + MODE_IN_CALL, + MODE_IN_COMMUNICATION, + NUM_MODES // not a valid entry, denotes end-of-list + }; + + enum audio_in_acoustics { + AGC_ENABLE = 0x0001, + AGC_DISABLE = 0, + NS_ENABLE = 0x0002, + NS_DISABLE = 0, + TX_IIR_ENABLE = 0x0004, + TX_DISABLE = 0 + }; + + enum audio_devices { + // output devices + DEVICE_OUT_EARPIECE = 0x1, + DEVICE_OUT_SPEAKER = 0x2, + DEVICE_OUT_WIRED_HEADSET = 0x4, + DEVICE_OUT_WIRED_HEADPHONE = 0x8, + DEVICE_OUT_BLUETOOTH_SCO = 0x10, + DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20, + DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40, + DEVICE_OUT_BLUETOOTH_A2DP = 0x80, + DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100, + DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200, + DEVICE_OUT_AUX_DIGITAL = 0x400, + DEVICE_OUT_ANLG_DOCK_HEADSET = 0x800, + DEVICE_OUT_DGTL_DOCK_HEADSET = 0x1000, + DEVICE_OUT_DEFAULT = 0x8000, + DEVICE_OUT_ALL = (DEVICE_OUT_EARPIECE | DEVICE_OUT_SPEAKER | DEVICE_OUT_WIRED_HEADSET | + DEVICE_OUT_WIRED_HEADPHONE | DEVICE_OUT_BLUETOOTH_SCO | DEVICE_OUT_BLUETOOTH_SCO_HEADSET | + DEVICE_OUT_BLUETOOTH_SCO_CARKIT | DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | + DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER | DEVICE_OUT_AUX_DIGITAL | + DEVICE_OUT_ANLG_DOCK_HEADSET | DEVICE_OUT_DGTL_DOCK_HEADSET | + DEVICE_OUT_DEFAULT), + DEVICE_OUT_ALL_A2DP = (DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | + DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER), + + // input devices + DEVICE_IN_COMMUNICATION = 0x10000, + DEVICE_IN_AMBIENT = 0x20000, + DEVICE_IN_BUILTIN_MIC = 0x40000, + DEVICE_IN_BLUETOOTH_SCO_HEADSET = 0x80000, + DEVICE_IN_WIRED_HEADSET = 0x100000, + DEVICE_IN_AUX_DIGITAL = 0x200000, + DEVICE_IN_VOICE_CALL = 0x400000, + DEVICE_IN_BACK_MIC = 0x800000, + DEVICE_IN_DEFAULT = 0x80000000, + + DEVICE_IN_ALL = (DEVICE_IN_COMMUNICATION | DEVICE_IN_AMBIENT | DEVICE_IN_BUILTIN_MIC | + DEVICE_IN_BLUETOOTH_SCO_HEADSET | DEVICE_IN_WIRED_HEADSET | DEVICE_IN_AUX_DIGITAL | + DEVICE_IN_VOICE_CALL | DEVICE_IN_BACK_MIC | DEVICE_IN_DEFAULT) + }; + + // request to open a direct output with getOutput() (by opposition to sharing an output with other AudioTracks) + enum output_flags { + OUTPUT_FLAG_INDIRECT = 0x0, + OUTPUT_FLAG_DIRECT = 0x1 + }; + + // device categories used for setForceUse() + enum forced_config { + FORCE_NONE, + FORCE_SPEAKER, + FORCE_HEADPHONES, + FORCE_BT_SCO, + FORCE_BT_A2DP, + FORCE_WIRED_ACCESSORY, + FORCE_BT_CAR_DOCK, + FORCE_BT_DESK_DOCK, + FORCE_ANALOG_DOCK, + FORCE_DIGITAL_DOCK, + NUM_FORCE_CONFIG, + FORCE_DEFAULT = FORCE_NONE + }; + + // usages used for setForceUse() + enum force_use { + FOR_COMMUNICATION, + FOR_MEDIA, + FOR_RECORD, + FOR_DOCK, + NUM_FORCE_USE + }; + + // + // AudioPolicyService interface + // + + // device connection states used for setDeviceConnectionState() + enum device_connection_state { + DEVICE_STATE_UNAVAILABLE, + DEVICE_STATE_AVAILABLE, + NUM_DEVICE_STATES + }; + +#endif + + static uint32_t popCount(uint32_t u) { + return popcount(u); + } + +#if 1 + static bool isOutputDevice(audio_devices device) { + return audio_is_output_device((audio_devices_t)device); + } + static bool isInputDevice(audio_devices device) { + return audio_is_input_device((audio_devices_t)device); + } + static bool isA2dpDevice(audio_devices device) { + return audio_is_a2dp_device((audio_devices_t)device); + } + static bool isBluetoothScoDevice(audio_devices device) { + return audio_is_bluetooth_sco_device((audio_devices_t)device); + } + static bool isLowVisibility(stream_type stream) { + return audio_is_low_visibility((audio_stream_type_t)stream); + } + static bool isValidFormat(uint32_t format) { + return audio_is_valid_format(format); + } + static bool isLinearPCM(uint32_t format) { + return audio_is_linear_pcm(format); + } + static bool isOutputChannel(uint32_t channel) { + return audio_is_output_channel(channel); + } + static bool isInputChannel(uint32_t channel) { + return audio_is_input_channel(channel); + } + +#endif +}; + +}; // namespace android + +#endif // ANDROID_AUDIOSYSTEM_LEGACY_H_ |
