You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
392 lines
12 KiB
392 lines
12 KiB
/*
|
|
* 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
|