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 "PolicyAudioPort.h"
20 #include <media/AudioContainers.h>
21 #include <media/DeviceDescriptorBase.h>
22 #include <utils/Errors.h>
23 #include <utils/String8.h>
24 #include <utils/SortedVector.h>
25 #include <cutils/config_utils.h>
26 #include <system/audio.h>
27 #include <system/audio_policy.h>
28 
29 namespace android {
30 
31 class DeviceDescriptor : public DeviceDescriptorBase,
32                          public PolicyAudioPort, public PolicyAudioPortConfig
33 {
34 public:
35      // Note that empty name refers by convention to a generic device.
36     explicit DeviceDescriptor(audio_devices_t type);
37     DeviceDescriptor(audio_devices_t type, const std::string &tagName,
38             const FormatVector &encodedFormats = FormatVector{});
39     DeviceDescriptor(audio_devices_t type, const std::string &tagName,
40             const std::string &address, const FormatVector &encodedFormats = FormatVector{});
41     DeviceDescriptor(const AudioDeviceTypeAddr &deviceTypeAddr, const std::string &tagName = "",
42             const FormatVector &encodedFormats = FormatVector{});
43 
~DeviceDescriptor()44     virtual ~DeviceDescriptor() {}
45 
addAudioProfile(const sp<AudioProfile> & profile)46     virtual void addAudioProfile(const sp<AudioProfile> &profile) {
47         addAudioProfileAndSort(mProfiles, profile);
48     }
49 
getTagName()50     virtual const std::string getTagName() const { return mTagName; }
51 
encodedFormats()52     const FormatVector& encodedFormats() const { return mEncodedFormats; }
53 
getEncodedFormat()54     audio_format_t getEncodedFormat() { return mCurrentEncodedFormat; }
55 
setEncodedFormat(audio_format_t format)56     void setEncodedFormat(audio_format_t format) {
57         mCurrentEncodedFormat = format;
58     }
59 
60     bool equals(const sp<DeviceDescriptor>& other) const;
61 
62     bool hasCurrentEncodedFormat() const;
63 
64     bool supportsFormat(audio_format_t format);
65 
66     // PolicyAudioPortConfig
getPolicyAudioPort()67     virtual sp<PolicyAudioPort> getPolicyAudioPort() const {
68         return static_cast<PolicyAudioPort*>(const_cast<DeviceDescriptor*>(this));
69     }
70 
71     // AudioPortConfig
72     virtual status_t applyAudioPortConfig(const struct audio_port_config *config,
73                                           struct audio_port_config *backupConfig = NULL);
74     virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
75             const struct audio_port_config *srcConfig = NULL) const;
76 
77     // PolicyAudioPort
asAudioPort()78     virtual sp<AudioPort> asAudioPort() const {
79         return static_cast<AudioPort*>(const_cast<DeviceDescriptor*>(this));
80     }
81     virtual void attach(const sp<HwModule>& module);
82     virtual void detach();
83 
84     // AudioPort
85     virtual void toAudioPort(struct audio_port *port) const;
86 
87     void importAudioPortAndPickAudioProfile(const sp<PolicyAudioPort>& policyPort,
88                                             bool force = false);
89 
90     void dump(String8 *dst, int spaces, int index, bool verbose = true) const;
91 
92 private:
93     std::string mTagName; // Unique human readable identifier for a device port found in conf file.
94     FormatVector        mEncodedFormats;
95     audio_format_t      mCurrentEncodedFormat;
96 };
97 
98 class DeviceVector : public SortedVector<sp<DeviceDescriptor> >
99 {
100 public:
DeviceVector()101     DeviceVector() : SortedVector() {}
DeviceVector(const sp<DeviceDescriptor> & item)102     explicit DeviceVector(const sp<DeviceDescriptor>& item) : DeviceVector()
103     {
104         add(item);
105     }
106 
107     ssize_t add(const sp<DeviceDescriptor>& item);
108     void add(const DeviceVector &devices);
109     ssize_t remove(const sp<DeviceDescriptor>& item);
110     void remove(const DeviceVector &devices);
111     ssize_t indexOf(const sp<DeviceDescriptor>& item) const;
112 
types()113     DeviceTypeSet types() const { return mDeviceTypes; }
114 
115     // If 'address' is empty and 'codec' is AUDIO_FORMAT_DEFAULT, a device with a non-empty
116     // address may be returned if there is no device with the specified 'type' and empty address.
117     sp<DeviceDescriptor> getDevice(audio_devices_t type, const String8 &address,
118                                    audio_format_t codec) const;
119     DeviceVector getDevicesFromTypes(const DeviceTypeSet& types) const;
getDevicesFromType(audio_devices_t type)120     DeviceVector getDevicesFromType(audio_devices_t type) const {
121         return getDevicesFromTypes({type});
122     }
123 
124     /**
125      * @brief getDeviceFromId
126      * @param id of the DeviceDescriptor to seach (aka Port handle).
127      * @return DeviceDescriptor associated to port id if found, nullptr otherwise. If the id is
128      * equal to AUDIO_PORT_HANDLE_NONE, it also returns a nullptr.
129      */
130     sp<DeviceDescriptor> getDeviceFromId(audio_port_handle_t id) const;
131     sp<DeviceDescriptor> getDeviceFromTagName(const std::string &tagName) const;
132     DeviceVector getDevicesFromHwModule(audio_module_handle_t moduleHandle) const;
133 
134     DeviceVector getFirstDevicesFromTypes(std::vector<audio_devices_t> orderedTypes) const;
135     sp<DeviceDescriptor> getFirstExistingDevice(std::vector<audio_devices_t> orderedTypes) const;
136 
137     // Return device descriptor that is used to open an input/output stream.
138     // Null pointer will be returned if
139     //     1) this collection is empty
140     //     2) the device descriptors are not the same category(input or output)
141     //     3) there are more than one device type for input case
142     //     4) the combination of all devices is invalid for selection
143     sp<DeviceDescriptor> getDeviceForOpening() const;
144 
145     // If there are devices with the given type and the devices to add is not empty,
146     // remove all the devices with the given type and add all the devices to add.
147     void replaceDevicesByType(audio_devices_t typeToRemove, const DeviceVector &devicesToAdd);
148 
containsDeviceAmongTypes(const DeviceTypeSet & deviceTypes)149     bool containsDeviceAmongTypes(const DeviceTypeSet& deviceTypes) const {
150         return !Intersection(mDeviceTypes, deviceTypes).empty();
151     }
152 
containsDeviceWithType(audio_devices_t deviceType)153     bool containsDeviceWithType(audio_devices_t deviceType) const {
154         return containsDeviceAmongTypes({deviceType});
155     }
156 
onlyContainsDevicesWithType(audio_devices_t deviceType)157     bool onlyContainsDevicesWithType(audio_devices_t deviceType) const {
158         return isSingleDeviceType(mDeviceTypes, deviceType);
159     }
160 
contains(const sp<DeviceDescriptor> & item)161     bool contains(const sp<DeviceDescriptor>& item) const { return indexOf(item) >= 0; }
162 
163     /**
164      * @brief containsAtLeastOne
165      * @param devices vector of devices to check against.
166      * @return true if the DeviceVector contains at list one of the devices from the given vector.
167      */
168     bool containsAtLeastOne(const DeviceVector &devices) const;
169 
170     /**
171      * @brief containsAllDevices
172      * @param devices vector of devices to check against.
173      * @return true if the DeviceVector contains all the devices from the given vector
174      */
175     bool containsAllDevices(const DeviceVector &devices) const;
176 
177     /**
178      * @brief filter the devices supported by this collection against another collection
179      * @param devices to filter against
180      * @return a filtered DeviceVector
181      */
182     DeviceVector filter(const DeviceVector &devices) const;
183 
184     /**
185      * @brief filter the devices supported by this collection before sending
186      * then to the Engine via AudioPolicyManagerObserver interface
187      * @return a filtered DeviceVector
188      */
189     DeviceVector filterForEngine() const;
190 
191     /**
192      * @brief merge two vectors. As SortedVector Implementation is buggy (it does not check the size
193      * of the destination vector, only of the source, it provides a safe implementation
194      * @param devices source device vector to merge with
195      * @return size of the merged vector.
196      */
merge(const DeviceVector & devices)197     ssize_t merge(const DeviceVector &devices)
198     {
199         if (isEmpty()) {
200             add(devices);
201             return size();
202         }
203         return SortedVector::merge(devices);
204     }
205 
206     /**
207      * @brief operator == DeviceVector are equals if all the DeviceDescriptor can be found (aka
208      * DeviceDescriptor with same type and address) and the vector has same size.
209      * @param right DeviceVector to compare to.
210      * @return true if right contains the same device and has the same size.
211      */
212     bool operator==(const DeviceVector &right) const
213     {
214         if (size() != right.size()) {
215             return false;
216         }
217         for (const auto &device : *this) {
218             if (right.indexOf(device) < 0) {
219                 return false;
220             }
221         }
222         return true;
223     }
224 
225     bool operator!=(const DeviceVector &right) const
226     {
227         return !operator==(right);
228     }
229 
230     /**
231      * @brief getFirstValidAddress
232      * @return the first valid address of a list of device, "" if no device with valid address
233      * found.
234      * This helper function helps maintaining compatibility with legacy where we used to have a
235      * devices mask and an address.
236      */
getFirstValidAddress()237     String8 getFirstValidAddress() const
238     {
239         for (const auto &device : *this) {
240             if (device->address() != "") {
241                 return String8(device->address().c_str());
242             }
243         }
244         return String8("");
245     }
246 
247     std::string toString() const;
248 
249     void dump(String8 *dst, const String8 &tag, int spaces = 0, bool verbose = true) const;
250 
251 private:
252     void refreshTypes();
253     DeviceTypeSet mDeviceTypes;
254 };
255 
256 } // namespace android
257