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; 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 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 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 145 String16 getDeviceId() const { 146 return mDeviceId; 147 } 148 149 int getPortId() const { 150 return mPortId; 151 } 152 153 unsigned int getType() const { 154 return mType; 155 } 156 157 String16 getAddress() const { 158 return mAddress; 159 } 160 161 int getDeviceLocation() const { 162 return mDeviceLocation; 163 } 164 165 int getDeviceGroup() const { 166 return mDeviceGroup; 167 } 168 169 int getIndexInTheGroup() const { 170 return mIndexInTheGroup; 171 } 172 173 const Vector<float>& getGeometricLocation() const { 174 return mGeometricLocation; 175 } 176 177 const Vector<float>& getOrientation() const { 178 return mOrientation; 179 } 180 181 const Vector<Vector<float>>& getFrequencyResponses() const { 182 return mFrequencyResponses; 183 } 184 185 const Vector<int>& getChannelMapping() const { 186 return mChannelMapping; 187 } 188 189 float getSensitivity() const { 190 return mSensitivity; 191 } 192 193 float getMaxSpl() const { 194 return mMaxSpl; 195 } 196 197 float getMinSpl() const { 198 return mMinSpl; 199 } 200 201 int getDirectionality() const { 202 return mDirectionality; 203 } 204 205 private: 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 } 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