diff options
| author | TreeHugger Robot <treehugger-gerrit@google.com> | 2019-07-02 07:41:24 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2019-07-02 07:41:24 +0000 |
| commit | 26f1b51bfbd5e8d2d2e55247a8bae49ccd52872d (patch) | |
| tree | 0d99225e22e2956cf075fcf48527d0e17e872c0f /audio/core/all-versions/default/Device.cpp | |
| parent | 3adfddb29552dbf79387c23e10a9960d1f9c2f79 (diff) | |
| parent | 8b76f6692c718c21272d3585541b72fed7ac93f0 (diff) | |
Merge "DO NOT MERGE - Merge qt-dev-plus-aosp-without-vendor (5699924) into stage-aosp-master" into stage-aosp-master
Diffstat (limited to 'audio/core/all-versions/default/Device.cpp')
| -rw-r--r-- | audio/core/all-versions/default/Device.cpp | 390 |
1 files changed, 390 insertions, 0 deletions
diff --git a/audio/core/all-versions/default/Device.cpp b/audio/core/all-versions/default/Device.cpp new file mode 100644 index 0000000000..bec22df6d5 --- /dev/null +++ b/audio/core/all-versions/default/Device.cpp @@ -0,0 +1,390 @@ +/* + * Copyright (C) 2018 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 "DeviceHAL" + +#include "core/default/Device.h" +#include <HidlUtils.h> +#include "core/default/Conversions.h" +#include "core/default/StreamIn.h" +#include "core/default/StreamOut.h" +#include "core/default/Util.h" + +//#define LOG_NDEBUG 0 + +#include <memory.h> +#include <string.h> +#include <algorithm> + +#include <android/log.h> + +namespace android { +namespace hardware { +namespace audio { +namespace CPP_VERSION { +namespace implementation { + +using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils; + +Device::Device(audio_hw_device_t* device) : mDevice(device) {} + +Device::~Device() { + int status = audio_hw_device_close(mDevice); + ALOGW_IF(status, "Error closing audio hw device %p: %s", mDevice, strerror(-status)); + mDevice = nullptr; +} + +Result Device::analyzeStatus(const char* funcName, int status, + const std::vector<int>& ignoreErrors) { + return util::analyzeStatus("Device", funcName, status, ignoreErrors); +} + +void Device::closeInputStream(audio_stream_in_t* stream) { + mDevice->close_input_stream(mDevice, stream); +} + +void Device::closeOutputStream(audio_stream_out_t* stream) { + mDevice->close_output_stream(mDevice, stream); +} + +char* Device::halGetParameters(const char* keys) { + return mDevice->get_parameters(mDevice, keys); +} + +int Device::halSetParameters(const char* keysAndValues) { + return mDevice->set_parameters(mDevice, keysAndValues); +} + +// Methods from ::android::hardware::audio::CPP_VERSION::IDevice follow. +Return<Result> Device::initCheck() { + return analyzeStatus("init_check", mDevice->init_check(mDevice)); +} + +Return<Result> Device::setMasterVolume(float volume) { + if (mDevice->set_master_volume == NULL) { + return Result::NOT_SUPPORTED; + } + if (!isGainNormalized(volume)) { + ALOGW("Can not set a master volume (%f) outside [0,1]", volume); + return Result::INVALID_ARGUMENTS; + } + return analyzeStatus("set_master_volume", mDevice->set_master_volume(mDevice, volume)); +} + +Return<void> Device::getMasterVolume(getMasterVolume_cb _hidl_cb) { + Result retval(Result::NOT_SUPPORTED); + float volume = 0; + if (mDevice->get_master_volume != NULL) { + retval = analyzeStatus("get_master_volume", mDevice->get_master_volume(mDevice, &volume)); + } + _hidl_cb(retval, volume); + return Void(); +} + +Return<Result> Device::setMicMute(bool mute) { + return analyzeStatus("set_mic_mute", mDevice->set_mic_mute(mDevice, mute)); +} + +Return<void> Device::getMicMute(getMicMute_cb _hidl_cb) { + bool mute = false; + Result retval = analyzeStatus("get_mic_mute", mDevice->get_mic_mute(mDevice, &mute)); + _hidl_cb(retval, mute); + return Void(); +} + +Return<Result> Device::setMasterMute(bool mute) { + Result retval(Result::NOT_SUPPORTED); + if (mDevice->set_master_mute != NULL) { + retval = analyzeStatus("set_master_mute", mDevice->set_master_mute(mDevice, mute)); + } + return retval; +} + +Return<void> Device::getMasterMute(getMasterMute_cb _hidl_cb) { + Result retval(Result::NOT_SUPPORTED); + bool mute = false; + if (mDevice->get_master_mute != NULL) { + retval = analyzeStatus("get_master_mute", mDevice->get_master_mute(mDevice, &mute)); + } + _hidl_cb(retval, mute); + return Void(); +} + +Return<void> Device::getInputBufferSize(const AudioConfig& config, getInputBufferSize_cb _hidl_cb) { + audio_config_t halConfig; + HidlUtils::audioConfigToHal(config, &halConfig); + size_t halBufferSize = mDevice->get_input_buffer_size(mDevice, &halConfig); + Result retval(Result::INVALID_ARGUMENTS); + uint64_t bufferSize = 0; + if (halBufferSize != 0) { + retval = Result::OK; + bufferSize = halBufferSize; + } + _hidl_cb(retval, bufferSize); + return Void(); +} + +std::tuple<Result, sp<IStreamOut>> Device::openOutputStreamImpl(int32_t ioHandle, + const DeviceAddress& device, + const AudioConfig& config, + AudioOutputFlagBitfield flags, + AudioConfig* suggestedConfig) { + audio_config_t halConfig; + HidlUtils::audioConfigToHal(config, &halConfig); + audio_stream_out_t* halStream; + ALOGV( + "open_output_stream handle: %d devices: %x flags: %#x " + "srate: %d format %#x channels %x address %s", + ioHandle, static_cast<audio_devices_t>(device.device), + static_cast<audio_output_flags_t>(flags), halConfig.sample_rate, halConfig.format, + halConfig.channel_mask, deviceAddressToHal(device).c_str()); + int status = + mDevice->open_output_stream(mDevice, ioHandle, static_cast<audio_devices_t>(device.device), + static_cast<audio_output_flags_t>(flags), &halConfig, + &halStream, deviceAddressToHal(device).c_str()); + ALOGV("open_output_stream status %d stream %p", status, halStream); + sp<IStreamOut> streamOut; + if (status == OK) { + streamOut = new StreamOut(this, halStream); + } + HidlUtils::audioConfigFromHal(halConfig, suggestedConfig); + return {analyzeStatus("open_output_stream", status, {EINVAL} /*ignore*/), streamOut}; +} + +std::tuple<Result, sp<IStreamIn>> Device::openInputStreamImpl( + int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, + AudioInputFlagBitfield flags, AudioSource source, AudioConfig* suggestedConfig) { + audio_config_t halConfig; + HidlUtils::audioConfigToHal(config, &halConfig); + audio_stream_in_t* halStream; + ALOGV( + "open_input_stream handle: %d devices: %x flags: %#x " + "srate: %d format %#x channels %x address %s source %d", + ioHandle, static_cast<audio_devices_t>(device.device), + static_cast<audio_input_flags_t>(flags), halConfig.sample_rate, halConfig.format, + halConfig.channel_mask, deviceAddressToHal(device).c_str(), + static_cast<audio_source_t>(source)); + int status = mDevice->open_input_stream( + mDevice, ioHandle, static_cast<audio_devices_t>(device.device), &halConfig, &halStream, + static_cast<audio_input_flags_t>(flags), deviceAddressToHal(device).c_str(), + static_cast<audio_source_t>(source)); + ALOGV("open_input_stream status %d stream %p", status, halStream); + sp<IStreamIn> streamIn; + if (status == OK) { + streamIn = new StreamIn(this, halStream); + } + HidlUtils::audioConfigFromHal(halConfig, suggestedConfig); + return {analyzeStatus("open_input_stream", status, {EINVAL} /*ignore*/), streamIn}; +} + +#if MAJOR_VERSION == 2 +Return<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device, + const AudioConfig& config, AudioOutputFlagBitfield flags, + openOutputStream_cb _hidl_cb) { + AudioConfig suggestedConfig; + auto [result, streamOut] = + openOutputStreamImpl(ioHandle, device, config, flags, &suggestedConfig); + _hidl_cb(result, streamOut, suggestedConfig); + return Void(); +} + +Return<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& device, + const AudioConfig& config, AudioInputFlagBitfield flags, + AudioSource source, openInputStream_cb _hidl_cb) { + AudioConfig suggestedConfig; + auto [result, streamIn] = + openInputStreamImpl(ioHandle, device, config, flags, source, &suggestedConfig); + _hidl_cb(result, streamIn, suggestedConfig); + return Void(); +} + +#elif MAJOR_VERSION >= 4 +Return<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device, + const AudioConfig& config, AudioOutputFlagBitfield flags, + const SourceMetadata& sourceMetadata, + openOutputStream_cb _hidl_cb) { + AudioConfig suggestedConfig; + auto [result, streamOut] = + openOutputStreamImpl(ioHandle, device, config, flags, &suggestedConfig); + if (streamOut) { + streamOut->updateSourceMetadata(sourceMetadata); + } + _hidl_cb(result, streamOut, suggestedConfig); + return Void(); +} + +Return<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& device, + const AudioConfig& config, AudioInputFlagBitfield flags, + const SinkMetadata& sinkMetadata, + openInputStream_cb _hidl_cb) { + if (sinkMetadata.tracks.size() == 0) { + // This should never happen, the framework must not create as stream + // if there is no client + ALOGE("openInputStream called without tracks connected"); + _hidl_cb(Result::INVALID_ARGUMENTS, nullptr, AudioConfig()); + return Void(); + } + // Pick the first one as the main. + AudioSource source = sinkMetadata.tracks[0].source; + AudioConfig suggestedConfig; + auto [result, streamIn] = + openInputStreamImpl(ioHandle, device, config, flags, source, &suggestedConfig); + if (streamIn) { + streamIn->updateSinkMetadata(sinkMetadata); + } + _hidl_cb(result, streamIn, suggestedConfig); + return Void(); +} +#endif /* MAJOR_VERSION */ + +Return<bool> Device::supportsAudioPatches() { + return version() >= AUDIO_DEVICE_API_VERSION_3_0; +} + +Return<void> Device::createAudioPatch(const hidl_vec<AudioPortConfig>& sources, + const hidl_vec<AudioPortConfig>& sinks, + createAudioPatch_cb _hidl_cb) { + Result retval(Result::NOT_SUPPORTED); + AudioPatchHandle patch = 0; + if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { + std::unique_ptr<audio_port_config[]> halSources(HidlUtils::audioPortConfigsToHal(sources)); + std::unique_ptr<audio_port_config[]> halSinks(HidlUtils::audioPortConfigsToHal(sinks)); + audio_patch_handle_t halPatch = AUDIO_PATCH_HANDLE_NONE; + retval = analyzeStatus("create_audio_patch", + mDevice->create_audio_patch(mDevice, sources.size(), &halSources[0], + sinks.size(), &halSinks[0], &halPatch)); + if (retval == Result::OK) { + patch = static_cast<AudioPatchHandle>(halPatch); + } + } + _hidl_cb(retval, patch); + return Void(); +} + +Return<Result> Device::releaseAudioPatch(int32_t patch) { + if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { + return analyzeStatus( + "release_audio_patch", + mDevice->release_audio_patch(mDevice, static_cast<audio_patch_handle_t>(patch))); + } + return Result::NOT_SUPPORTED; +} + +Return<void> Device::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) { + audio_port halPort; + HidlUtils::audioPortToHal(port, &halPort); + Result retval = analyzeStatus("get_audio_port", mDevice->get_audio_port(mDevice, &halPort)); + AudioPort resultPort = port; + if (retval == Result::OK) { + HidlUtils::audioPortFromHal(halPort, &resultPort); + } + _hidl_cb(retval, resultPort); + return Void(); +} + +Return<Result> Device::setAudioPortConfig(const AudioPortConfig& config) { + if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { + struct audio_port_config halPortConfig; + HidlUtils::audioPortConfigToHal(config, &halPortConfig); + return analyzeStatus("set_audio_port_config", + mDevice->set_audio_port_config(mDevice, &halPortConfig)); + } + return Result::NOT_SUPPORTED; +} + +#if MAJOR_VERSION == 2 +Return<AudioHwSync> Device::getHwAvSync() { + int halHwAvSync; + Result retval = getParam(AudioParameter::keyHwAvSync, &halHwAvSync); + return retval == Result::OK ? halHwAvSync : AUDIO_HW_SYNC_INVALID; +} +#elif MAJOR_VERSION >= 4 +Return<void> Device::getHwAvSync(getHwAvSync_cb _hidl_cb) { + int halHwAvSync; + Result retval = getParam(AudioParameter::keyHwAvSync, &halHwAvSync); + _hidl_cb(retval, halHwAvSync); + return Void(); +} +#endif + +Return<Result> Device::setScreenState(bool turnedOn) { + return setParam(AudioParameter::keyScreenState, turnedOn); +} + +#if MAJOR_VERSION == 2 +Return<void> Device::getParameters(const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) { + getParametersImpl({}, keys, _hidl_cb); + return Void(); +} + +Return<Result> Device::setParameters(const hidl_vec<ParameterValue>& parameters) { + return setParametersImpl({} /* context */, parameters); +} +#elif MAJOR_VERSION >= 4 +Return<void> Device::getParameters(const hidl_vec<ParameterValue>& context, + const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) { + getParametersImpl(context, keys, _hidl_cb); + return Void(); +} +Return<Result> Device::setParameters(const hidl_vec<ParameterValue>& context, + const hidl_vec<ParameterValue>& parameters) { + return setParametersImpl(context, parameters); +} +#endif + +#if MAJOR_VERSION == 2 +Return<void> Device::debugDump(const hidl_handle& fd) { + return debug(fd, {}); +} +#endif + +Return<void> Device::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& /* options */) { + if (fd.getNativeHandle() != nullptr && fd->numFds == 1) { + analyzeStatus("dump", mDevice->dump(mDevice, fd->data[0])); + } + return Void(); +} + +#if MAJOR_VERSION >= 4 +Return<void> Device::getMicrophones(getMicrophones_cb _hidl_cb) { + Result retval = Result::NOT_SUPPORTED; + size_t actual_mics = AUDIO_MICROPHONE_MAX_COUNT; + audio_microphone_characteristic_t mic_array[AUDIO_MICROPHONE_MAX_COUNT]; + + hidl_vec<MicrophoneInfo> microphones; + if (mDevice->get_microphones != NULL && + mDevice->get_microphones(mDevice, &mic_array[0], &actual_mics) == 0) { + microphones.resize(actual_mics); + for (size_t i = 0; i < actual_mics; ++i) { + halToMicrophoneCharacteristics(µphones[i], mic_array[i]); + } + retval = Result::OK; + } + _hidl_cb(retval, microphones); + return Void(); +} + +Return<Result> Device::setConnectedState(const DeviceAddress& address, bool connected) { + auto key = connected ? AudioParameter::keyStreamConnect : AudioParameter::keyStreamDisconnect; + return setParam(key, address); +} +#endif + +} // namespace implementation +} // namespace CPP_VERSION +} // namespace audio +} // namespace hardware +} // namespace android |
