• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "AudioPort.h"
20 #include <utils/Errors.h>
21 #include <utils/String8.h>
22 #include <utils/SortedVector.h>
23 #include <cutils/config_utils.h>
24 #include <system/audio.h>
25 #include <system/audio_policy.h>
26 
27 namespace android {
28 
29 class DeviceDescriptor : public AudioPort, public AudioPortConfig
30 {
31 public:
32      // Note that empty name refers by convention to a generic device.
33     explicit DeviceDescriptor(audio_devices_t type, const String8 &tagName = String8(""));
34     DeviceDescriptor(audio_devices_t type, const FormatVector &encodedFormats,
35             const String8 &tagName = String8(""));
36 
~DeviceDescriptor()37     virtual ~DeviceDescriptor() {}
38 
getTagName()39     virtual const String8 getTagName() const { return mTagName; }
40 
type()41     audio_devices_t type() const { return mDeviceType; }
address()42     String8 address() const { return mAddress; }
setAddress(const String8 & address)43     void setAddress(const String8 &address) { mAddress = address; }
44 
encodedFormats()45     const FormatVector& encodedFormats() const { return mEncodedFormats; }
46 
getEncodedFormat()47     audio_format_t getEncodedFormat() { return mCurrentEncodedFormat; }
48 
setEncodedFormat(audio_format_t format)49     void setEncodedFormat(audio_format_t format) {
50         mCurrentEncodedFormat = format;
51     }
52 
53     bool equals(const sp<DeviceDescriptor>& other) const;
54 
55     bool hasCurrentEncodedFormat() const;
56 
57     bool supportsFormat(audio_format_t format);
58 
59     // AudioPortConfig
getAudioPort()60     virtual sp<AudioPort> getAudioPort() const { return (AudioPort*) this; }
61     virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
62             const struct audio_port_config *srcConfig = NULL) const;
63 
64     // AudioPort
65     virtual void attach(const sp<HwModule>& module);
66     virtual void detach();
67 
68     virtual void toAudioPort(struct audio_port *port) const;
69     virtual void importAudioPort(const sp<AudioPort>& port, bool force = false);
70 
71     audio_port_handle_t getId() const;
72     void dump(String8 *dst, int spaces, int index, bool verbose = true) const;
73     void log() const;
74     std::string toString() const;
75 
76 private:
77     String8 mAddress{""};
78     String8 mTagName; // Unique human readable identifier for a device port found in conf file.
79     audio_devices_t     mDeviceType;
80     FormatVector        mEncodedFormats;
81     audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE;
82     audio_format_t      mCurrentEncodedFormat;
83 };
84 
85 class DeviceVector : public SortedVector<sp<DeviceDescriptor> >
86 {
87 public:
DeviceVector()88     DeviceVector() : SortedVector(), mDeviceTypes(AUDIO_DEVICE_NONE) {}
DeviceVector(const sp<DeviceDescriptor> & item)89     explicit DeviceVector(const sp<DeviceDescriptor>& item) : DeviceVector()
90     {
91         add(item);
92     }
93 
94     ssize_t add(const sp<DeviceDescriptor>& item);
95     void add(const DeviceVector &devices);
96     ssize_t remove(const sp<DeviceDescriptor>& item);
97     void remove(const DeviceVector &devices);
98     ssize_t indexOf(const sp<DeviceDescriptor>& item) const;
99 
types()100     audio_devices_t types() const { return mDeviceTypes; }
101 
102     // If 'address' is empty and 'codec' is AUDIO_FORMAT_DEFAULT, a device with a non-empty
103     // address may be returned if there is no device with the specified 'type' and empty address.
104     sp<DeviceDescriptor> getDevice(audio_devices_t type, const String8 &address,
105                                    audio_format_t codec) const;
106     DeviceVector getDevicesFromTypeMask(audio_devices_t types) const;
107 
108     /**
109      * @brief getDeviceFromId
110      * @param id of the DeviceDescriptor to seach (aka Port handle).
111      * @return DeviceDescriptor associated to port id if found, nullptr otherwise. If the id is
112      * equal to AUDIO_PORT_HANDLE_NONE, it also returns a nullptr.
113      */
114     sp<DeviceDescriptor> getDeviceFromId(audio_port_handle_t id) const;
115     sp<DeviceDescriptor> getDeviceFromTagName(const String8 &tagName) const;
116     DeviceVector getDevicesFromHwModule(audio_module_handle_t moduleHandle) const;
117     audio_devices_t getDeviceTypesFromHwModule(audio_module_handle_t moduleHandle) const;
118 
contains(const sp<DeviceDescriptor> & item)119     bool contains(const sp<DeviceDescriptor>& item) const { return indexOf(item) >= 0; }
120 
121     /**
122      * @brief containsAtLeastOne
123      * @param devices vector of devices to check against.
124      * @return true if the DeviceVector contains at list one of the devices from the given vector.
125      */
126     bool containsAtLeastOne(const DeviceVector &devices) const;
127 
128     /**
129      * @brief containsAllDevices
130      * @param devices vector of devices to check against.
131      * @return true if the DeviceVector contains all the devices from the given vector
132      */
133     bool containsAllDevices(const DeviceVector &devices) const;
134 
135     /**
136      * @brief filter the devices supported by this collection against another collection
137      * @param devices to filter against
138      * @return a filtered DeviceVector
139      */
140     DeviceVector filter(const DeviceVector &devices) const;
141 
142     /**
143      * @brief filter the devices supported by this collection before sending
144      * then to the Engine via AudioPolicyManagerObserver interface
145      * @return a filtered DeviceVector
146      */
147     DeviceVector filterForEngine() const;
148 
149     /**
150      * @brief merge two vectors. As SortedVector Implementation is buggy (it does not check the size
151      * of the destination vector, only of the source, it provides a safe implementation
152      * @param devices source device vector to merge with
153      * @return size of the merged vector.
154      */
merge(const DeviceVector & devices)155     ssize_t merge(const DeviceVector &devices)
156     {
157         if (isEmpty()) {
158             add(devices);
159             return size();
160         }
161         return SortedVector::merge(devices);
162     }
163 
164     /**
165      * @brief operator == DeviceVector are equals if all the DeviceDescriptor can be found (aka
166      * DeviceDescriptor with same type and address) and the vector has same size.
167      * @param right DeviceVector to compare to.
168      * @return true if right contains the same device and has the same size.
169      */
170     bool operator==(const DeviceVector &right) const
171     {
172         if (size() != right.size()) {
173             return false;
174         }
175         for (const auto &device : *this) {
176             if (right.indexOf(device) < 0) {
177                 return false;
178             }
179         }
180         return true;
181     }
182 
183     bool operator!=(const DeviceVector &right) const
184     {
185         return !operator==(right);
186     }
187 
188     /**
189      * @brief getFirstValidAddress
190      * @return the first valid address of a list of device, "" if no device with valid address
191      * found.
192      * This helper function helps maintaining compatibility with legacy where we used to have a
193      * devices mask and an address.
194      */
getFirstValidAddress()195     String8 getFirstValidAddress() const
196     {
197         for (const auto &device : *this) {
198             if (device->address() != "") {
199                 return device->address();
200             }
201         }
202         return String8("");
203     }
204 
205     std::string toString() const;
206 
207     void dump(String8 *dst, const String8 &tag, int spaces = 0, bool verbose = true) const;
208 
209 private:
210     void refreshTypes();
211     audio_devices_t mDeviceTypes;
212 };
213 
214 } // namespace android
215