| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #define LOG_TAG "MidiDeviceInfo" |
| |
| #include <MidiDeviceInfo.h> |
| |
| #include <binder/Parcel.h> |
| #include <log/log.h> |
| #include <utils/Errors.h> |
| #include <utils/String16.h> |
| |
| namespace android { |
| namespace media { |
| namespace midi { |
| |
| // The constant values need to be kept in sync with MidiDeviceInfo.java. |
| // static |
| const char* const MidiDeviceInfo::PROPERTY_NAME = "name"; |
| const char* const MidiDeviceInfo::PROPERTY_MANUFACTURER = "manufacturer"; |
| const char* const MidiDeviceInfo::PROPERTY_PRODUCT = "product"; |
| const char* const MidiDeviceInfo::PROPERTY_VERSION = "version"; |
| const char* const MidiDeviceInfo::PROPERTY_SERIAL_NUMBER = "serial_number"; |
| const char* const MidiDeviceInfo::PROPERTY_ALSA_CARD = "alsa_card"; |
| const char* const MidiDeviceInfo::PROPERTY_ALSA_DEVICE = "alsa_device"; |
| |
| String16 MidiDeviceInfo::getProperty(const char* propertyName) { |
| String16 value; |
| if (mProperties.getString(String16(propertyName), &value)) { |
| return value; |
| } else { |
| return String16(); |
| } |
| } |
| |
| #define RETURN_IF_FAILED(calledOnce) \ |
| { \ |
| status_t returnStatus = calledOnce; \ |
| if (returnStatus) { \ |
| ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \ |
| return returnStatus; \ |
| } \ |
| } |
| |
| status_t MidiDeviceInfo::writeToParcel(Parcel* parcel) const { |
| // Needs to be kept in sync with code in MidiDeviceInfo.java |
| RETURN_IF_FAILED(parcel->writeInt32(mType)); |
| RETURN_IF_FAILED(parcel->writeInt32(mId)); |
| RETURN_IF_FAILED(parcel->writeInt32((int32_t)mInputPortNames.size())); |
| RETURN_IF_FAILED(parcel->writeInt32((int32_t)mOutputPortNames.size())); |
| RETURN_IF_FAILED(writeStringVector(parcel, mInputPortNames)); |
| RETURN_IF_FAILED(writeStringVector(parcel, mOutputPortNames)); |
| RETURN_IF_FAILED(parcel->writeInt32(mIsPrivate ? 1 : 0)); |
| RETURN_IF_FAILED(parcel->writeInt32(mDefaultProtocol)); |
| RETURN_IF_FAILED(mProperties.writeToParcel(parcel)); |
| // This corresponds to "extra" properties written by Java code |
| RETURN_IF_FAILED(mProperties.writeToParcel(parcel)); |
| return OK; |
| } |
| |
| status_t MidiDeviceInfo::readFromParcel(const Parcel* parcel) { |
| // Needs to be kept in sync with code in MidiDeviceInfo.java |
| RETURN_IF_FAILED(parcel->readInt32(&mType)); |
| RETURN_IF_FAILED(parcel->readInt32(&mId)); |
| int32_t inputPortCount; |
| RETURN_IF_FAILED(parcel->readInt32(&inputPortCount)); |
| int32_t outputPortCount; |
| RETURN_IF_FAILED(parcel->readInt32(&outputPortCount)); |
| RETURN_IF_FAILED(readStringVector(parcel, &mInputPortNames, inputPortCount)); |
| RETURN_IF_FAILED(readStringVector(parcel, &mOutputPortNames, outputPortCount)); |
| int32_t isPrivate; |
| RETURN_IF_FAILED(parcel->readInt32(&isPrivate)); |
| mIsPrivate = isPrivate == 1; |
| RETURN_IF_FAILED(parcel->readInt32(&mDefaultProtocol)); |
| RETURN_IF_FAILED(mProperties.readFromParcel(parcel)); |
| // Ignore "extra" properties as they may contain Java Parcelables |
| return OK; |
| } |
| |
| status_t MidiDeviceInfo::readStringVector( |
| const Parcel* parcel, Vector<String16> *vectorPtr, size_t defaultLength) { |
| std::optional<std::vector<std::optional<String16>>> v; |
| status_t result = parcel->readString16Vector(&v); |
| if (result != OK) return result; |
| vectorPtr->clear(); |
| if (v) { |
| for (const auto& iter : *v) { |
| if (iter) { |
| vectorPtr->push_back(*iter); |
| } else { |
| vectorPtr->push_back(String16()); |
| } |
| } |
| } else { |
| vectorPtr->resize(defaultLength); |
| } |
| return OK; |
| } |
| |
| status_t MidiDeviceInfo::writeStringVector(Parcel* parcel, const Vector<String16>& vector) const { |
| std::vector<String16> v; |
| for (size_t i = 0; i < vector.size(); ++i) { |
| v.push_back(vector[i]); |
| } |
| return parcel->writeString16Vector(v); |
| } |
| |
| // Vector does not define operator== |
| static inline bool areVectorsEqual(const Vector<String16>& lhs, const Vector<String16>& rhs) { |
| if (lhs.size() != rhs.size()) return false; |
| for (size_t i = 0; i < lhs.size(); ++i) { |
| if (lhs[i] != rhs[i]) return false; |
| } |
| return true; |
| } |
| |
| bool operator==(const MidiDeviceInfo& lhs, const MidiDeviceInfo& rhs) { |
| return (lhs.mType == rhs.mType && lhs.mId == rhs.mId && |
| areVectorsEqual(lhs.mInputPortNames, rhs.mInputPortNames) && |
| areVectorsEqual(lhs.mOutputPortNames, rhs.mOutputPortNames) && |
| lhs.mProperties == rhs.mProperties && |
| lhs.mIsPrivate == rhs.mIsPrivate && |
| lhs.mDefaultProtocol == rhs.mDefaultProtocol); |
| } |
| |
| } // namespace midi |
| } // namespace media |
| } // namespace android |