1 /*
2  * Copyright (C) 2018 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 #ifndef ANDROID_MICROPHONE_INFO_H
18 #define ANDROID_MICROPHONE_INFO_H
19 
20 #include <binder/Parcel.h>
21 #include <binder/Parcelable.h>
22 #include <system/audio.h>
23 #include <utils/String16.h>
24 #include <utils/Vector.h>
25 
26 namespace android {
27 namespace media {
28 
29 #define RETURN_IF_FAILED(calledOnce)                                     \
30     {                                                                    \
31         status_t returnStatus = calledOnce;                              \
32         if (returnStatus) {                                              \
33             ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
34             return returnStatus;                                         \
35          }                                                               \
36     }
37 
38 class MicrophoneInfo : public Parcelable {
39 public:
40     MicrophoneInfo() = default;
41     MicrophoneInfo(const MicrophoneInfo& microphoneInfo) = default;
MicrophoneInfo(audio_microphone_characteristic_t & characteristic)42     MicrophoneInfo(audio_microphone_characteristic_t& characteristic) {
43         mDeviceId = String16(&characteristic.device_id[0]);
44         mPortId = characteristic.id;
45         mType = characteristic.device;
46         mAddress = String16(&characteristic.address[0]);
47         mDeviceLocation = characteristic.location;
48         mDeviceGroup = characteristic.group;
49         mIndexInTheGroup = characteristic.index_in_the_group;
50         mGeometricLocation.push_back(characteristic.geometric_location.x);
51         mGeometricLocation.push_back(characteristic.geometric_location.y);
52         mGeometricLocation.push_back(characteristic.geometric_location.z);
53         mOrientation.push_back(characteristic.orientation.x);
54         mOrientation.push_back(characteristic.orientation.y);
55         mOrientation.push_back(characteristic.orientation.z);
56         Vector<float> frequencies;
57         Vector<float> responses;
58         for (size_t i = 0; i < characteristic.num_frequency_responses; i++) {
59             frequencies.push_back(characteristic.frequency_responses[0][i]);
60             responses.push_back(characteristic.frequency_responses[1][i]);
61         }
62         mFrequencyResponses.push_back(frequencies);
63         mFrequencyResponses.push_back(responses);
64         for (size_t i = 0; i < AUDIO_CHANNEL_COUNT_MAX; i++) {
65             mChannelMapping.push_back(characteristic.channel_mapping[i]);
66         }
67         mSensitivity = characteristic.sensitivity;
68         mMaxSpl = characteristic.max_spl;
69         mMinSpl = characteristic.min_spl;
70         mDirectionality = characteristic.directionality;
71     }
72 
73     virtual ~MicrophoneInfo() = default;
74 
writeToParcel(Parcel * parcel)75     virtual status_t writeToParcel(Parcel* parcel) const {
76         RETURN_IF_FAILED(parcel->writeString16(mDeviceId));
77         RETURN_IF_FAILED(parcel->writeInt32(mPortId));
78         RETURN_IF_FAILED(parcel->writeUint32(mType));
79         RETURN_IF_FAILED(parcel->writeString16(mAddress));
80         RETURN_IF_FAILED(parcel->writeInt32(mDeviceLocation));
81         RETURN_IF_FAILED(parcel->writeInt32(mDeviceGroup));
82         RETURN_IF_FAILED(parcel->writeInt32(mIndexInTheGroup));
83         RETURN_IF_FAILED(writeFloatVector(parcel, mGeometricLocation));
84         RETURN_IF_FAILED(writeFloatVector(parcel, mOrientation));
85         if (mFrequencyResponses.size() != 2) {
86             return BAD_VALUE;
87         }
88         for (size_t i = 0; i < mFrequencyResponses.size(); i++) {
89             RETURN_IF_FAILED(parcel->writeInt32(mFrequencyResponses[i].size()));
90             RETURN_IF_FAILED(writeFloatVector(parcel, mFrequencyResponses[i]));
91         }
92         std::vector<int> channelMapping;
93         for (size_t i = 0; i < mChannelMapping.size(); ++i) {
94             channelMapping.push_back(mChannelMapping[i]);
95         }
96         RETURN_IF_FAILED(parcel->writeInt32Vector(channelMapping));
97         RETURN_IF_FAILED(parcel->writeFloat(mSensitivity));
98         RETURN_IF_FAILED(parcel->writeFloat(mMaxSpl));
99         RETURN_IF_FAILED(parcel->writeFloat(mMinSpl));
100         RETURN_IF_FAILED(parcel->writeInt32(mDirectionality));
101         return OK;
102     }
103 
readFromParcel(const Parcel * parcel)104     virtual status_t readFromParcel(const Parcel* parcel) {
105         RETURN_IF_FAILED(parcel->readString16(&mDeviceId));
106         RETURN_IF_FAILED(parcel->readInt32(&mPortId));
107         RETURN_IF_FAILED(parcel->readUint32(&mType));
108         RETURN_IF_FAILED(parcel->readString16(&mAddress));
109         RETURN_IF_FAILED(parcel->readInt32(&mDeviceLocation));
110         RETURN_IF_FAILED(parcel->readInt32(&mDeviceGroup));
111         RETURN_IF_FAILED(parcel->readInt32(&mIndexInTheGroup));
112         RETURN_IF_FAILED(readFloatVector(parcel, &mGeometricLocation, 3));
113         RETURN_IF_FAILED(readFloatVector(parcel, &mOrientation, 3));
114         int32_t frequenciesNum;
115         RETURN_IF_FAILED(parcel->readInt32(&frequenciesNum));
116         Vector<float> frequencies;
117         RETURN_IF_FAILED(readFloatVector(parcel, &frequencies, frequenciesNum));
118         int32_t responsesNum;
119         RETURN_IF_FAILED(parcel->readInt32(&responsesNum));
120         Vector<float> responses;
121         RETURN_IF_FAILED(readFloatVector(parcel, &responses, responsesNum));
122         if (frequencies.size() != responses.size()) {
123             return BAD_VALUE;
124         }
125         mFrequencyResponses.push_back(frequencies);
126         mFrequencyResponses.push_back(responses);
127         std::vector<int> channelMapping;
128         status_t result = parcel->readInt32Vector(&channelMapping);
129         if (result != OK) {
130             return result;
131         }
132         if (channelMapping.size() != AUDIO_CHANNEL_COUNT_MAX) {
133             return BAD_VALUE;
134         }
135         for (size_t i = 0; i < channelMapping.size(); i++) {
136             mChannelMapping.push_back(channelMapping[i]);
137         }
138         RETURN_IF_FAILED(parcel->readFloat(&mSensitivity));
139         RETURN_IF_FAILED(parcel->readFloat(&mMaxSpl));
140         RETURN_IF_FAILED(parcel->readFloat(&mMinSpl));
141         RETURN_IF_FAILED(parcel->readInt32(&mDirectionality));
142         return OK;
143     }
144 
getDeviceId()145     String16 getDeviceId() const {
146         return mDeviceId;
147     }
148 
getPortId()149     int getPortId() const {
150         return mPortId;
151     }
152 
getType()153     unsigned int getType() const {
154         return mType;
155     }
156 
getAddress()157     String16 getAddress() const {
158         return mAddress;
159     }
160 
getDeviceLocation()161     int getDeviceLocation() const {
162         return mDeviceLocation;
163     }
164 
getDeviceGroup()165     int getDeviceGroup() const {
166         return mDeviceGroup;
167     }
168 
getIndexInTheGroup()169     int getIndexInTheGroup() const {
170         return mIndexInTheGroup;
171     }
172 
getGeometricLocation()173     const Vector<float>& getGeometricLocation() const {
174         return mGeometricLocation;
175     }
176 
getOrientation()177     const Vector<float>& getOrientation() const {
178         return mOrientation;
179     }
180 
getFrequencyResponses()181     const Vector<Vector<float>>& getFrequencyResponses() const {
182         return mFrequencyResponses;
183     }
184 
getChannelMapping()185     const Vector<int>& getChannelMapping() const {
186         return mChannelMapping;
187     }
188 
getSensitivity()189     float getSensitivity() const {
190         return mSensitivity;
191     }
192 
getMaxSpl()193     float getMaxSpl() const {
194         return mMaxSpl;
195     }
196 
getMinSpl()197     float getMinSpl() const {
198         return mMinSpl;
199     }
200 
getDirectionality()201     int getDirectionality() const {
202         return mDirectionality;
203     }
204 
205 private:
readFloatVector(const Parcel * parcel,Vector<float> * vectorPtr,size_t defaultLength)206     status_t readFloatVector(
207             const Parcel* parcel, Vector<float> *vectorPtr, size_t defaultLength) {
208         std::unique_ptr<std::vector<float>> v;
209         status_t result = parcel->readFloatVector(&v);
210         if (result != OK) return result;
211         vectorPtr->clear();
212         if (v.get() != nullptr) {
213             for (const auto& iter : *v) {
214                 vectorPtr->push_back(iter);
215             }
216         } else {
217             vectorPtr->resize(defaultLength);
218         }
219         return OK;
220     }
writeFloatVector(Parcel * parcel,const Vector<float> & vector)221     status_t writeFloatVector(Parcel* parcel, const Vector<float>& vector) const {
222         std::vector<float> v;
223         for (size_t i = 0; i < vector.size(); i++) {
224             v.push_back(vector[i]);
225         }
226         return parcel->writeFloatVector(v);
227     }
228 
229     String16 mDeviceId;
230     int32_t mPortId;
231     uint32_t mType;
232     String16 mAddress;
233     int32_t mDeviceLocation;
234     int32_t mDeviceGroup;
235     int32_t mIndexInTheGroup;
236     Vector<float> mGeometricLocation;
237     Vector<float> mOrientation;
238     Vector<Vector<float>> mFrequencyResponses;
239     Vector<int> mChannelMapping;
240     float mSensitivity;
241     float mMaxSpl;
242     float mMinSpl;
243     int32_t mDirectionality;
244 };
245 
246 } // namespace media
247 } // namespace android
248 
249 #endif
250