1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include "DeviceDescriptor.h"
20 #include "AudioRoute.h"
21 #include <utils/RefBase.h>
22 #include <utils/String8.h>
23 #include <utils/Errors.h>
24 #include <utils/Vector.h>
25 #include <system/audio.h>
26 #include <cutils/config_utils.h>
27 #include <string>
28 
29 namespace android {
30 
31 class IOProfile;
32 class InputProfile;
33 class OutputProfile;
34 
35 typedef Vector<sp<IOProfile> > InputProfileCollection;
36 typedef Vector<sp<IOProfile> > OutputProfileCollection;
37 typedef Vector<sp<IOProfile> > IOProfileCollection;
38 
39 class HwModule : public RefBase
40 {
41 public:
42     explicit HwModule(const char *name, uint32_t halVersionMajor = 0, uint32_t halVersionMinor = 0);
43     ~HwModule();
44 
getName()45     const char *getName() const { return mName.string(); }
46 
getDeclaredDevices()47     const DeviceVector &getDeclaredDevices() const { return mDeclaredDevices; }
48     void setDeclaredDevices(const DeviceVector &devices);
getAllDevices()49     DeviceVector getAllDevices() const
50     {
51         DeviceVector devices = mDeclaredDevices;
52         devices.merge(mDynamicDevices);
53         return devices;
54     }
addDynamicDevice(const sp<DeviceDescriptor> & device)55     void addDynamicDevice(const sp<DeviceDescriptor> &device)
56     {
57         mDynamicDevices.add(device);
58     }
59 
removeDynamicDevice(const sp<DeviceDescriptor> & device)60     bool removeDynamicDevice(const sp<DeviceDescriptor> &device)
61     {
62         return mDynamicDevices.remove(device) >= 0;
63     }
getDynamicDevices()64     DeviceVector getDynamicDevices() const { return mDynamicDevices; }
65 
getInputProfiles()66     const InputProfileCollection &getInputProfiles() const { return mInputProfiles; }
getOutputProfiles()67     const OutputProfileCollection &getOutputProfiles() const { return mOutputProfiles; }
68 
69     void setProfiles(const IOProfileCollection &profiles);
70 
setHalVersion(uint32_t major,uint32_t minor)71     void setHalVersion(uint32_t major, uint32_t minor) {
72         mHalVersion = (major << 8) | (minor & 0xff);
73     }
getHalVersionMajor()74     uint32_t getHalVersionMajor() const { return mHalVersion >> 8; }
getHalVersionMinor()75     uint32_t getHalVersionMinor() const { return mHalVersion & 0xff; }
76 
77     sp<DeviceDescriptor> getRouteSinkDevice(const sp<AudioRoute> &route) const;
78     DeviceVector getRouteSourceDevices(const sp<AudioRoute> &route) const;
79     void setRoutes(const AudioRouteVector &routes);
80 
81     status_t addOutputProfile(const sp<IOProfile> &profile);
82     status_t addInputProfile(const sp<IOProfile> &profile);
83     status_t addProfile(const sp<IOProfile> &profile);
84 
85     status_t addOutputProfile(const std::string& name, const audio_config_t *config,
86             audio_devices_t device, const String8& address);
87     status_t removeOutputProfile(const std::string& name);
88     status_t addInputProfile(const std::string& name, const audio_config_t *config,
89             audio_devices_t device, const String8& address);
90     status_t removeInputProfile(const std::string& name);
91 
getHandle()92     audio_module_handle_t getHandle() const { return mHandle; }
93     void setHandle(audio_module_handle_t handle);
94 
findPortByTagName(const std::string & tagName)95     sp<PolicyAudioPort> findPortByTagName(const std::string &tagName) const
96     {
97         return findByTagName(mPorts, tagName);
98     }
99 
100     /**
101      * @brief supportsPatch checks if an audio patch between 2 ports beloging to this HwModule
102      * is supported by a HwModule. The ports and the route shall be declared in the
103      * audio_policy_configuration.xml file.
104      * @param srcPort (aka the source) to be considered
105      * @param dstPort (aka the sink) to be considered
106      * @return true if the HwModule supports the connection between the sink and the source,
107      * false otherwise
108      */
109     bool supportsPatch(const sp<PolicyAudioPort> &srcPort,
110                        const sp<PolicyAudioPort> &dstPort) const;
111 
112     // TODO remove from here (split serialization)
113     void dump(String8 *dst) const;
114 
115 private:
116     void refreshSupportedDevices();
117 
118     const String8 mName; // base name of the audio HW module (primary, a2dp ...)
119     audio_module_handle_t mHandle;
120     OutputProfileCollection mOutputProfiles; // output profiles exposed by this module
121     InputProfileCollection mInputProfiles;  // input profiles exposed by this module
122     uint32_t mHalVersion; // audio HAL API version
123     DeviceVector mDeclaredDevices; // devices declared in audio_policy configuration file.
124     DeviceVector mDynamicDevices; /**< devices that can be added/removed at runtime (e.g. rsbumix)*/
125     AudioRouteVector mRoutes;
126     PolicyAudioPortVector mPorts;
127 };
128 
129 class HwModuleCollection : public Vector<sp<HwModule> >
130 {
131 public:
132     sp<HwModule> getModuleFromName(const char *name) const;
133 
134     sp<HwModule> getModuleForDeviceType(audio_devices_t device,
135                                         audio_format_t encodedFormat) const;
136 
137     sp<HwModule> getModuleForDevice(const sp<DeviceDescriptor> &device,
138                                     audio_format_t encodedFormat) const;
139 
140     DeviceVector getAvailableDevicesFromModuleName(const char *name,
141                                                    const DeviceVector &availableDevices) const;
142 
143     /**
144      * @brief getDeviceDescriptor returns a device descriptor associated to the device type and
145      * device address (if matchAddress is true).
146      * It may loop twice on all modules to check if allowToCreate is true
147      *      -first loop will check if the device is found on a module since declared in the list
148      * of device port in configuration file
149      *      -(allowToCreate is true)second loop will check if the device is weakly supported by one
150      * or more profiles on a given module and will add as a supported device for this module.
151      *       The device will also be added to the dynamic list of device of this module
152      * @param type of the device requested
153      * @param address of the device requested
154      * @param name of the device that requested
155      * @param encodedFormat if not AUDIO_FORMAT_DEFAULT, must match one supported format
156      * @param matchAddress true if a strong match is required
157      * @param allowToCreate true if allowed to create dynamic device (e.g. hdmi, usb...)
158      * @return device descriptor associated to the type (and address if matchAddress is true)
159      */
160     sp<DeviceDescriptor> getDeviceDescriptor(const audio_devices_t type,
161                                              const char *address,
162                                              const char *name,
163                                              audio_format_t encodedFormat,
164                                              bool allowToCreate = false,
165                                              bool matchAddress = true) const;
166 
167     /**
168      * @brief createDevice creates a new device from the type and address given. It checks that
169      * according to the device type, a module is supporting this device (weak check).
170      * This concerns only dynamic device, aka device with a specific address and not
171      * already supported by module/underlying profiles.
172      * @param type of the device to be created
173      * @param address of the device to be created
174      * @param name of the device to be created
175      * @return device descriptor if a module is supporting this type, nullptr otherwise.
176      */
177     sp<DeviceDescriptor> createDevice(const audio_devices_t type,
178                                       const char *address,
179                                       const char *name,
180                                       const audio_format_t encodedFormat) const;
181 
182     /**
183      * @brief cleanUpForDevice: loop on all profiles of all modules to remove device from
184      * the list of supported device. If this device is a dynamic device (aka a device not in the
185      * xml file with a runtime address), it is also removed from the module collection of dynamic
186      * devices.
187      * @param device that has been disconnected
188      */
189     void cleanUpForDevice(const sp<DeviceDescriptor> &device);
190 
191     void dump(String8 *dst) const;
192 };
193 
194 } // namespace android
195