blob: 64626e78f0035a346180b523d20b21fd2d2e4257 [file] [log] [blame]
Martijn Coenen99e6beb2016-12-01 15:48:42 +01001/*
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 "MemoryType.h"
18
Andreas Huber6755e9d2017-04-06 11:09:07 -070019#include "HidlTypeAssertion.h"
20
Martijn Coenen99e6beb2016-12-01 15:48:42 +010021#include <hidl-util/Formatter.h>
22#include <android-base/logging.h>
23
24namespace android {
25
Neel Mehta3b414a82019-07-02 15:47:48 -070026MemoryType::MemoryType(Scope* parent) : Type(parent, "memory") {}
Martijn Coenen99e6beb2016-12-01 15:48:42 +010027
Martijn Coenen99e6beb2016-12-01 15:48:42 +010028std::string MemoryType::getCppType(StorageMode mode,
29 bool specifyNamespaces) const {
30 const std::string base =
31 std::string(specifyNamespaces ? "::android::hardware::" : "")
32 + "hidl_memory";
33
34 switch (mode) {
35 case StorageMode_Stack:
36 return base;
37
38 case StorageMode_Argument:
39 return "const " + base + "&";
40
41 case StorageMode_Result:
42 return "const " + base + "*";
43 }
44}
45
Steven Moreland1a8d20f2017-06-08 13:14:03 -070046std::string MemoryType::typeName() const {
47 return "memory";
48}
49
Martijn Coenen99e6beb2016-12-01 15:48:42 +010050std::string MemoryType::getVtsType() const {
Keun Soo Yimb349e012017-01-06 16:51:32 -080051 return "TYPE_HIDL_MEMORY";
Martijn Coenen99e6beb2016-12-01 15:48:42 +010052}
53
Ytai Ben-Tsvi03f644b2019-11-12 10:32:17 -080054std::string MemoryType::getJavaType(bool /* forInitializer */) const {
55 return "android.os.HidlMemory";
56}
57
58std::string MemoryType::getJavaSuffix() const {
59 return "HidlMemory";
60}
61
62void MemoryType::emitJavaFieldInitializer(
63 Formatter &out, const std::string &fieldName) const {
64 const std::string fieldDeclaration = getJavaType(false) + " " + fieldName;
65 emitJavaFieldDefaultInitialValue(out, fieldDeclaration);
66}
67
68void MemoryType::emitJavaFieldDefaultInitialValue(
69 Formatter &out, const std::string &declaredFieldName) const {
70 out << declaredFieldName
71 << " = null;\n";
72}
73
74void MemoryType::emitJavaFieldReaderWriter(Formatter& out,
75 size_t /* depth */,
76 const std::string& parcelName,
77 const std::string& blobName,
78 const std::string& fieldName,
79 const std::string& offset,
80 bool isReader) const {
81 if (isReader) {
82 out << "try {\n";
83 out.indent();
84 out << fieldName
85 << " = "
86 << parcelName
87 << ".readEmbeddedHidlMemory(\n";
88
89 out << blobName << ".getFieldHandle(" << offset << "),\n"
90 << blobName << ".handle(),\n"
91 << offset
92 << ").dup();\n";
93 out.unindent();
94 out << "} catch (java.io.IOException e) {\n";
95 out.indent();
96 out << "throw new RuntimeException(e);\n";
97 out.unindent();
98 out << "}\n";
99
100 return;
101 }
102
103 out << blobName
104 << ".putHidlMemory("
105 << offset
106 << ", "
107 << fieldName
108 << ");\n";
109}
110
111void MemoryType::emitJavaReaderWriter(Formatter& out,
112 const std::string& parcelObj,
113 const std::string& argName,
114 bool isReader) const {
115 if (isReader) {
116 // The weird-looking lambda code below is intended to replace an
117 // IOException with a RuntimeException within an expression context.
118 out << "((java.util.function.Function<android.os.HwParcel, android.os.HidlMemory>)"
119 " _parcel -> {\n";
120 out.indent();
121 out << "try {\n";
122 out.indent();
123 out << "return _parcel.readHidlMemory().dup();\n";
124 out.unindent();
125 out << "} catch (java.io.IOException e) {\n";
126 out.indent();
127 out << "throw new RuntimeException(e);\n";
128 out.unindent();
129 out << "}\n";
130 out.unindent();
131 out << "}).apply(" << parcelObj << ");\n";
132 } else {
133 out << parcelObj
134 << ".writeHidlMemory("
135 << argName
136 << ");\n";
137 }
138}
139
Martijn Coenen99e6beb2016-12-01 15:48:42 +0100140void MemoryType::emitReaderWriter(
141 Formatter &out,
142 const std::string &name,
143 const std::string &parcelObj,
144 bool parcelObjIsPointer,
145 bool isReader,
146 ErrorMode mode) const {
147 const std::string parentName = "_hidl_" + name + "_parent";
148 out << "size_t " << parentName << ";\n\n";
149
150 const std::string parcelObjDeref =
151 parcelObj + (parcelObjIsPointer ? "->" : ".");
152
153 if (isReader) {
Martijn Coenen6a082c62017-01-11 12:47:02 +0100154 out << "_hidl_err = "
Martijn Coenen99e6beb2016-12-01 15:48:42 +0100155 << parcelObjDeref
Martijn Coenenb2a861c2017-04-18 15:54:25 -0700156 << "readBuffer("
157 << "sizeof(*"
158 << name
159 << "), &"
Martijn Coenen99e6beb2016-12-01 15:48:42 +0100160 << parentName
Martijn Coenen6a082c62017-01-11 12:47:02 +0100161 << ", "
162 << " reinterpret_cast<const void **>("
163 << "&" << name
164 << "));\n\n";
Martijn Coenen99e6beb2016-12-01 15:48:42 +0100165
Martijn Coenen6a082c62017-01-11 12:47:02 +0100166 handleError(out, mode);
Martijn Coenen99e6beb2016-12-01 15:48:42 +0100167 } else {
168 out << "_hidl_err = "
169 << parcelObjDeref
170 << "writeBuffer(&"
171 << name
172 << ", sizeof("
173 << name
174 << "), &"
175 << parentName
176 << ");\n";
177
178 handleError(out, mode);
179 }
180
181 emitReaderWriterEmbedded(
182 out,
183 0 /* depth */,
184 name,
185 name /* sanitizedName */,
186 isReader /* nameIsPointer */,
187 parcelObj,
188 parcelObjIsPointer,
189 isReader,
190 mode,
191 parentName,
192 "0 /* parentOffset */");
193}
194
195void MemoryType::emitReaderWriterEmbedded(
196 Formatter &out,
197 size_t /* depth */,
198 const std::string &name,
199 const std::string & /*sanitizedName*/,
200 bool nameIsPointer,
201 const std::string &parcelObj,
202 bool parcelObjIsPointer,
203 bool isReader,
204 ErrorMode mode,
205 const std::string &parentName,
206 const std::string &offsetText) const {
207 emitReaderWriterEmbeddedForTypeName(
208 out,
209 name,
210 nameIsPointer,
211 parcelObj,
212 parcelObjIsPointer,
213 isReader,
214 mode,
215 parentName,
216 offsetText,
217 "::android::hardware::hidl_memory",
218 "" /* childName */,
219 "::android::hardware");
220}
221
222bool MemoryType::needsEmbeddedReadWrite() const {
223 return true;
224}
225
226bool MemoryType::resultNeedsDeref() const {
227 return true;
228}
229
Steven Moreland60864a42017-06-08 14:02:26 -0700230bool MemoryType::isMemory() const {
231 return true;
232}
233
Timur Iskhakov5dc72fe2017-09-07 23:13:44 -0700234bool MemoryType::deepIsJavaCompatible(std::unordered_set<const Type*>* /* visited */) const {
Ytai Ben-Tsvi03f644b2019-11-12 10:32:17 -0800235 return true;
Martijn Coenen99e6beb2016-12-01 15:48:42 +0100236}
237
Andreas Huber6755e9d2017-04-06 11:09:07 -0700238static HidlTypeAssertion assertion("hidl_memory", 40 /* size */);
Martijn Coenen99e6beb2016-12-01 15:48:42 +0100239void MemoryType::getAlignmentAndSize(size_t *align, size_t *size) const {
Andreas Huber60d3b222017-03-30 09:10:56 -0700240 *align = 8; // hidl_memory
Andreas Huber6755e9d2017-04-06 11:09:07 -0700241 *size = assertion.size();
Martijn Coenen99e6beb2016-12-01 15:48:42 +0100242}
243
Steven Moreland6ec9eb92018-02-16 14:21:49 -0800244void MemoryType::emitVtsTypeDeclarations(Formatter& out) const {
Martijn Coenen99e6beb2016-12-01 15:48:42 +0100245 out << "type: " << getVtsType() << "\n";
Martijn Coenen99e6beb2016-12-01 15:48:42 +0100246}
247
248} // namespace android
249