/* * 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 #include #include #include #include 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(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(mProperties.readFromParcel(parcel)); // Ignore "extra" properties as they may contain Java Parcelables return OK; } status_t MidiDeviceInfo::readStringVector( const Parcel* parcel, Vector *vectorPtr, size_t defaultLength) { std::optional>> 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& vector) const { std::vector 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& lhs, const Vector& 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); } } // namespace midi } // namespace media } // namespace android