1f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov/* 2f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov * Copyright (C) 2016 The Android Open Source Project 3f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov * 4f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov * Licensed under the Apache License, Version 2.0 (the "License"); 5f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov * you may not use this file except in compliance with the License. 6f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov * You may obtain a copy of the License at 7f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov * 8f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov * http://www.apache.org/licenses/LICENSE-2.0 9f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov * 10f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov * Unless required by applicable law or agreed to in writing, software 11f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov * distributed under the License is distributed on an "AS IS" BASIS, 12f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov * See the License for the specific language governing permissions and 14f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov * limitations under the License. 15f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov */ 16f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov 17f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov#define LOG_TAG "MidiDeviceInfo" 18f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov 19f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov#include "MidiDeviceInfo.h" 20f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov 21f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov#include <binder/Parcel.h> 22f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov#include <log/log.h> 23f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov#include <utils/Errors.h> 24f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov#include <utils/String16.h> 25f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov 26f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganovnamespace android { 27f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganovnamespace media { 28f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganovnamespace midi { 29f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov 30f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov// The constant values need to be kept in sync with MidiDeviceInfo.java. 31f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov// static 32f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganovconst char* const MidiDeviceInfo::PROPERTY_NAME = "name"; 33f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganovconst char* const MidiDeviceInfo::PROPERTY_MANUFACTURER = "manufacturer"; 34f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganovconst char* const MidiDeviceInfo::PROPERTY_PRODUCT = "product"; 35f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganovconst char* const MidiDeviceInfo::PROPERTY_VERSION = "version"; 36f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganovconst char* const MidiDeviceInfo::PROPERTY_SERIAL_NUMBER = "serial_number"; 37f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganovconst char* const MidiDeviceInfo::PROPERTY_ALSA_CARD = "alsa_card"; 38f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganovconst char* const MidiDeviceInfo::PROPERTY_ALSA_DEVICE = "alsa_device"; 39f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov 40f28256f3113212db62aa8527b9ceae4caa414be3Mikhail NaganovString16 MidiDeviceInfo::getProperty(const char* propertyName) { 41f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov String16 value; 42f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov if (mProperties.getString(String16(propertyName), &value)) { 43f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov return value; 44f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov } else { 45f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov return String16(); 46f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov } 47f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov} 48f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov 49f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov#define RETURN_IF_FAILED(calledOnce) \ 50f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov { \ 51f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov status_t returnStatus = calledOnce; \ 52f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov if (returnStatus) { \ 53f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \ 54f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov return returnStatus; \ 55f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov } \ 56f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov } 57f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov 58f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganovstatus_t MidiDeviceInfo::writeToParcel(Parcel* parcel) const { 59f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov // Needs to be kept in sync with code in MidiDeviceInfo.java 60f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov RETURN_IF_FAILED(parcel->writeInt32(mType)); 61f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov RETURN_IF_FAILED(parcel->writeInt32(mId)); 62f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov RETURN_IF_FAILED(parcel->writeInt32((int32_t)mInputPortNames.size())); 63f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov RETURN_IF_FAILED(parcel->writeInt32((int32_t)mOutputPortNames.size())); 64f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov RETURN_IF_FAILED(writeStringVector(parcel, mInputPortNames)); 65f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov RETURN_IF_FAILED(writeStringVector(parcel, mOutputPortNames)); 66f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov RETURN_IF_FAILED(parcel->writeInt32(mIsPrivate ? 1 : 0)); 67f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov RETURN_IF_FAILED(mProperties.writeToParcel(parcel)); 68f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov // This corresponds to "extra" properties written by Java code 69f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov RETURN_IF_FAILED(mProperties.writeToParcel(parcel)); 70f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov return OK; 71f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov} 72f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov 73f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganovstatus_t MidiDeviceInfo::readFromParcel(const Parcel* parcel) { 74f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov // Needs to be kept in sync with code in MidiDeviceInfo.java 75f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov RETURN_IF_FAILED(parcel->readInt32(&mType)); 76f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov RETURN_IF_FAILED(parcel->readInt32(&mId)); 77f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov int32_t inputPortCount; 78f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov RETURN_IF_FAILED(parcel->readInt32(&inputPortCount)); 79f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov int32_t outputPortCount; 80f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov RETURN_IF_FAILED(parcel->readInt32(&outputPortCount)); 81f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov RETURN_IF_FAILED(readStringVector(parcel, &mInputPortNames, inputPortCount)); 82f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov RETURN_IF_FAILED(readStringVector(parcel, &mOutputPortNames, outputPortCount)); 83f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov int32_t isPrivate; 84f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov RETURN_IF_FAILED(parcel->readInt32(&isPrivate)); 85f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov mIsPrivate = isPrivate == 1; 86f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov RETURN_IF_FAILED(mProperties.readFromParcel(parcel)); 87f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov // Ignore "extra" properties as they may contain Java Parcelables 88f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov return OK; 89f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov} 90f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov 91f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganovstatus_t MidiDeviceInfo::readStringVector( 92f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov const Parcel* parcel, Vector<String16> *vectorPtr, size_t defaultLength) { 93f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov std::unique_ptr<std::vector<std::unique_ptr<String16>>> v; 94f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov status_t result = parcel->readString16Vector(&v); 95f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov if (result != OK) return result; 96f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov vectorPtr->clear(); 97f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov if (v.get() != nullptr) { 98f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov for (const auto& iter : *v) { 99f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov if (iter.get() != nullptr) { 100f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov vectorPtr->push_back(*iter); 101f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov } else { 102f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov vectorPtr->push_back(String16()); 103f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov } 104f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov } 105f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov } else { 106f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov vectorPtr->resize(defaultLength); 107f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov } 108f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov return OK; 109f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov} 110f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov 111f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganovstatus_t MidiDeviceInfo::writeStringVector(Parcel* parcel, const Vector<String16>& vector) const { 112f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov std::vector<String16> v; 113f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov for (size_t i = 0; i < vector.size(); ++i) { 114f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov v.push_back(vector[i]); 115f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov } 116f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov return parcel->writeString16Vector(v); 117f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov} 118f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov 119f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov// Vector does not define operator== 120f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganovstatic inline bool areVectorsEqual(const Vector<String16>& lhs, const Vector<String16>& rhs) { 121f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov if (lhs.size() != rhs.size()) return false; 122f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov for (size_t i = 0; i < lhs.size(); ++i) { 123f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov if (lhs[i] != rhs[i]) return false; 124f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov } 125f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov return true; 126f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov} 127f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov 128f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganovbool operator==(const MidiDeviceInfo& lhs, const MidiDeviceInfo& rhs) { 129f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov return (lhs.mType == rhs.mType && lhs.mId == rhs.mId && 130f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov areVectorsEqual(lhs.mInputPortNames, rhs.mInputPortNames) && 131f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov areVectorsEqual(lhs.mOutputPortNames, rhs.mOutputPortNames) && 132f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov lhs.mProperties == rhs.mProperties && 133f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov lhs.mIsPrivate == rhs.mIsPrivate); 134f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov} 135f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov 136f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov} // namespace midi 137f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov} // namespace media 138f28256f3113212db62aa8527b9ceae4caa414be3Mikhail Naganov} // namespace android 139