7d6df38051
* hardware/interfaces/audio/aidl/default/ at android-16.0.0_r1.
282 lines
15 KiB
C++
282 lines
15 KiB
C++
/*
|
|
* Copyright (C) 2022 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.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <functional>
|
|
#include <iostream>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <set>
|
|
|
|
#include <Utils.h>
|
|
#include <aidl/android/hardware/audio/core/BnModule.h>
|
|
|
|
#include "core-impl/ChildInterface.h"
|
|
#include "core-impl/Stream.h"
|
|
|
|
namespace aidl::android::hardware::audio::core {
|
|
|
|
class Module : public BnModule {
|
|
public:
|
|
struct Configuration {
|
|
std::vector<::aidl::android::media::audio::common::AudioPort> ports;
|
|
std::vector<::aidl::android::media::audio::common::AudioPortConfig> portConfigs;
|
|
std::vector<::aidl::android::media::audio::common::AudioPortConfig> initialConfigs;
|
|
// Port id -> List of profiles to use when the device port state is set to 'connected'
|
|
// in connection simulation mode.
|
|
std::map<int32_t, std::vector<::aidl::android::media::audio::common::AudioProfile>>
|
|
connectedProfiles;
|
|
std::vector<AudioRoute> routes;
|
|
std::vector<AudioPatch> patches;
|
|
int32_t nextPortId = 1;
|
|
int32_t nextPatchId = 1;
|
|
};
|
|
enum Type : int { DEFAULT, R_SUBMIX, STUB, USB, BLUETOOTH };
|
|
|
|
static std::shared_ptr<Module> createInstance(Type type) {
|
|
return createInstance(type, std::make_unique<Configuration>());
|
|
}
|
|
static std::shared_ptr<Module> createInstance(Type type,
|
|
std::unique_ptr<Configuration>&& config);
|
|
static std::optional<Type> typeFromString(const std::string& type);
|
|
|
|
Module(Type type, std::unique_ptr<Configuration>&& config);
|
|
|
|
protected:
|
|
// The vendor extension done via inheritance can override interface methods and augment
|
|
// a call to the base implementation.
|
|
|
|
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
|
|
|
|
ndk::ScopedAStatus setModuleDebug(
|
|
const ::aidl::android::hardware::audio::core::ModuleDebug& in_debug) override;
|
|
ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override;
|
|
ndk::ScopedAStatus getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) override;
|
|
ndk::ScopedAStatus getBluetoothA2dp(std::shared_ptr<IBluetoothA2dp>* _aidl_return) override;
|
|
ndk::ScopedAStatus getBluetoothLe(std::shared_ptr<IBluetoothLe>* _aidl_return) override;
|
|
ndk::ScopedAStatus connectExternalDevice(
|
|
const ::aidl::android::media::audio::common::AudioPort& in_templateIdAndAdditionalData,
|
|
::aidl::android::media::audio::common::AudioPort* _aidl_return) override;
|
|
ndk::ScopedAStatus disconnectExternalDevice(int32_t in_portId) override;
|
|
ndk::ScopedAStatus prepareToDisconnectExternalDevice(int32_t in_portId) override;
|
|
ndk::ScopedAStatus getAudioPatches(std::vector<AudioPatch>* _aidl_return) override;
|
|
ndk::ScopedAStatus getAudioPort(
|
|
int32_t in_portId,
|
|
::aidl::android::media::audio::common::AudioPort* _aidl_return) override;
|
|
ndk::ScopedAStatus getAudioPortConfigs(
|
|
std::vector<::aidl::android::media::audio::common::AudioPortConfig>* _aidl_return)
|
|
override;
|
|
ndk::ScopedAStatus getAudioPorts(
|
|
std::vector<::aidl::android::media::audio::common::AudioPort>* _aidl_return) override;
|
|
ndk::ScopedAStatus getAudioRoutes(std::vector<AudioRoute>* _aidl_return) override;
|
|
ndk::ScopedAStatus getAudioRoutesForAudioPort(
|
|
int32_t in_portId,
|
|
std::vector<::aidl::android::hardware::audio::core::AudioRoute>* _aidl_return) override;
|
|
ndk::ScopedAStatus openInputStream(
|
|
const ::aidl::android::hardware::audio::core::IModule::OpenInputStreamArguments&
|
|
in_args,
|
|
::aidl::android::hardware::audio::core::IModule::OpenInputStreamReturn* _aidl_return)
|
|
override;
|
|
ndk::ScopedAStatus openOutputStream(
|
|
const ::aidl::android::hardware::audio::core::IModule::OpenOutputStreamArguments&
|
|
in_args,
|
|
::aidl::android::hardware::audio::core::IModule::OpenOutputStreamReturn* _aidl_return)
|
|
override;
|
|
ndk::ScopedAStatus getSupportedPlaybackRateFactors(
|
|
SupportedPlaybackRateFactors* _aidl_return) override;
|
|
ndk::ScopedAStatus setAudioPatch(const AudioPatch& in_requested,
|
|
AudioPatch* _aidl_return) override;
|
|
ndk::ScopedAStatus setAudioPortConfig(
|
|
const ::aidl::android::media::audio::common::AudioPortConfig& in_requested,
|
|
::aidl::android::media::audio::common::AudioPortConfig* out_suggested,
|
|
bool* _aidl_return) override;
|
|
ndk::ScopedAStatus resetAudioPatch(int32_t in_patchId) override;
|
|
ndk::ScopedAStatus resetAudioPortConfig(int32_t in_portConfigId) override;
|
|
ndk::ScopedAStatus getMasterMute(bool* _aidl_return) override;
|
|
ndk::ScopedAStatus setMasterMute(bool in_mute) override;
|
|
ndk::ScopedAStatus getMasterVolume(float* _aidl_return) override;
|
|
ndk::ScopedAStatus setMasterVolume(float in_volume) override;
|
|
ndk::ScopedAStatus getMicMute(bool* _aidl_return) override;
|
|
ndk::ScopedAStatus setMicMute(bool in_mute) override;
|
|
ndk::ScopedAStatus getMicrophones(
|
|
std::vector<::aidl::android::media::audio::common::MicrophoneInfo>* _aidl_return)
|
|
override;
|
|
ndk::ScopedAStatus updateAudioMode(
|
|
::aidl::android::media::audio::common::AudioMode in_mode) override;
|
|
ndk::ScopedAStatus updateScreenRotation(
|
|
::aidl::android::hardware::audio::core::IModule::ScreenRotation in_rotation) override;
|
|
ndk::ScopedAStatus updateScreenState(bool in_isTurnedOn) override;
|
|
ndk::ScopedAStatus getSoundDose(std::shared_ptr<sounddose::ISoundDose>* _aidl_return) override;
|
|
ndk::ScopedAStatus generateHwAvSyncId(int32_t* _aidl_return) override;
|
|
ndk::ScopedAStatus getVendorParameters(const std::vector<std::string>& in_ids,
|
|
std::vector<VendorParameter>* _aidl_return) override;
|
|
ndk::ScopedAStatus setVendorParameters(const std::vector<VendorParameter>& in_parameters,
|
|
bool in_async) override;
|
|
ndk::ScopedAStatus addDeviceEffect(
|
|
int32_t in_portConfigId,
|
|
const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect)
|
|
override;
|
|
ndk::ScopedAStatus removeDeviceEffect(
|
|
int32_t in_portConfigId,
|
|
const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect)
|
|
override;
|
|
ndk::ScopedAStatus getMmapPolicyInfos(
|
|
::aidl::android::media::audio::common::AudioMMapPolicyType mmapPolicyType,
|
|
std::vector<::aidl::android::media::audio::common::AudioMMapPolicyInfo>* _aidl_return)
|
|
override;
|
|
ndk::ScopedAStatus supportsVariableLatency(bool* _aidl_return) override;
|
|
ndk::ScopedAStatus getAAudioMixerBurstCount(int32_t* _aidl_return) override;
|
|
ndk::ScopedAStatus getAAudioHardwareBurstMinUsec(int32_t* _aidl_return) override;
|
|
|
|
// The maximum stream buffer size is 1 GiB = 2 ** 30 bytes;
|
|
static constexpr int32_t kMaximumStreamBufferSizeBytes = 1 << 30;
|
|
|
|
private:
|
|
struct VendorDebug {
|
|
static const std::string kForceTransientBurstName;
|
|
static const std::string kForceSynchronousDrainName;
|
|
bool forceTransientBurst = false;
|
|
bool forceSynchronousDrain = false;
|
|
};
|
|
// ids of device ports created at runtime via 'connectExternalDevice'.
|
|
// Also stores a list of ids of mix ports with dynamic profiles that were populated from
|
|
// the connected port. This list can be empty, thus an int->int multimap can't be used.
|
|
using ConnectedDevicePorts = std::map<int32_t, std::set<int32_t>>;
|
|
// Maps port ids and port config ids to patch ids.
|
|
// Multimap because both ports and configs can be used by multiple patches.
|
|
using Patches = std::multimap<int32_t, int32_t>;
|
|
|
|
static const std::string kClipTransitionSupportName;
|
|
const Type mType;
|
|
std::unique_ptr<Configuration> mConfig;
|
|
ModuleDebug mDebug;
|
|
VendorDebug mVendorDebug;
|
|
ConnectedDevicePorts mConnectedDevicePorts;
|
|
Streams mStreams;
|
|
Patches mPatches;
|
|
bool mMicMute = false;
|
|
bool mMasterMute = false;
|
|
float mMasterVolume = 1.0f;
|
|
ChildInterface<sounddose::SoundDose> mSoundDose;
|
|
std::optional<bool> mIsMmapSupported;
|
|
|
|
protected:
|
|
// The following virtual functions are intended for vendor extension via inheritance.
|
|
|
|
virtual ndk::ScopedAStatus createInputStream(
|
|
StreamContext&& context,
|
|
const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
|
|
const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones,
|
|
std::shared_ptr<StreamIn>* result) = 0;
|
|
virtual ndk::ScopedAStatus createOutputStream(
|
|
StreamContext&& context,
|
|
const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
|
|
const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
|
|
offloadInfo,
|
|
std::shared_ptr<StreamOut>* result) = 0;
|
|
// If the module is unable to populate the connected device port correctly, the returned error
|
|
// code must correspond to the errors of `IModule.connectedExternalDevice` method.
|
|
virtual ndk::ScopedAStatus populateConnectedDevicePort(
|
|
::aidl::android::media::audio::common::AudioPort* audioPort, int32_t nextPortId);
|
|
// If the module finds that the patch endpoints configurations are not matched, the returned
|
|
// error code must correspond to the errors of `IModule.setAudioPatch` method.
|
|
virtual ndk::ScopedAStatus checkAudioPatchEndpointsMatch(
|
|
const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources,
|
|
const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks);
|
|
virtual void onExternalDeviceConnectionChanged(
|
|
const ::aidl::android::media::audio::common::AudioPort& audioPort, bool connected);
|
|
virtual void onPrepareToDisconnectExternalDevice(
|
|
const ::aidl::android::media::audio::common::AudioPort& audioPort);
|
|
virtual ndk::ScopedAStatus onMasterMuteChanged(bool mute);
|
|
virtual ndk::ScopedAStatus onMasterVolumeChanged(float volume);
|
|
virtual std::vector<::aidl::android::media::audio::common::MicrophoneInfo> getMicrophoneInfos();
|
|
virtual std::unique_ptr<Configuration> initializeConfig();
|
|
virtual int32_t getNominalLatencyMs(
|
|
const ::aidl::android::media::audio::common::AudioPortConfig& portConfig);
|
|
virtual ndk::ScopedAStatus calculateBufferSizeFrames(
|
|
const ::aidl::android::media::audio::common::AudioFormatDescription &format,
|
|
int32_t latencyMs, int32_t sampleRateHz, int32_t *bufferSizeFrames);
|
|
virtual ndk::ScopedAStatus createMmapBuffer(
|
|
const ::aidl::android::media::audio::common::AudioPortConfig& portConfig,
|
|
int32_t bufferSizeFrames, int32_t frameSizeBytes, MmapBufferDescriptor* desc);
|
|
|
|
// Utility and helper functions accessible to subclasses.
|
|
static int32_t calculateBufferSizeFramesForPcm(int32_t latencyMs, int32_t sampleRateHz) {
|
|
const int32_t rawSizeFrames =
|
|
aidl::android::hardware::audio::common::frameCountFromDurationMs(latencyMs,
|
|
sampleRateHz);
|
|
// Round up to nearest 16 frames since in the framework this is the size of a mixer burst.
|
|
const int32_t multipleOf16 = (rawSizeFrames + 15) & ~15;
|
|
if (sampleRateHz < 44100 || multipleOf16 <= 512) return multipleOf16;
|
|
// Larger buffers should use powers of 2.
|
|
int32_t powerOf2 = 1;
|
|
while (powerOf2 < multipleOf16) powerOf2 <<= 1;
|
|
return powerOf2;
|
|
}
|
|
|
|
ndk::ScopedAStatus bluetoothParametersUpdated();
|
|
void cleanUpPatch(int32_t patchId);
|
|
ndk::ScopedAStatus createStreamContext(
|
|
int32_t in_portConfigId, int64_t in_bufferSizeFrames,
|
|
std::shared_ptr<IStreamCallback> asyncCallback,
|
|
std::shared_ptr<IStreamOutEventCallback> outEventCallback,
|
|
::aidl::android::hardware::audio::core::StreamContext* out_context);
|
|
std::vector<::aidl::android::media::audio::common::AudioDevice> findConnectedDevices(
|
|
int32_t portConfigId);
|
|
std::set<int32_t> findConnectedPortConfigIds(int32_t portConfigId);
|
|
ndk::ScopedAStatus findPortIdForNewStream(
|
|
int32_t in_portConfigId, ::aidl::android::media::audio::common::AudioPort** port);
|
|
// Note: does not assign an ID to the config.
|
|
bool generateDefaultPortConfig(const ::aidl::android::media::audio::common::AudioPort& port,
|
|
::aidl::android::media::audio::common::AudioPortConfig* config);
|
|
std::vector<AudioRoute*> getAudioRoutesForAudioPortImpl(int32_t portId);
|
|
Configuration& getConfig();
|
|
const ConnectedDevicePorts& getConnectedDevicePorts() const { return mConnectedDevicePorts; }
|
|
std::vector<::aidl::android::media::audio::common::AudioDevice>
|
|
getDevicesFromDevicePortConfigIds(const std::set<int32_t>& devicePortConfigIds);
|
|
bool getMasterMute() const { return mMasterMute; }
|
|
bool getMasterVolume() const { return mMasterVolume; }
|
|
bool getMicMute() const { return mMicMute; }
|
|
const ModuleDebug& getModuleDebug() const { return mDebug; }
|
|
const Patches& getPatches() const { return mPatches; }
|
|
std::set<int32_t> getRoutableAudioPortIds(int32_t portId,
|
|
std::vector<AudioRoute*>* routes = nullptr);
|
|
const Streams& getStreams() const { return mStreams; }
|
|
Type getType() const { return mType; }
|
|
bool isMmapSupported();
|
|
void populateConnectedProfiles();
|
|
template <typename C>
|
|
std::set<int32_t> portIdsFromPortConfigIds(C portConfigIds);
|
|
void registerPatch(const AudioPatch& patch);
|
|
ndk::ScopedAStatus setAudioPortConfigImpl(
|
|
const ::aidl::android::media::audio::common::AudioPortConfig& in_requested,
|
|
const std::function<bool(const ::aidl::android::media::audio::common::AudioPort& port,
|
|
::aidl::android::media::audio::common::AudioPortConfig*
|
|
config)>& fillPortConfig,
|
|
::aidl::android::media::audio::common::AudioPortConfig* out_suggested, bool* applied);
|
|
ndk::ScopedAStatus updateStreamsConnectedState(const AudioPatch& oldPatch,
|
|
const AudioPatch& newPatch);
|
|
bool setAudioPortConfigGain(
|
|
const ::aidl::android::media::audio::common::AudioPort& port,
|
|
const ::aidl::android::media::audio::common::AudioGainConfig& gainRequested);
|
|
};
|
|
|
|
std::ostream& operator<<(std::ostream& os, Module::Type t);
|
|
|
|
} // namespace aidl::android::hardware::audio::core
|