1 /* 2 * Copyright (C) 2016 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 #define LOG_TAG "MidiDeviceInfo" 18 19 #include <media/MidiDeviceInfo.h> 20 21 #include <binder/Parcel.h> 22 #include <log/log.h> 23 #include <utils/Errors.h> 24 #include <utils/String16.h> 25 26 namespace android { 27 namespace media { 28 namespace midi { 29 30 // The constant values need to be kept in sync with MidiDeviceInfo.java. 31 // static 32 const char* const MidiDeviceInfo::PROPERTY_NAME = "name"; 33 const char* const MidiDeviceInfo::PROPERTY_MANUFACTURER = "manufacturer"; 34 const char* const MidiDeviceInfo::PROPERTY_PRODUCT = "product"; 35 const char* const MidiDeviceInfo::PROPERTY_VERSION = "version"; 36 const char* const MidiDeviceInfo::PROPERTY_SERIAL_NUMBER = "serial_number"; 37 const char* const MidiDeviceInfo::PROPERTY_ALSA_CARD = "alsa_card"; 38 const char* const MidiDeviceInfo::PROPERTY_ALSA_DEVICE = "alsa_device"; 39 40 String16 MidiDeviceInfo::getProperty(const char* propertyName) { 41 String16 value; 42 if (mProperties.getString(String16(propertyName), &value)) { 43 return value; 44 } else { 45 return String16(); 46 } 47 } 48 49 #define RETURN_IF_FAILED(calledOnce) \ 50 { \ 51 status_t returnStatus = calledOnce; \ 52 if (returnStatus) { \ 53 ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \ 54 return returnStatus; \ 55 } \ 56 } 57 58 status_t MidiDeviceInfo::writeToParcel(Parcel* parcel) const { 59 // Needs to be kept in sync with code in MidiDeviceInfo.java 60 RETURN_IF_FAILED(parcel->writeInt32(mType)); 61 RETURN_IF_FAILED(parcel->writeInt32(mId)); 62 RETURN_IF_FAILED(parcel->writeInt32((int32_t)mInputPortNames.size())); 63 RETURN_IF_FAILED(parcel->writeInt32((int32_t)mOutputPortNames.size())); 64 RETURN_IF_FAILED(writeStringVector(parcel, mInputPortNames)); 65 RETURN_IF_FAILED(writeStringVector(parcel, mOutputPortNames)); 66 RETURN_IF_FAILED(parcel->writeInt32(mIsPrivate ? 1 : 0)); 67 RETURN_IF_FAILED(mProperties.writeToParcel(parcel)); 68 // This corresponds to "extra" properties written by Java code 69 RETURN_IF_FAILED(mProperties.writeToParcel(parcel)); 70 return OK; 71 } 72 73 status_t MidiDeviceInfo::readFromParcel(const Parcel* parcel) { 74 // Needs to be kept in sync with code in MidiDeviceInfo.java 75 RETURN_IF_FAILED(parcel->readInt32(&mType)); 76 RETURN_IF_FAILED(parcel->readInt32(&mId)); 77 int32_t inputPortCount; 78 RETURN_IF_FAILED(parcel->readInt32(&inputPortCount)); 79 int32_t outputPortCount; 80 RETURN_IF_FAILED(parcel->readInt32(&outputPortCount)); 81 RETURN_IF_FAILED(readStringVector(parcel, &mInputPortNames, inputPortCount)); 82 RETURN_IF_FAILED(readStringVector(parcel, &mOutputPortNames, outputPortCount)); 83 int32_t isPrivate; 84 RETURN_IF_FAILED(parcel->readInt32(&isPrivate)); 85 mIsPrivate = isPrivate == 1; 86 RETURN_IF_FAILED(mProperties.readFromParcel(parcel)); 87 // Ignore "extra" properties as they may contain Java Parcelables 88 return OK; 89 } 90 91 status_t MidiDeviceInfo::readStringVector( 92 const Parcel* parcel, Vector<String16> *vectorPtr, size_t defaultLength) { 93 std::unique_ptr<std::vector<std::unique_ptr<String16>>> v; 94 status_t result = parcel->readString16Vector(&v); 95 if (result != OK) return result; 96 vectorPtr->clear(); 97 if (v.get() != nullptr) { 98 for (const auto& iter : *v) { 99 if (iter.get() != nullptr) { 100 vectorPtr->push_back(*iter); 101 } else { 102 vectorPtr->push_back(String16()); 103 } 104 } 105 } else { 106 vectorPtr->resize(defaultLength); 107 } 108 return OK; 109 } 110 111 status_t MidiDeviceInfo::writeStringVector(Parcel* parcel, const Vector<String16>& vector) const { 112 std::vector<String16> v; 113 for (size_t i = 0; i < vector.size(); ++i) { 114 v.push_back(vector[i]); 115 } 116 return parcel->writeString16Vector(v); 117 } 118 119 // Vector does not define operator== 120 static inline bool areVectorsEqual(const Vector<String16>& lhs, const Vector<String16>& rhs) { 121 if (lhs.size() != rhs.size()) return false; 122 for (size_t i = 0; i < lhs.size(); ++i) { 123 if (lhs[i] != rhs[i]) return false; 124 } 125 return true; 126 } 127 128 bool operator==(const MidiDeviceInfo& lhs, const MidiDeviceInfo& rhs) { 129 return (lhs.mType == rhs.mType && lhs.mId == rhs.mId && 130 areVectorsEqual(lhs.mInputPortNames, rhs.mInputPortNames) && 131 areVectorsEqual(lhs.mOutputPortNames, rhs.mOutputPortNames) && 132 lhs.mProperties == rhs.mProperties && 133 lhs.mIsPrivate == rhs.mIsPrivate); 134 } 135 136 } // namespace midi 137 } // namespace media 138 } // namespace android 139