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