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 #include "FmqType.h" 18 19 #include "HidlTypeAssertion.h" 20 21 #include <android-base/logging.h> 22 #include <hidl-util/Formatter.h> 23 #include <string> 24 25 namespace android { 26 27 FmqType::FmqType(const std::string& nsp, const std::string& name, Scope* parent, 28 const std::string& definedName) 29 : TemplatedType(parent, definedName), mNamespace(nsp), mName(name) {} 30 31 bool FmqType::isFmq() const { 32 return true; 33 } 34 35 std::string FmqType::templatedTypeName() const { 36 return mName; 37 } 38 39 std::string FmqType::fullName() const { 40 return mNamespace + 41 (mNamespace.empty() ? "" : "::") + 42 mName + "<" + mElementType->getCppStackType(true) + ">"; 43 } 44 45 std::string FmqType::getCppType( 46 StorageMode mode, 47 bool) const { 48 49 const std::string base = fullName(); 50 51 switch (mode) { 52 case StorageMode_Stack: 53 return base; 54 55 case StorageMode_Argument: 56 return "const " + base + "&"; 57 58 case StorageMode_Result: 59 return "const " + base + "*"; 60 } 61 } 62 63 void FmqType::emitReaderWriter( 64 Formatter &out, 65 const std::string &name, 66 const std::string &parcelObj, 67 bool parcelObjIsPointer, 68 bool isReader, 69 ErrorMode mode) const { 70 const std::string parentName = "_hidl_" + name + "_parent"; 71 72 out << "size_t " << parentName << ";\n\n"; 73 74 const std::string parcelObjDeref = 75 parcelObj + (parcelObjIsPointer ? "->" : "."); 76 77 if (isReader) { 78 out << "_hidl_err = " 79 << parcelObjDeref 80 << "readBuffer(" 81 << "sizeof(*" 82 << name 83 << "), &" 84 << parentName 85 << ", " 86 << " reinterpret_cast<const void **>(" 87 << "&" << name 88 << "));\n\n"; 89 90 handleError(out, mode); 91 } else { 92 out << "_hidl_err = " 93 << parcelObjDeref 94 << "writeBuffer(&" 95 << name 96 << ", sizeof(" 97 << name 98 << "), &" 99 << parentName 100 << ");\n"; 101 102 handleError(out, mode); 103 } 104 105 emitReaderWriterEmbedded( 106 out, 107 0 /* depth */, 108 name, 109 name /* sanitizedName */, 110 isReader /* nameIsPointer */, 111 parcelObj, 112 parcelObjIsPointer, 113 isReader, 114 mode, 115 parentName, 116 "0 /* parentOffset */"); 117 } 118 119 void FmqType::emitReaderWriterEmbedded( 120 Formatter &out, 121 size_t /* depth */, 122 const std::string &name, 123 const std::string & /* sanitizedName */, 124 bool nameIsPointer, 125 const std::string &parcelObj, 126 bool parcelObjIsPointer, 127 bool isReader, 128 ErrorMode mode, 129 const std::string &parentName, 130 const std::string &offsetText) const { 131 emitReaderWriterEmbeddedForTypeName( 132 out, 133 name, 134 nameIsPointer, 135 parcelObj, 136 parcelObjIsPointer, 137 isReader, 138 mode, 139 parentName, 140 offsetText, 141 fullName(), 142 "" /* childName */, 143 mNamespace); 144 } 145 146 bool FmqType::deepIsJavaCompatible(std::unordered_set<const Type*>* /* visited */) const { 147 return false; 148 } 149 150 // All MQDescriptor<T, flavor> have the same size. 151 static HidlTypeAssertion assertion( 152 "MQDescriptor<char, ::android::hardware::kSynchronizedReadWrite>", 32); 153 154 void FmqType::getAlignmentAndSize( 155 size_t *align, size_t *size) const { 156 *align = 8; // MQDescriptor<> 157 *size = assertion.size(); 158 } 159 160 bool FmqType::needsEmbeddedReadWrite() const { 161 return true; 162 } 163 164 bool FmqType::resultNeedsDeref() const { 165 return true; 166 } 167 168 bool FmqType::isCompatibleElementType(const Type* elementType) const { 169 return (!elementType->isInterface() && !elementType->needsEmbeddedReadWrite()); 170 } 171 172 std::string FmqType::getVtsType() const { 173 if (mName == "MQDescriptorSync") { 174 return "TYPE_FMQ_SYNC"; 175 } else if (mName == "MQDescriptorUnsync") { 176 return "TYPE_FMQ_UNSYNC"; 177 } 178 179 CHECK(false) << "Invalid FmqType."; 180 return ""; 181 } 182 183 std::string FmqType::getVtsValueName() const { 184 return "fmq_value"; 185 } 186 } // namespace android 187 188