/* * 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. */ #include #include #include "primary_device.h" #include "stream_in.h" #include "stream_out.h" #include "util.h" #include "debug.h" namespace android { namespace hardware { namespace audio { namespace V6_0 { namespace implementation { constexpr size_t kInBufferDurationMs = 15; constexpr size_t kOutBufferDurationMs = 22; using ::android::hardware::Void; PrimaryDevice::PrimaryDevice() {} Return PrimaryDevice::initCheck() { return Result::OK; } Return PrimaryDevice::setMasterVolume(float volume) { if (isnan(volume) || volume < 0 || volume > 1.0) { return FAILURE(Result::INVALID_ARGUMENTS); } mMasterVolume = volume; updateOutputStreamVolume(mMasterMute ? 0.0f : volume); return Result::OK; } Return PrimaryDevice::getMasterVolume(getMasterVolume_cb _hidl_cb) { _hidl_cb(Result::OK, mMasterVolume); return Void(); } Return PrimaryDevice::PrimaryDevice::setMicMute(bool mute) { mMicMute = mute; updateInputStreamMicMute(mute); return Result::OK; } Return PrimaryDevice::getMicMute(getMicMute_cb _hidl_cb) { _hidl_cb(Result::OK, mMicMute); return Void(); } Return PrimaryDevice::setMasterMute(bool mute) { mMasterMute = mute; updateOutputStreamVolume(mute ? 0.0f : mMasterVolume); return Result::OK; } Return PrimaryDevice::getMasterMute(getMasterMute_cb _hidl_cb) { _hidl_cb(Result::OK, mMasterMute); return Void(); } Return PrimaryDevice::getInputBufferSize(const AudioConfig& config, getInputBufferSize_cb _hidl_cb) { AudioConfig suggestedConfig; if (util::checkAudioConfig(false, kInBufferDurationMs, config, suggestedConfig)) { const size_t sz = suggestedConfig.frameCount * util::countChannels(suggestedConfig.channelMask) * util::getBytesPerSample(suggestedConfig.format); _hidl_cb(Result::OK, sz); } else { ALOGE("PrimaryDevice::%s:%d failed", __func__, __LINE__); _hidl_cb(FAILURE(Result::INVALID_ARGUMENTS), 0); } return Void(); } Return PrimaryDevice::openOutputStream(int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, hidl_bitfield flags, const SourceMetadata& sourceMetadata, openOutputStream_cb _hidl_cb) { AudioConfig suggestedConfig; if (util::checkAudioConfig(true, kOutBufferDurationMs, config, suggestedConfig)) { auto stream = std::make_unique( this, ioHandle, device, suggestedConfig, flags, sourceMetadata); stream->setMasterVolume(mMasterMute ? 0.0f : mMasterVolume); { std::lock_guard guard(mMutex); LOG_ALWAYS_FATAL_IF(!mOutputStreams.insert(stream.get()).second); } _hidl_cb(Result::OK, stream.release(), config); } else { ALOGE("PrimaryDevice::%s:%d failed", __func__, __LINE__); _hidl_cb(FAILURE(Result::INVALID_ARGUMENTS), nullptr, suggestedConfig); } return Void(); } Return PrimaryDevice::openInputStream(int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, hidl_bitfield flags, const SinkMetadata& sinkMetadata, openInputStream_cb _hidl_cb) { AudioConfig suggestedConfig; if (util::checkAudioConfig(false, kInBufferDurationMs, config, suggestedConfig)) { auto stream = std::make_unique( this, ioHandle, device, suggestedConfig, flags, sinkMetadata); stream->setMicMute(mMicMute); { std::lock_guard guard(mMutex); LOG_ALWAYS_FATAL_IF(!mInputStreams.insert(stream.get()).second); } _hidl_cb(Result::OK, stream.release(), config); } else { ALOGE("PrimaryDevice::%s:%d failed", __func__, __LINE__); _hidl_cb(FAILURE(Result::INVALID_ARGUMENTS), nullptr, suggestedConfig); } return Void(); } Return PrimaryDevice::supportsAudioPatches() { return true; } Return PrimaryDevice::createAudioPatch(const hidl_vec& sources, const hidl_vec& sinks, createAudioPatch_cb _hidl_cb) { if (sources.size() == 1 && sinks.size() == 1) { AudioPatch patch; patch.source = sources[0]; patch.sink = sinks[0]; AudioPatchHandle handle; while (true) { handle = mNextAudioPatchHandle; mNextAudioPatchHandle = std::max(handle + 1, 0); if (mAudioPatches.insert({handle, patch}).second) { break; } } _hidl_cb(Result::OK, handle); } else { _hidl_cb(FAILURE(Result::NOT_SUPPORTED), 0); } return Void(); } Return PrimaryDevice::releaseAudioPatch(AudioPatchHandle patchHandle) { return (mAudioPatches.erase(patchHandle) == 1) ? Result::OK : FAILURE(Result::INVALID_ARGUMENTS); } Return PrimaryDevice::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) { _hidl_cb(FAILURE(Result::NOT_SUPPORTED), port); return Void(); } Return PrimaryDevice::setAudioPortConfig(const AudioPortConfig& config) { (void)config; return FAILURE(Result::NOT_SUPPORTED); } Return PrimaryDevice::setScreenState(bool turnedOn) { (void)turnedOn; return Result::OK; } Return PrimaryDevice::getHwAvSync(getHwAvSync_cb _hidl_cb) { _hidl_cb(FAILURE(Result::NOT_SUPPORTED), {}); return Void(); } Return PrimaryDevice::getParameters(const hidl_vec& context, const hidl_vec& keys, getParameters_cb _hidl_cb) { (void)context; if (keys.size() == 0) { _hidl_cb(Result::OK, {}); } else { _hidl_cb(FAILURE(Result::NOT_SUPPORTED), {}); } return Void(); } Return PrimaryDevice::setParameters(const hidl_vec& context, const hidl_vec& parameters) { (void)context; (void)parameters; return Result::OK; } Return PrimaryDevice::getMicrophones(getMicrophones_cb _hidl_cb) { _hidl_cb(Result::OK, {util::getMicrophoneInfo()}); return Void(); } Return PrimaryDevice::setConnectedState(const DeviceAddress& dev_addr, bool connected) { (void)dev_addr; (void)connected; return FAILURE(Result::NOT_SUPPORTED); } Return PrimaryDevice::close() { std::lock_guard guard(mMutex); return (mInputStreams.empty() && mOutputStreams.empty()) ? Result::OK : FAILURE(Result::INVALID_STATE); } Return PrimaryDevice::addDeviceEffect(AudioPortHandle device, uint64_t effectId) { (void)device; (void)effectId; return FAILURE(Result::NOT_SUPPORTED); } Return PrimaryDevice::removeDeviceEffect(AudioPortHandle device, uint64_t effectId) { (void)device; (void)effectId; return FAILURE(Result::NOT_SUPPORTED); } Return PrimaryDevice::setVoiceVolume(float volume) { return (volume >= 0 && volume <= 1.0) ? Result::OK : FAILURE(Result::INVALID_ARGUMENTS); } Return PrimaryDevice::setMode(AudioMode mode) { switch (mode) { case AudioMode::NORMAL: case AudioMode::RINGTONE: case AudioMode::IN_CALL: case AudioMode::IN_COMMUNICATION: return Result::OK; default: return FAILURE(Result::INVALID_ARGUMENTS); } } Return PrimaryDevice::setBtScoHeadsetDebugName(const hidl_string& name) { (void)name; return FAILURE(Result::NOT_SUPPORTED); } Return PrimaryDevice::getBtScoNrecEnabled(getBtScoNrecEnabled_cb _hidl_cb) { _hidl_cb(FAILURE(Result::NOT_SUPPORTED), false); return Void(); } Return PrimaryDevice::setBtScoNrecEnabled(bool enabled) { (void)enabled; return FAILURE(Result::NOT_SUPPORTED); } Return PrimaryDevice::getBtScoWidebandEnabled(getBtScoWidebandEnabled_cb _hidl_cb) { _hidl_cb(FAILURE(Result::NOT_SUPPORTED), false); return Void(); } Return PrimaryDevice::setBtScoWidebandEnabled(bool enabled) { (void)enabled; return FAILURE(Result::NOT_SUPPORTED); } Return PrimaryDevice::getTtyMode(getTtyMode_cb _hidl_cb) { _hidl_cb(FAILURE(Result::NOT_SUPPORTED), TtyMode::OFF); return Void(); } Return PrimaryDevice::setTtyMode(IPrimaryDevice::TtyMode mode) { (void)mode; return FAILURE(Result::NOT_SUPPORTED); } Return PrimaryDevice::getHacEnabled(getHacEnabled_cb _hidl_cb) { _hidl_cb(FAILURE(Result::NOT_SUPPORTED), false); return Void(); } Return PrimaryDevice::setHacEnabled(bool enabled) { (void)enabled; return FAILURE(Result::NOT_SUPPORTED); } Return PrimaryDevice::getBtHfpEnabled(getBtHfpEnabled_cb _hidl_cb) { _hidl_cb(FAILURE(Result::NOT_SUPPORTED), false); return Void(); } Return PrimaryDevice::setBtHfpEnabled(bool enabled) { (void)enabled; return FAILURE(Result::NOT_SUPPORTED); } Return PrimaryDevice::setBtHfpSampleRate(uint32_t sampleRateHz) { (void)sampleRateHz; return FAILURE(Result::NOT_SUPPORTED); } Return PrimaryDevice::setBtHfpVolume(float volume) { (void)volume; return FAILURE(Result::NOT_SUPPORTED); } Return PrimaryDevice::updateRotation(IPrimaryDevice::Rotation rotation) { (void)rotation; return FAILURE(Result::NOT_SUPPORTED); } void PrimaryDevice::unrefDevice(StreamIn *sin) { std::lock_guard guard(mMutex); LOG_ALWAYS_FATAL_IF(mInputStreams.erase(sin) < 1); } void PrimaryDevice::unrefDevice(StreamOut *sout) { std::lock_guard guard(mMutex); LOG_ALWAYS_FATAL_IF(mOutputStreams.erase(sout) < 1); } void PrimaryDevice::updateOutputStreamVolume(float masterVolume) const { std::lock_guard guard(mMutex); for (StreamOut *stream : mOutputStreams) { stream->setMasterVolume(masterVolume); } } void PrimaryDevice::updateInputStreamMicMute(bool micMute) const { std::lock_guard guard(mMutex); for (StreamIn *stream : mInputStreams) { stream->setMicMute(micMute); } } } // namespace implementation } // namespace V6_0 } // namespace audio } // namespace hardware } // namespace android