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
24 namespace android {
25
FmqType(const char * nsp,const char * name)26 FmqType::FmqType(const char *nsp, const char *name)
27 : mNamespace(nsp), mName(name) {
28 }
29
typeName() const30 std::string FmqType::typeName() const {
31 return mName + " of " + mElementType->typeName();
32 }
33
fullName() const34 std::string FmqType::fullName() const {
35 return mNamespace +
36 (mNamespace.empty() ? "" : "::") +
37 mName + "<" + mElementType->getCppStackType(true) + ">";
38 }
39
getCppType(StorageMode mode,bool) const40 std::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
emitReaderWriter(Formatter & out,const std::string & name,const std::string & parcelObj,bool parcelObjIsPointer,bool isReader,ErrorMode mode) const58 void 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
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) const114 void 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
isJavaCompatible() const141 bool FmqType::isJavaCompatible() const {
142 return false;
143 }
144
145 // All MQDescriptor<T, flavor> have the same size.
146 static HidlTypeAssertion assertion(
147 "MQDescriptor<char, ::android::hardware::kSynchronizedReadWrite>", 32);
148
getAlignmentAndSize(size_t * align,size_t * size) const149 void FmqType::getAlignmentAndSize(
150 size_t *align, size_t *size) const {
151 *align = 8; // MQDescriptor<>
152 *size = assertion.size();
153 }
154
needsEmbeddedReadWrite() const155 bool FmqType::needsEmbeddedReadWrite() const {
156 return true;
157 }
158
resultNeedsDeref() const159 bool FmqType::resultNeedsDeref() const {
160 return true;
161 }
162
isCompatibleElementType(Type * elementType) const163 bool FmqType::isCompatibleElementType(Type *elementType) const {
164 return (!elementType->isInterface() && !elementType->needsEmbeddedReadWrite());
165 }
166
getVtsType() const167 std::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
getVtsValueName() const178 std::string FmqType::getVtsValueName() const {
179 return "fmq_value";
180 }
181 } // namespace android
182
183