/* * Copyright (C) 2015 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 "DeviceDescriptor.h" #include "AudioRoute.h" #include #include #include #include #include #include #include namespace android { class IOProfile; class InputProfile; class OutputProfile; typedef Vector > InputProfileCollection; typedef Vector > OutputProfileCollection; typedef Vector > IOProfileCollection; class HwModule : public RefBase { public: explicit HwModule(const char *name, uint32_t halVersionMajor = 0, uint32_t halVersionMinor = 0); ~HwModule(); const char *getName() const { return mName.string(); } const DeviceVector &getDeclaredDevices() const { return mDeclaredDevices; } void setDeclaredDevices(const DeviceVector &devices); DeviceVector getAllDevices() const { DeviceVector devices = mDeclaredDevices; devices.merge(mDynamicDevices); return devices; } std::string getTagForDevice(audio_devices_t device, const String8 &address = String8(), audio_format_t codec = AUDIO_FORMAT_DEFAULT); void addDynamicDevice(const sp &device) { device->setDynamic(); mDynamicDevices.add(device); } bool removeDynamicDevice(const sp &device) { return mDynamicDevices.remove(device) >= 0; } DeviceVector getDynamicDevices() const { return mDynamicDevices; } const InputProfileCollection &getInputProfiles() const { return mInputProfiles; } const OutputProfileCollection &getOutputProfiles() const { return mOutputProfiles; } void setProfiles(const IOProfileCollection &profiles); void setHalVersion(uint32_t major, uint32_t minor) { mHalVersion = (major << 8) | (minor & 0xff); } uint32_t getHalVersionMajor() const { return mHalVersion >> 8; } uint32_t getHalVersionMinor() const { return mHalVersion & 0xff; } sp getRouteSinkDevice(const sp &route) const; DeviceVector getRouteSourceDevices(const sp &route) const; void setRoutes(const AudioRouteVector &routes); status_t addOutputProfile(const sp &profile); status_t addInputProfile(const sp &profile); status_t addProfile(const sp &profile); status_t addOutputProfile(const std::string& name, const audio_config_t *config, audio_devices_t device, const String8& address); status_t removeOutputProfile(const std::string& name); status_t addInputProfile(const std::string& name, const audio_config_t *config, audio_devices_t device, const String8& address); status_t removeInputProfile(const std::string& name); audio_module_handle_t getHandle() const { return mHandle; } void setHandle(audio_module_handle_t handle); sp findPortByTagName(const std::string &tagName) const { return findByTagName(mPorts, tagName); } /** * @brief supportsPatch checks if an audio patch between 2 ports beloging to this HwModule * is supported by a HwModule. The ports and the route shall be declared in the * audio_policy_configuration.xml file. * @param srcPort (aka the source) to be considered * @param dstPort (aka the sink) to be considered * @return true if the HwModule supports the connection between the sink and the source, * false otherwise */ bool supportsPatch(const sp &srcPort, const sp &dstPort) const; // TODO remove from here (split serialization) void dump(String8 *dst) const; private: void refreshSupportedDevices(); const String8 mName; // base name of the audio HW module (primary, a2dp ...) audio_module_handle_t mHandle; OutputProfileCollection mOutputProfiles; // output profiles exposed by this module InputProfileCollection mInputProfiles; // input profiles exposed by this module uint32_t mHalVersion; // audio HAL API version DeviceVector mDeclaredDevices; // devices declared in audio_policy configuration file. DeviceVector mDynamicDevices; /**< devices that can be added/removed at runtime (e.g. rsbumix)*/ AudioRouteVector mRoutes; PolicyAudioPortVector mPorts; }; class HwModuleCollection : public Vector > { public: sp getModuleFromName(const char *name) const; /** * @brief getModuleForDeviceType try to get a device from type / format on all modules * @param device type to consider * @param encodedFormat to consider * @param[out] tagName if not null, if a matching device is found, will return the tagName * of original device from XML file so that audio routes matchin rules work. * @return valid module if considered device found, nullptr otherwise. */ sp getModuleForDeviceType(audio_devices_t device, audio_format_t encodedFormat, std::string *tagName = nullptr) const; sp getModuleForDevice(const sp &device, audio_format_t encodedFormat) const; DeviceVector getAvailableDevicesFromModuleName(const char *name, const DeviceVector &availableDevices) const; /** * @brief getDeviceDescriptor returns a device descriptor associated to the device type and * device address (if matchAddress is true). * It may loop twice on all modules to check if allowToCreate is true * -first loop will check if the device is found on a module since declared in the list * of device port in configuration file * -(allowToCreate is true)second loop will check if the device is weakly supported by one * or more profiles on a given module and will add as a supported device for this module. * The device will also be added to the dynamic list of device of this module * @param type of the device requested * @param address of the device requested * @param name of the device that requested * @param encodedFormat if not AUDIO_FORMAT_DEFAULT, must match one supported format * @param matchAddress true if a strong match is required * @param allowToCreate true if allowed to create dynamic device (e.g. hdmi, usb...) * @return device descriptor associated to the type (and address if matchAddress is true) */ sp getDeviceDescriptor(const audio_devices_t type, const char *address, const char *name, audio_format_t encodedFormat, bool allowToCreate = false, bool matchAddress = true) const; /** * @brief createDevice creates a new device from the type and address given. It checks that * according to the device type, a module is supporting this device (weak check). * This concerns only dynamic device, aka device with a specific address and not * already supported by module/underlying profiles. * @param type of the device to be created * @param address of the device to be created * @param name of the device to be created * @return device descriptor if a module is supporting this type, nullptr otherwise. */ sp createDevice(const audio_devices_t type, const char *address, const char *name, const audio_format_t encodedFormat) const; /** * @brief cleanUpForDevice: loop on all profiles of all modules to remove device from * the list of supported device. If this device is a dynamic device (aka a device not in the * xml file with a runtime address), it is also removed from the module collection of dynamic * devices. * @param device that has been disconnected */ void cleanUpForDevice(const sp &device); void dump(String8 *dst) const; }; } // namespace android