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