blob: 3ba4bf8f0211c54d87a2b0c023c5b7e4b22f8008 [file] [log] [blame]
/*
* 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 <log/log.h>
#include <system/audio.h>
#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<Result> PrimaryDevice::initCheck() {
return Result::OK;
}
Return<Result> 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<void> PrimaryDevice::getMasterVolume(getMasterVolume_cb _hidl_cb) {
_hidl_cb(Result::OK, mMasterVolume);
return Void();
}
Return<Result> PrimaryDevice::PrimaryDevice::setMicMute(bool mute) {
mMicMute = mute;
updateInputStreamMicMute(mute);
return Result::OK;
}
Return<void> PrimaryDevice::getMicMute(getMicMute_cb _hidl_cb) {
_hidl_cb(Result::OK, mMicMute);
return Void();
}
Return<Result> PrimaryDevice::setMasterMute(bool mute) {
mMasterMute = mute;
updateOutputStreamVolume(mute ? 0.0f : mMasterVolume);
return Result::OK;
}
Return<void> PrimaryDevice::getMasterMute(getMasterMute_cb _hidl_cb) {
_hidl_cb(Result::OK, mMasterMute);
return Void();
}
Return<void> 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<void> PrimaryDevice::openOutputStream(int32_t ioHandle,
const DeviceAddress& device,
const AudioConfig& config,
hidl_bitfield<AudioOutputFlag> flags,
const SourceMetadata& sourceMetadata,
openOutputStream_cb _hidl_cb) {
AudioConfig suggestedConfig;
if (util::checkAudioConfig(true, kOutBufferDurationMs, config, suggestedConfig)) {
auto stream = std::make_unique<StreamOut>(
this, ioHandle, device, suggestedConfig, flags, sourceMetadata);
stream->setMasterVolume(mMasterMute ? 0.0f : mMasterVolume);
{
std::lock_guard<std::mutex> 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<void> PrimaryDevice::openInputStream(int32_t ioHandle,
const DeviceAddress& device,
const AudioConfig& config,
hidl_bitfield<AudioInputFlag> flags,
const SinkMetadata& sinkMetadata,
openInputStream_cb _hidl_cb) {
AudioConfig suggestedConfig;
if (util::checkAudioConfig(false, kInBufferDurationMs, config, suggestedConfig)) {
auto stream = std::make_unique<StreamIn>(
this, ioHandle, device, suggestedConfig, flags, sinkMetadata);
stream->setMicMute(mMicMute);
{
std::lock_guard<std::mutex> 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<bool> PrimaryDevice::supportsAudioPatches() {
return true;
}
Return<void> PrimaryDevice::createAudioPatch(const hidl_vec<AudioPortConfig>& sources,
const hidl_vec<AudioPortConfig>& 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<void> PrimaryDevice::updateAudioPatch(AudioPatchHandle previousPatchHandle,
const hidl_vec<AudioPortConfig>& sources,
const hidl_vec<AudioPortConfig>& sinks,
updateAudioPatch_cb _hidl_cb) {
const auto i = mAudioPatches.find(previousPatchHandle);
if (i == mAudioPatches.end()) {
_hidl_cb(FAILURE(Result::INVALID_ARGUMENTS), previousPatchHandle);
} else {
if (sources.size() == 1 && sinks.size() == 1) {
AudioPatch patch;
patch.source = sources[0];
patch.sink = sinks[0];
i->second = patch;
_hidl_cb(Result::OK, previousPatchHandle);
} else {
_hidl_cb(Result::NOT_SUPPORTED, previousPatchHandle);
}
}
return Void();
}
Return<Result> PrimaryDevice::releaseAudioPatch(AudioPatchHandle patchHandle) {
return (mAudioPatches.erase(patchHandle) == 1) ? Result::OK : FAILURE(Result::INVALID_ARGUMENTS);
}
Return<void> PrimaryDevice::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) {
_hidl_cb(FAILURE(Result::NOT_SUPPORTED), port);
return Void();
}
Return<Result> PrimaryDevice::setAudioPortConfig(const AudioPortConfig& config) {
(void)config;
return FAILURE(Result::NOT_SUPPORTED);
}
Return<Result> PrimaryDevice::setScreenState(bool turnedOn) {
(void)turnedOn;
return Result::OK;
}
Return<void> PrimaryDevice::getHwAvSync(getHwAvSync_cb _hidl_cb) {
_hidl_cb(FAILURE(Result::NOT_SUPPORTED), {});
return Void();
}
Return<void> PrimaryDevice::getParameters(const hidl_vec<ParameterValue>& context,
const hidl_vec<hidl_string>& 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<Result> PrimaryDevice::setParameters(const hidl_vec<ParameterValue>& context,
const hidl_vec<ParameterValue>& parameters) {
(void)context;
(void)parameters;
return Result::OK;
}
Return<void> PrimaryDevice::getMicrophones(getMicrophones_cb _hidl_cb) {
_hidl_cb(Result::OK, {util::getMicrophoneInfo()});
return Void();
}
Return<Result> PrimaryDevice::setConnectedState(const DeviceAddress& dev_addr, bool connected) {
(void)dev_addr;
(void)connected;
return FAILURE(Result::NOT_SUPPORTED);
}
Return<Result> PrimaryDevice::close() {
std::lock_guard<std::mutex> guard(mMutex);
return (mInputStreams.empty() && mOutputStreams.empty())
? Result::OK : FAILURE(Result::INVALID_STATE);
}
Return<Result> PrimaryDevice::addDeviceEffect(AudioPortHandle device, uint64_t effectId) {
(void)device;
(void)effectId;
return FAILURE(Result::NOT_SUPPORTED);
}
Return<Result> PrimaryDevice::removeDeviceEffect(AudioPortHandle device, uint64_t effectId) {
(void)device;
(void)effectId;
return FAILURE(Result::NOT_SUPPORTED);
}
Return<Result> PrimaryDevice::setVoiceVolume(float volume) {
return (volume >= 0 && volume <= 1.0) ? Result::OK : FAILURE(Result::INVALID_ARGUMENTS);
}
Return<Result> 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<Result> PrimaryDevice::setBtScoHeadsetDebugName(const hidl_string& name) {
(void)name;
return FAILURE(Result::NOT_SUPPORTED);
}
Return<void> PrimaryDevice::getBtScoNrecEnabled(getBtScoNrecEnabled_cb _hidl_cb) {
_hidl_cb(FAILURE(Result::NOT_SUPPORTED), false);
return Void();
}
Return<Result> PrimaryDevice::setBtScoNrecEnabled(bool enabled) {
(void)enabled;
return FAILURE(Result::NOT_SUPPORTED);
}
Return<void> PrimaryDevice::getBtScoWidebandEnabled(getBtScoWidebandEnabled_cb _hidl_cb) {
_hidl_cb(FAILURE(Result::NOT_SUPPORTED), false);
return Void();
}
Return<Result> PrimaryDevice::setBtScoWidebandEnabled(bool enabled) {
(void)enabled;
return FAILURE(Result::NOT_SUPPORTED);
}
Return<void> PrimaryDevice::getTtyMode(getTtyMode_cb _hidl_cb) {
_hidl_cb(FAILURE(Result::NOT_SUPPORTED), TtyMode::OFF);
return Void();
}
Return<Result> PrimaryDevice::setTtyMode(IPrimaryDevice::TtyMode mode) {
(void)mode;
return FAILURE(Result::NOT_SUPPORTED);
}
Return<void> PrimaryDevice::getHacEnabled(getHacEnabled_cb _hidl_cb) {
_hidl_cb(FAILURE(Result::NOT_SUPPORTED), false);
return Void();
}
Return<Result> PrimaryDevice::setHacEnabled(bool enabled) {
(void)enabled;
return FAILURE(Result::NOT_SUPPORTED);
}
Return<void> PrimaryDevice::getBtHfpEnabled(getBtHfpEnabled_cb _hidl_cb) {
_hidl_cb(FAILURE(Result::NOT_SUPPORTED), false);
return Void();
}
Return<Result> PrimaryDevice::setBtHfpEnabled(bool enabled) {
(void)enabled;
return FAILURE(Result::NOT_SUPPORTED);
}
Return<Result> PrimaryDevice::setBtHfpSampleRate(uint32_t sampleRateHz) {
(void)sampleRateHz;
return FAILURE(Result::NOT_SUPPORTED);
}
Return<Result> PrimaryDevice::setBtHfpVolume(float volume) {
(void)volume;
return FAILURE(Result::NOT_SUPPORTED);
}
Return<Result> PrimaryDevice::updateRotation(IPrimaryDevice::Rotation rotation) {
(void)rotation;
return FAILURE(Result::NOT_SUPPORTED);
}
void PrimaryDevice::unrefDevice(StreamIn *sin) {
std::lock_guard<std::mutex> guard(mMutex);
LOG_ALWAYS_FATAL_IF(mInputStreams.erase(sin) < 1);
}
void PrimaryDevice::unrefDevice(StreamOut *sout) {
std::lock_guard<std::mutex> guard(mMutex);
LOG_ALWAYS_FATAL_IF(mOutputStreams.erase(sout) < 1);
}
void PrimaryDevice::updateOutputStreamVolume(float masterVolume) const {
std::lock_guard<std::mutex> guard(mMutex);
for (StreamOut *stream : mOutputStreams) {
stream->setMasterVolume(masterVolume);
}
}
void PrimaryDevice::updateInputStreamMicMute(bool micMute) const {
std::lock_guard<std::mutex> guard(mMutex);
for (StreamIn *stream : mInputStreams) {
stream->setMicMute(micMute);
}
}
} // namespace implementation
} // namespace V6_0
} // namespace audio
} // namespace hardware
} // namespace android