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
FmqType(const std::string & nsp,const std::string & name,Scope * parent,const std::string & definedName)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
isFmq() const31 bool FmqType::isFmq() const {
32 return true;
33 }
34
templatedTypeName() const35 std::string FmqType::templatedTypeName() const {
36 return mName;
37 }
38
fullName() const39 std::string FmqType::fullName() const {
40 return mNamespace +
41 (mNamespace.empty() ? "" : "::") +
42 mName + "<" + mElementType->getCppStackType(true) + ">";
43 }
44
getCppType(StorageMode mode,bool) const45 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
emitReaderWriter(Formatter & out,const std::string & name,const std::string & parcelObj,bool parcelObjIsPointer,bool isReader,ErrorMode mode) const63 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
emitReaderWriterEmbedded(Formatter & out,size_t,const std::string & name,const std::string &,bool nameIsPointer,const std::string & parcelObj,bool parcelObjIsPointer,bool isReader,ErrorMode mode,const std::string & parentName,const std::string & offsetText) const119 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
deepIsJavaCompatible(std::unordered_set<const Type * > *) const146 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
getAlignmentAndSize(size_t * align,size_t * size) const154 void FmqType::getAlignmentAndSize(
155 size_t *align, size_t *size) const {
156 *align = 8; // MQDescriptor<>
157 *size = assertion.size();
158 }
159
needsEmbeddedReadWrite() const160 bool FmqType::needsEmbeddedReadWrite() const {
161 return true;
162 }
163
resultNeedsDeref() const164 bool FmqType::resultNeedsDeref() const {
165 return true;
166 }
167
isCompatibleElementType(const Type * elementType) const168 bool FmqType::isCompatibleElementType(const Type* elementType) const {
169 return (!elementType->isInterface() && !elementType->needsEmbeddedReadWrite());
170 }
171
getVtsType() const172 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
getVtsValueName() const183 std::string FmqType::getVtsValueName() const {
184 return "fmq_value";
185 }
186 } // namespace android
187
188