blob: 9bf1b33684c54ca412518e8d5808bfedbd34329a [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
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
Andreas Huber881227d2016-08-02 14:20:21 -070017#include "AST.h"
18
19#include "Coordinator.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070020#include "EnumType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070021#include "Interface.h"
22#include "Method.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070023#include "ScalarType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070024#include "Scope.h"
25
Andreas Huberdca261f2016-08-04 13:47:51 -070026#include <algorithm>
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070027#include <hidl-util/Formatter.h>
Steven Moreland5708edf2016-11-04 15:33:31 +000028#include <hidl-util/StringHelper.h>
Andreas Huber881227d2016-08-02 14:20:21 -070029#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070030#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070031#include <vector>
32
33namespace android {
34
Andreas Huberb82318c2016-08-02 14:45:54 -070035status_t AST::generateCpp(const std::string &outputPath) const {
36 status_t err = generateInterfaceHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070037
38 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070039 err = generateStubHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070040 }
41
42 if (err == OK) {
Steven Moreland40786312016-08-16 10:29:40 -070043 err = generateHwBinderHeader(outputPath);
44 }
45
46 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070047 err = generateProxyHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070048 }
49
50 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070051 err = generateAllSource(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070052 }
53
Steven Moreland69e7c702016-09-09 11:16:32 -070054 if (err == OK) {
55 generatePassthroughHeader(outputPath);
56 }
57
Andreas Huber881227d2016-08-02 14:20:21 -070058 return err;
59}
60
Andreas Huber737080b2016-08-02 15:38:04 -070061void AST::getPackageComponents(
62 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070063 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070064}
65
66void AST::getPackageAndVersionComponents(
67 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070068 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070069}
70
Steven Moreland5708edf2016-11-04 15:33:31 +000071std::string AST::makeHeaderGuard(const std::string &baseName,
72 bool indicateGenerated) const {
73 std::string guard;
Andreas Huber881227d2016-08-02 14:20:21 -070074
Steven Moreland5708edf2016-11-04 15:33:31 +000075 if (indicateGenerated) {
76 guard += "HIDL_GENERATED_";
77 }
78
79 guard += StringHelper::Uppercase(mPackage.tokenName());
Andreas Huber881227d2016-08-02 14:20:21 -070080 guard += "_";
Steven Moreland5708edf2016-11-04 15:33:31 +000081 guard += StringHelper::Uppercase(baseName);
82 guard += "_H";
Andreas Huber881227d2016-08-02 14:20:21 -070083
84 return guard;
85}
86
Steven Morelandee88eed2016-10-31 17:49:00 -070087// static
88void AST::generateCppPackageInclude(
89 Formatter &out,
90 const FQName &package,
91 const std::string &klass) {
92
93 out << "#include <";
94
95 std::vector<std::string> components;
96 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
97
98 for (const auto &component : components) {
99 out << component << "/";
100 }
101
102 out << klass
103 << ".h>\n";
104}
105
Andreas Huber881227d2016-08-02 14:20:21 -0700106void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
107 std::vector<std::string> packageComponents;
108 getPackageAndVersionComponents(
109 &packageComponents, true /* cpp_compatible */);
110
111 if (enter) {
112 for (const auto &component : packageComponents) {
113 out << "namespace " << component << " {\n";
114 }
Andreas Huber0e00de42016-08-03 09:56:02 -0700115
Andreas Huber2831d512016-08-15 09:33:47 -0700116 out.setNamespace(mPackage.cppNamespace() + "::");
Andreas Huber881227d2016-08-02 14:20:21 -0700117 } else {
Andreas Huber0e00de42016-08-03 09:56:02 -0700118 out.setNamespace(std::string());
119
Andreas Huber881227d2016-08-02 14:20:21 -0700120 for (auto it = packageComponents.rbegin();
121 it != packageComponents.rend();
122 ++it) {
123 out << "} // namespace " << *it << "\n";
124 }
125 }
126}
127
Andreas Huberb82318c2016-08-02 14:45:54 -0700128status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700129
Andreas Huberb82318c2016-08-02 14:45:54 -0700130 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700131 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700132 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700133
134 std::string ifaceName;
135 bool isInterface = true;
136 if (!AST::isInterface(&ifaceName)) {
137 ifaceName = "types";
138 isInterface = false;
139 }
140 path.append(ifaceName);
141 path.append(".h");
142
Andreas Huberd2943e12016-08-05 11:59:31 -0700143 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700144 FILE *file = fopen(path.c_str(), "w");
145
146 if (file == NULL) {
147 return -errno;
148 }
149
150 Formatter out(file);
151
152 const std::string guard = makeHeaderGuard(ifaceName);
153
154 out << "#ifndef " << guard << "\n";
155 out << "#define " << guard << "\n\n";
156
Andreas Huber737080b2016-08-02 15:38:04 -0700157 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700158 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700159 }
160
161 if (!mImportedNames.empty()) {
162 out << "\n";
163 }
164
Steven Moreland0693f312016-11-09 15:06:14 -0800165 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800166 if (isIBase()) {
167 out << "// skipped #include IServiceNotification.h\n\n";
168 } else {
169 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
170 }
Steven Moreland0693f312016-11-09 15:06:14 -0800171 }
172
Yifan Hongc8934042016-11-17 17:10:52 -0800173 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700174 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700175
176 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200177 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700178 }
179
Martijn Coenenaf712c02016-11-16 15:26:27 +0100180 out << "#include <utils/NativeHandle.h>\n";
181 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700182
183 enterLeaveNamespace(out, true /* enter */);
184 out << "\n";
185
186 if (isInterface) {
187 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700188 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700189
190 const Interface *iface = mRootScope->getInterface();
191 const Interface *superType = iface->superType();
192
Steven Moreland40786312016-08-16 10:29:40 -0700193 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800194 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700195 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000196 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700197 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700198 }
199
200 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700201
202 out.indent();
203
Andreas Huber881227d2016-08-02 14:20:21 -0700204 }
205
206 status_t err = emitTypeDeclarations(out);
207
208 if (err != OK) {
209 return err;
210 }
211
212 if (isInterface) {
213 const Interface *iface = mRootScope->getInterface();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700214 const Interface *superType = iface->superType();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700215 const std::string baseName = iface->getBaseName();
Steven Moreland19d5c172016-10-20 19:20:25 -0700216 out << "constexpr static ::android::hardware::hidl_version version = {"
Martijn Coenena21f1492016-09-08 15:55:14 +0200217 << mPackage.getPackageMajorVersion() << ","
218 << mPackage.getPackageMinorVersion() << "};\n";
Steven Moreland19d5c172016-10-20 19:20:25 -0700219 out << "virtual const ::android::hardware::hidl_version&"
220 << "getInterfaceVersion() const {\n";
Martijn Coenena21f1492016-09-08 15:55:14 +0200221 out.indent();
222 out << "return version;\n";
223 out.unindent();
224 out << "}\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800225 out << "virtual bool isRemote() const ";
226 if (!isIBase()) {
227 out << "override ";
228 }
229 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800230
Andreas Huber881227d2016-08-02 14:20:21 -0700231 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700232 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700233
Andreas Huber881227d2016-08-02 14:20:21 -0700234 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800235 const TypedVar *elidedReturn = method->canElideCallback();
236
237 if (elidedReturn == nullptr && returnsValue) {
238 out << "using "
239 << method->name()
240 << "_cb = std::function<void("
241 << Method::GetArgSignature(method->results(),
242 true /* specify namespaces */)
243 << ")>;\n";
244 }
Andreas Huber881227d2016-08-02 14:20:21 -0700245
Andreas Huber3599d922016-08-09 10:42:57 -0700246 method->dumpAnnotations(out);
247
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700248 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700249 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700250 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700251 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700252 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700253 }
254
255 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700256 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700257 << Method::GetArgSignature(method->args(),
258 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700259
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700260 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700261 if (!method->args().empty()) {
262 out << ", ";
263 }
264
Steven Moreland67f67b42016-09-29 08:59:02 -0700265 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700266 }
267
Yifan Hong10fe0b52016-10-19 14:20:17 -0700268 out << ")";
269 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800270 if (!isIBase()) {
271 out << " override";
272 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700273 out << " {\n";
274 out.indent();
275 method->cppImpl(out);
276 out.unindent();
277 out << "\n}\n";
278 } else {
279 out << " = 0;\n";
280 }
Andreas Huber881227d2016-08-02 14:20:21 -0700281 }
Steven Moreland40786312016-08-16 10:29:40 -0700282
Yifan Hong3d746092016-12-07 14:26:33 -0800283 out << "// cast static functions\n";
284 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700285
Yifan Hong3d746092016-12-07 14:26:33 -0800286 for (const Interface *superType : iface->typeChain()) {
287 out << "static "
288 << childTypeResult
289 << " castFrom("
290 << superType->getCppArgumentType()
291 << " parent"
292 << ");\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700293 }
294
Steven Morelandd39133b2016-11-11 12:30:08 -0800295 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700296
Yifan Hongc8934042016-11-17 17:10:52 -0800297 if (isIBase()) {
298 out << "// skipped DECLARE_SERVICE_MANAGER_INTERACTIONS\n\n";
299 } else {
300 out << "DECLARE_SERVICE_MANAGER_INTERACTIONS(" << baseName << ")\n\n";
301 }
Yifan Hong158655a2016-11-08 12:34:07 -0800302
303 out << "private: static int hidlStaticBlock;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700304 }
305
306 if (isInterface) {
307 out.unindent();
308
Andreas Hubere3f769a2016-10-10 10:54:44 -0700309 out << "};\n\n";
310 }
311
312 err = mRootScope->emitGlobalTypeDeclarations(out);
313
314 if (err != OK) {
315 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700316 }
317
318 out << "\n";
319 enterLeaveNamespace(out, false /* enter */);
320
321 out << "\n#endif // " << guard << "\n";
322
323 return OK;
324}
325
Steven Moreland40786312016-08-16 10:29:40 -0700326status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
327 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800328 bool isInterface = AST::isInterface(&ifaceName);
329 const Interface *iface = nullptr;
330 std::string baseName{};
331 std::string klassName{};
332
333 if(isInterface) {
334 iface = mRootScope->getInterface();
335 baseName = iface->getBaseName();
336 klassName = "IHw" + baseName;
337 } else {
338 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700339 }
340
Steven Moreland40786312016-08-16 10:29:40 -0700341 std::string path = outputPath;
342 path.append(mCoordinator->convertPackageRootToPath(mPackage));
343 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
344 path.append(klassName + ".h");
345
Yifan Hong244e82d2016-11-11 11:13:57 -0800346 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700347
348 if (file == NULL) {
349 return -errno;
350 }
351
352 Formatter out(file);
353
354 const std::string guard = makeHeaderGuard(klassName);
355
356 out << "#ifndef " << guard << "\n";
357 out << "#define " << guard << "\n\n";
358
Yifan Hong244e82d2016-11-11 11:13:57 -0800359 if (isInterface) {
360 generateCppPackageInclude(out, mPackage, ifaceName);
361 } else {
362 generateCppPackageInclude(out, mPackage, "types");
363 }
Steven Moreland40786312016-08-16 10:29:40 -0700364
Steven Morelandee88eed2016-10-31 17:49:00 -0700365 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700366
367 for (const auto &item : mImportedNames) {
368 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800369 generateCppPackageInclude(out, item, "hwtypes");
370 } else {
371 generateCppPackageInclude(out, item, "Bn" + item.getInterfaceBaseName());
Steven Moreland40786312016-08-16 10:29:40 -0700372 }
Steven Moreland40786312016-08-16 10:29:40 -0700373 }
374
375 out << "\n";
376
Yifan Hong859e53f2016-11-14 19:08:24 -0800377 out << "#include <hidl/HidlTransportSupport.h>\n";
Martijn Coenen93915102016-09-01 01:35:52 +0200378 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700379 out << "#include <hwbinder/IBinder.h>\n";
380 out << "#include <hwbinder/IInterface.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700381
382 out << "\n";
383
384 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700385
Yifan Hong244e82d2016-11-11 11:13:57 -0800386 if (isInterface) {
387 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700388
Yifan Hong244e82d2016-11-11 11:13:57 -0800389 out << "struct "
390 << klassName
391 << " : public "
392 << ifaceName;
Steven Moreland40786312016-08-16 10:29:40 -0700393
Yifan Hong244e82d2016-11-11 11:13:57 -0800394 const Interface *superType = iface->superType();
Steven Moreland40786312016-08-16 10:29:40 -0700395
Yifan Hong244e82d2016-11-11 11:13:57 -0800396 out << ", public ::android::hardware::IInterface";
Steven Moreland40786312016-08-16 10:29:40 -0700397
Yifan Hong244e82d2016-11-11 11:13:57 -0800398 out << " {\n";
Steven Moreland40786312016-08-16 10:29:40 -0700399
Yifan Hong244e82d2016-11-11 11:13:57 -0800400 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700401
Yifan Hong244e82d2016-11-11 11:13:57 -0800402 out << "DECLARE_HWBINDER_META_INTERFACE(" << baseName << ");\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700403
Yifan Hong244e82d2016-11-11 11:13:57 -0800404 out.unindent();
405
406 out << "};\n\n";
407 }
408
409 status_t err = mRootScope->emitGlobalHwDeclarations(out);
410 if (err != OK) {
411 return err;
412 }
Steven Moreland40786312016-08-16 10:29:40 -0700413
414 enterLeaveNamespace(out, false /* enter */);
415
416 out << "\n#endif // " << guard << "\n";
417
418 return OK;
419}
420
Andreas Huber881227d2016-08-02 14:20:21 -0700421status_t AST::emitTypeDeclarations(Formatter &out) const {
422 return mRootScope->emitTypeDeclarations(out);
423}
424
Steven Morelanda7a421a2016-09-07 08:35:18 -0700425status_t AST::generateStubMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700426 const Method *method) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700427 out << "inline ";
428
Yifan Hong068c5522016-10-31 14:07:25 -0700429 method->generateCppSignature(out);
Steven Morelanda7a421a2016-09-07 08:35:18 -0700430
431 const bool returnsValue = !method->results().empty();
432 const TypedVar *elidedReturn = method->canElideCallback();
433 out << " {\n";
434 out.indent();
435 out << "return mImpl->"
436 << method->name()
437 << "(";
438 bool first = true;
439 for (const auto &arg : method->args()) {
440 if (!first) {
441 out << ", ";
442 }
443 first = false;
444 out << arg->name();
445 }
446 if (returnsValue && elidedReturn == nullptr) {
447 if (!method->args().empty()) {
448 out << ", ";
449 }
450
451 out << "_hidl_cb";
452 }
453 out << ");\n";
454 out.unindent();
455 out << "}";
456
457 out << ";\n";
458
459 return OK;
460}
461
Steven Moreland69e7c702016-09-09 11:16:32 -0700462status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700463 const Method *method) const {
464 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700465
466 out << " {\n";
467 out.indent();
468
469 const bool returnsValue = !method->results().empty();
470 const TypedVar *elidedReturn = method->canElideCallback();
471
Steven Moreland67f67b42016-09-29 08:59:02 -0700472 if (returnsValue && elidedReturn == nullptr) {
473 generateCheckNonNull(out, "_hidl_cb");
474 }
475
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700476 generateCppInstrumentationCall(
477 out,
478 InstrumentationEvent::PASSTHROUGH_ENTRY,
479 method);
480
481 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700482
483 if (method->isOneway()) {
484 out << "addOnewayTask([this";
485 for (const auto &arg : method->args()) {
486 out << ", " << arg->name();
487 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700488 out << "] {\n";
489 out.indent();
490 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700491 }
492
493 out << "mImpl->"
494 << method->name()
495 << "(";
496
497 bool first = true;
498 for (const auto &arg : method->args()) {
499 if (!first) {
500 out << ", ";
501 }
502 first = false;
503 out << arg->name();
504 }
505 if (returnsValue && elidedReturn == nullptr) {
506 if (!method->args().empty()) {
507 out << ", ";
508 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800509 out << "[&](";
510 first = true;
511 for (const auto &arg : method->results()) {
512 if (!first) {
513 out << ", ";
514 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700515
Yifan Honga47eef32016-12-12 10:38:54 -0800516 out << "const auto &_hidl_out_" << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800517
518 first = false;
519 }
520
521 out << ") {\n";
522 out.indent();
523 status_t status = generateCppInstrumentationCall(
524 out,
525 InstrumentationEvent::PASSTHROUGH_EXIT,
526 method);
527 if (status != OK) {
528 return status;
529 }
530
531 out << "_hidl_cb(";
532 first = true;
533 for (const auto &arg : method->results()) {
534 if (!first) {
535 out << ", ";
536 }
537
Yifan Honga47eef32016-12-12 10:38:54 -0800538 out << "_hidl_out_" << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800539
540 first = false;
541 }
542 out << ");\n";
543 out.unindent();
544 out << "});\n\n";
545 } else {
546 out << ");\n\n";
547 if (elidedReturn != nullptr) {
548 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800549 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800550 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000551 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800552 }
553 status_t status = generateCppInstrumentationCall(
554 out,
555 InstrumentationEvent::PASSTHROUGH_EXIT,
556 method);
557 if (status != OK) {
558 return status;
559 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700560 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700561
562 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700563 out.unindent();
564 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700565 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700566
567 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700568
569 out.unindent();
570 out << "}\n";
571
572 return OK;
573}
574
Yifan Hong068c5522016-10-31 14:07:25 -0700575status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700576
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700577 const Interface *iface = mRootScope->getInterface();
578
Yifan Hong10fe0b52016-10-19 14:20:17 -0700579 const Interface *prevIterface = nullptr;
580 for (const auto &tuple : iface->allMethodsFromRoot()) {
581 const Method *method = tuple.method();
582 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700583
Yifan Hong10fe0b52016-10-19 14:20:17 -0700584 if(prevIterface != superInterface) {
585 if (prevIterface != nullptr) {
586 out << "\n";
587 }
588 out << "// Methods from "
589 << superInterface->fullName()
590 << " follow.\n";
591 prevIterface = superInterface;
592 }
Yifan Hong068c5522016-10-31 14:07:25 -0700593 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700594
Yifan Hong10fe0b52016-10-19 14:20:17 -0700595 if (err != OK) {
596 return err;
597 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700598 }
599
Yifan Hong10fe0b52016-10-19 14:20:17 -0700600 out << "\n";
601
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700602 return OK;
603}
604
Andreas Huberb82318c2016-08-02 14:45:54 -0700605status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700606 std::string ifaceName;
607 if (!AST::isInterface(&ifaceName)) {
608 // types.hal does not get a stub header.
609 return OK;
610 }
611
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700612 const Interface *iface = mRootScope->getInterface();
613 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700614 const std::string klassName = "Bn" + baseName;
Andreas Huber881227d2016-08-02 14:20:21 -0700615
Andreas Huberb82318c2016-08-02 14:45:54 -0700616 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700617 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700618 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700619 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700620 path.append(".h");
621
Andreas Huberd2943e12016-08-05 11:59:31 -0700622 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700623 FILE *file = fopen(path.c_str(), "w");
624
625 if (file == NULL) {
626 return -errno;
627 }
628
629 Formatter out(file);
630
Steven Moreland40786312016-08-16 10:29:40 -0700631 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700632
633 out << "#ifndef " << guard << "\n";
634 out << "#define " << guard << "\n\n";
635
Steven Morelandee88eed2016-10-31 17:49:00 -0700636 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
637 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700638
639 enterLeaveNamespace(out, true /* enter */);
640 out << "\n";
641
642 out << "struct "
643 << "Bn"
644 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700645 << " : public ::android::hardware::BnInterface<I"
646 << baseName << ", IHw" << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700647 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700648
649 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700650 out << "explicit Bn"
651 << baseName
652 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
653 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700654 out << "::android::status_t onTransact(\n";
655 out.indent();
656 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700657 out << "uint32_t _hidl_code,\n";
658 out << "const ::android::hardware::Parcel &_hidl_data,\n";
659 out << "::android::hardware::Parcel *_hidl_reply,\n";
660 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700661 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700662 out.unindent();
663 out.unindent();
664
Yifan Hong068c5522016-10-31 14:07:25 -0700665 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
666 return generateStubMethod(out, method);
667 });
Steven Moreland9c387612016-09-07 09:54:26 -0700668
669 if (err != OK) {
670 return err;
671 }
672
Zhuoyao Zhangde578002016-09-07 18:24:17 -0700673
Andreas Huber881227d2016-08-02 14:20:21 -0700674 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700675 out << "};\n\n";
676
677 enterLeaveNamespace(out, false /* enter */);
678
679 out << "\n#endif // " << guard << "\n";
680
681 return OK;
682}
683
Andreas Huberb82318c2016-08-02 14:45:54 -0700684status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700685 std::string ifaceName;
686 if (!AST::isInterface(&ifaceName)) {
687 // types.hal does not get a proxy header.
688 return OK;
689 }
690
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700691 const Interface *iface = mRootScope->getInterface();
692 const std::string baseName = iface->getBaseName();
Andreas Huber881227d2016-08-02 14:20:21 -0700693
Andreas Huberb82318c2016-08-02 14:45:54 -0700694 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700695 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700696 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700697 path.append("Bp");
698 path.append(baseName);
699 path.append(".h");
700
Andreas Huberd2943e12016-08-05 11:59:31 -0700701 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700702 FILE *file = fopen(path.c_str(), "w");
703
704 if (file == NULL) {
705 return -errno;
706 }
707
708 Formatter out(file);
709
710 const std::string guard = makeHeaderGuard("Bp" + baseName);
711
712 out << "#ifndef " << guard << "\n";
713 out << "#define " << guard << "\n\n";
714
715 std::vector<std::string> packageComponents;
716 getPackageAndVersionComponents(
717 &packageComponents, false /* cpp_compatible */);
718
Steven Morelandee88eed2016-10-31 17:49:00 -0700719 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
720 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700721
722 enterLeaveNamespace(out, true /* enter */);
723 out << "\n";
724
725 out << "struct "
726 << "Bp"
727 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700728 << " : public ::android::hardware::BpInterface<IHw"
729 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700730 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700731
732 out.indent();
733
734 out << "explicit Bp"
735 << baseName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700736 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700737 << "\n\n";
738
Yifan Hong10fe0b52016-10-19 14:20:17 -0700739 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700740
Yifan Hong068c5522016-10-31 14:07:25 -0700741 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
742 method->generateCppSignature(out);
743 out << " override;\n";
744 return OK;
745 });
Steven Moreland9c387612016-09-07 09:54:26 -0700746
747 if (err != OK) {
748 return err;
749 }
Andreas Huber881227d2016-08-02 14:20:21 -0700750
751 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700752 out << "};\n\n";
753
754 enterLeaveNamespace(out, false /* enter */);
755
756 out << "\n#endif // " << guard << "\n";
757
758 return OK;
759}
760
Andreas Huberb82318c2016-08-02 14:45:54 -0700761status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700762
Andreas Huberb82318c2016-08-02 14:45:54 -0700763 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700764 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700765 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700766
767 std::string ifaceName;
768 std::string baseName;
769
Yifan Hongfe95aa22016-10-19 17:26:45 -0700770 const Interface *iface = nullptr;
771 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700772 if (!AST::isInterface(&ifaceName)) {
773 baseName = "types";
774 isInterface = false;
775 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700776 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700777 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700778 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700779 }
780
781 path.append(baseName);
782
783 if (baseName != "types") {
784 path.append("All");
785 }
786
787 path.append(".cpp");
788
Andreas Huberd2943e12016-08-05 11:59:31 -0700789 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700790 FILE *file = fopen(path.c_str(), "w");
791
792 if (file == NULL) {
793 return -errno;
794 }
795
796 Formatter out(file);
797
Steven Moreland05cd4232016-11-21 16:01:12 -0800798 out << "#include <android/log.h>\n";
Martijn Coenen7b295242016-11-04 16:52:56 +0100799 out << "#include <cutils/trace.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700800 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700801 // This is a no-op for IServiceManager itself.
802 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
803
Steven Morelandee88eed2016-10-31 17:49:00 -0700804 generateCppPackageInclude(out, mPackage, "Bp" + baseName);
805 generateCppPackageInclude(out, mPackage, "Bn" + baseName);
806 generateCppPackageInclude(out, mPackage, "Bs" + baseName);
Yifan Hongfe95aa22016-10-19 17:26:45 -0700807
808 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700809 generateCppPackageInclude(out,
810 superType->fqName(),
811 "Bp" + superType->getBaseName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700812 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800813
814 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700815 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700816 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800817 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700818 }
819
820 out << "\n";
821
822 enterLeaveNamespace(out, true /* enter */);
823 out << "\n";
824
825 status_t err = generateTypeSource(out, ifaceName);
826
827 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700828 const Interface *iface = mRootScope->getInterface();
Steven Moreland19d5c172016-10-20 19:20:25 -0700829 out << "constexpr ::android::hardware::hidl_version "
830 << ifaceName
831 << "::version;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700832
833 // need to be put here, generateStubSource is using this.
Steven Morelandd39133b2016-11-11 12:30:08 -0800834 out << "const char* I"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700835 << iface->getBaseName()
836 << "::descriptor(\""
837 << iface->fqName().string()
838 << "\");\n\n";
839
Yifan Hong158655a2016-11-08 12:34:07 -0800840 out << "int I"
841 << iface->getBaseName()
842 << "::hidlStaticBlock = []() -> int {\n";
843 out.indentBlock([&] {
Steven Morelandd39133b2016-11-11 12:30:08 -0800844 out << "::android::hardware::gBnConstructorMap[I"
Yifan Hong158655a2016-11-08 12:34:07 -0800845 << iface->getBaseName()
Steven Morelandd39133b2016-11-11 12:30:08 -0800846 << "::descriptor]\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800847 out.indentBlock(2, [&] {
848 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
849 out.indentBlock([&] {
850 out << "return new Bn"
851 << iface->getBaseName()
852 << "(reinterpret_cast<I"
853 << iface->getBaseName()
854 << " *>(iIntf));\n";
855 });
856 out << "};\n";
857 });
858 out << "return 1;\n";
859 });
860 out << "}();\n\n";
861
Yifan Hongfe95aa22016-10-19 17:26:45 -0700862 err = generateInterfaceSource(out);
863 }
864
865 if (err == OK && isInterface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700866 err = generateProxySource(out, baseName);
867 }
868
869 if (err == OK && isInterface) {
870 err = generateStubSource(out, baseName);
871 }
872
Steven Moreland40786312016-08-16 10:29:40 -0700873 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -0700874 err = generatePassthroughSource(out);
875 }
876
877 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -0700878 const Interface *iface = mRootScope->getInterface();
879
Yifan Hongc8934042016-11-17 17:10:52 -0800880 if (isIBase()) {
881 out << "// skipped IMPLEMENT_SERVICE_MANAGER_INTERACTIONS\n";
882 } else {
883 out << "IMPLEMENT_SERVICE_MANAGER_INTERACTIONS("
884 << baseName << ", "
885 << "\"" << iface->fqName().package()
886 << iface->fqName().atVersion()
887 << "\")\n";
888 }
Steven Moreland40786312016-08-16 10:29:40 -0700889 }
890
Andreas Huber881227d2016-08-02 14:20:21 -0700891 enterLeaveNamespace(out, false /* enter */);
892
893 return err;
894}
895
Steven Moreland67f67b42016-09-29 08:59:02 -0700896// static
897void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
898 out << "if (" << nonNull << " == nullptr) {\n";
899 out.indent();
900 out << "return ::android::hardware::Status::fromExceptionCode(\n";
901 out.indent();
902 out.indent();
903 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
904 out.unindent();
905 out.unindent();
906 out.unindent();
907 out << "}\n\n";
908}
909
Andreas Huber881227d2016-08-02 14:20:21 -0700910status_t AST::generateTypeSource(
911 Formatter &out, const std::string &ifaceName) const {
912 return mRootScope->emitTypeDefinitions(out, ifaceName);
913}
914
Andreas Hubere7ff2282016-08-16 13:50:03 -0700915void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -0700916 Formatter &out,
917 const std::vector<TypedVar *> &args,
918 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700919 if (args.empty()) {
920 return;
921 }
922
923 for (const auto &arg : args) {
924 const Type &type = arg->type();
925
Yifan Hong3b320f82016-11-01 15:15:54 -0700926 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700927 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700928 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700929 << ";\n";
930 }
931
932 out << "\n";
933}
934
Andreas Huber881227d2016-08-02 14:20:21 -0700935void AST::emitCppReaderWriter(
936 Formatter &out,
937 const std::string &parcelObj,
938 bool parcelObjIsPointer,
939 const TypedVar *arg,
940 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -0700941 Type::ErrorMode mode,
942 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700943 const Type &type = arg->type();
944
Andreas Huber881227d2016-08-02 14:20:21 -0700945 type.emitReaderWriter(
946 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700947 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700948 parcelObj,
949 parcelObjIsPointer,
950 isReader,
951 mode);
952}
953
Yifan Hongbf459bc2016-08-23 16:50:37 -0700954void AST::emitCppResolveReferences(
955 Formatter &out,
956 const std::string &parcelObj,
957 bool parcelObjIsPointer,
958 const TypedVar *arg,
959 bool isReader,
960 Type::ErrorMode mode,
961 bool addPrefixToName) const {
962 const Type &type = arg->type();
963 if(type.needsResolveReferences()) {
964 type.emitResolveReferences(
965 out,
966 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
967 isReader, // nameIsPointer
968 parcelObj,
969 parcelObjIsPointer,
970 isReader,
971 mode);
972 }
973}
974
Yifan Hong068c5522016-10-31 14:07:25 -0700975status_t AST::generateProxyMethodSource(Formatter &out,
976 const std::string &klassName,
977 const Method *method,
978 const Interface *superInterface) const {
979
980 method->generateCppSignature(out,
981 klassName,
982 true /* specify namespaces */);
983
984 const bool returnsValue = !method->results().empty();
985 const TypedVar *elidedReturn = method->canElideCallback();
986
Steven Moreland41c6d2e2016-11-07 12:26:54 -0800987 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700988
989 out.indent();
990
991 if (returnsValue && elidedReturn == nullptr) {
992 generateCheckNonNull(out, "_hidl_cb");
993 }
994
995 status_t status = generateCppInstrumentationCall(
996 out,
997 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -0700998 method);
999 if (status != OK) {
1000 return status;
1001 }
1002
1003 out << "::android::hardware::Parcel _hidl_data;\n";
1004 out << "::android::hardware::Parcel _hidl_reply;\n";
1005 out << "::android::status_t _hidl_err;\n";
1006 out << "::android::hardware::Status _hidl_status;\n\n";
1007
1008 declareCppReaderLocals(
1009 out, method->results(), true /* forResults */);
1010
1011 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongc8934042016-11-17 17:10:52 -08001012 out << superInterface->fqName().cppNamespace()
1013 << "::I"
1014 << superInterface->getBaseName();
Yifan Hong068c5522016-10-31 14:07:25 -07001015 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001016 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1017
1018 // First DFS: write all buffers and resolve pointers for parent
1019 for (const auto &arg : method->args()) {
1020 emitCppReaderWriter(
1021 out,
1022 "_hidl_data",
1023 false /* parcelObjIsPointer */,
1024 arg,
1025 false /* reader */,
1026 Type::ErrorMode_Goto,
1027 false /* addPrefixToName */);
1028 }
1029
1030 // Second DFS: resolve references.
1031 for (const auto &arg : method->args()) {
1032 emitCppResolveReferences(
1033 out,
1034 "_hidl_data",
1035 false /* parcelObjIsPointer */,
1036 arg,
1037 false /* reader */,
1038 Type::ErrorMode_Goto,
1039 false /* addPrefixToName */);
1040 }
1041
1042 out << "_hidl_err = remote()->transact("
1043 << method->getSerialId()
1044 << " /* "
1045 << method->name()
1046 << " */, _hidl_data, &_hidl_reply";
1047
1048 if (method->isOneway()) {
1049 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1050 }
1051 out << ");\n";
1052
1053 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1054
1055 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001056 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001057 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1058 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1059
1060
1061 // First DFS: write all buffers and resolve pointers for parent
1062 for (const auto &arg : method->results()) {
1063 emitCppReaderWriter(
1064 out,
1065 "_hidl_reply",
1066 false /* parcelObjIsPointer */,
1067 arg,
1068 true /* reader */,
1069 Type::ErrorMode_Goto,
1070 true /* addPrefixToName */);
1071 }
1072
1073 // Second DFS: resolve references.
1074 for (const auto &arg : method->results()) {
1075 emitCppResolveReferences(
1076 out,
1077 "_hidl_reply",
1078 false /* parcelObjIsPointer */,
1079 arg,
1080 true /* reader */,
1081 Type::ErrorMode_Goto,
1082 true /* addPrefixToName */);
1083 }
1084
1085 if (returnsValue && elidedReturn == nullptr) {
1086 out << "_hidl_cb(";
1087
1088 bool first = true;
1089 for (const auto &arg : method->results()) {
1090 if (!first) {
1091 out << ", ";
1092 }
1093
1094 if (arg->type().resultNeedsDeref()) {
1095 out << "*";
1096 }
1097 out << "_hidl_out_" << arg->name();
1098
1099 first = false;
1100 }
1101
1102 out << ");\n\n";
1103 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001104 }
1105 status = generateCppInstrumentationCall(
1106 out,
1107 InstrumentationEvent::CLIENT_API_EXIT,
1108 method);
1109 if (status != OK) {
1110 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001111 }
1112
1113 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001114 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1115 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001116 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001117 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1118 } else {
1119 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1120 out << "return ::android::hardware::Return<void>();\n\n";
1121 }
1122
1123 out.unindent();
1124 out << "_hidl_error:\n";
1125 out.indent();
1126 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1127 out << "return ::android::hardware::Return<";
1128 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001129 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001130 } else {
1131 out << "void";
1132 }
1133 out << ">(_hidl_status);\n";
1134
1135 out.unindent();
1136 out << "}\n\n";
1137 return OK;
1138}
1139
Andreas Huber881227d2016-08-02 14:20:21 -07001140status_t AST::generateProxySource(
1141 Formatter &out, const std::string &baseName) const {
1142 const std::string klassName = "Bp" + baseName;
1143
1144 out << klassName
1145 << "::"
1146 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001147 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001148
1149 out.indent();
1150 out.indent();
1151
1152 out << ": BpInterface"
Steven Moreland40786312016-08-16 10:29:40 -07001153 << "<IHw"
Andreas Huber881227d2016-08-02 14:20:21 -07001154 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001155 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001156 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001157 << mPackage.string()
1158 << "::I"
1159 << baseName
1160 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001161
Andreas Huber881227d2016-08-02 14:20:21 -07001162 out.unindent();
1163 out.unindent();
1164 out << "}\n\n";
1165
Yifan Hong068c5522016-10-31 14:07:25 -07001166 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1167 return generateProxyMethodSource(out, klassName, method, superInterface);
1168 });
Andreas Huber881227d2016-08-02 14:20:21 -07001169
Yifan Hong068c5522016-10-31 14:07:25 -07001170 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001171}
1172
1173status_t AST::generateStubSource(
1174 Formatter &out, const std::string &baseName) const {
1175 out << "IMPLEMENT_HWBINDER_META_INTERFACE("
1176 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001177 << ", "
1178 << mPackage.cppNamespace()
Andreas Huber881227d2016-08-02 14:20:21 -07001179 << "::I"
1180 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001181 << "::descriptor);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001182
1183 const std::string klassName = "Bn" + baseName;
1184
Steven Moreland40786312016-08-16 10:29:40 -07001185 out << klassName
1186 << "::"
1187 << klassName
1188 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl)\n";
1189
1190 out.indent();
1191 out.indent();
1192
1193 out << ": BnInterface"
1194 << "<I"
1195 << baseName
1196 << ", IHw"
1197 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001198 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001199 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001200 << mPackage.string()
1201 << "::I"
1202 << baseName
1203 << "\") {\n";
Steven Moreland40786312016-08-16 10:29:40 -07001204
1205 out.unindent();
1206 out.unindent();
1207 out << "}\n\n";
1208
Andreas Huber881227d2016-08-02 14:20:21 -07001209 out << "::android::status_t " << klassName << "::onTransact(\n";
1210
1211 out.indent();
1212 out.indent();
1213
Iliyan Malchev549e2592016-08-10 08:59:12 -07001214 out << "uint32_t _hidl_code,\n"
1215 << "const ::android::hardware::Parcel &_hidl_data,\n"
1216 << "::android::hardware::Parcel *_hidl_reply,\n"
1217 << "uint32_t _hidl_flags,\n"
1218 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001219
1220 out.unindent();
1221
Iliyan Malchev549e2592016-08-10 08:59:12 -07001222 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001223 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001224 out.indent();
1225
1226 const Interface *iface = mRootScope->getInterface();
1227
Yifan Hong10fe0b52016-10-19 14:20:17 -07001228 for (const auto &tuple : iface->allMethodsFromRoot()) {
1229 const Method *method = tuple.method();
1230 const Interface *superInterface = tuple.interface();
1231 out << "case "
1232 << method->getSerialId()
1233 << " /* "
1234 << method->name()
1235 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001236
Yifan Hong10fe0b52016-10-19 14:20:17 -07001237 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001238
Yifan Hong10fe0b52016-10-19 14:20:17 -07001239 status_t err =
1240 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001241
Yifan Hong10fe0b52016-10-19 14:20:17 -07001242 if (err != OK) {
1243 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001244 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001245
1246 out.unindent();
1247 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001248 }
1249
1250 out << "default:\n{\n";
1251 out.indent();
1252
Andreas Huber8a82ff72016-08-04 10:29:39 -07001253 out << "return ::android::hardware::BnInterface<I"
Steven Moreland40786312016-08-16 10:29:40 -07001254 << baseName << ", IHw" << baseName
Andreas Huber881227d2016-08-02 14:20:21 -07001255 << ">::onTransact(\n";
1256
1257 out.indent();
1258 out.indent();
1259
Iliyan Malchev549e2592016-08-10 08:59:12 -07001260 out << "_hidl_code, _hidl_data, _hidl_reply, "
1261 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001262
1263 out.unindent();
1264 out.unindent();
1265
1266 out.unindent();
1267 out << "}\n";
1268
1269 out.unindent();
1270 out << "}\n\n";
1271
Iliyan Malchev549e2592016-08-10 08:59:12 -07001272 out << "if (_hidl_err == ::android::UNEXPECTED_NULL) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001273 out.indent();
Yifan Hong859e53f2016-11-14 19:08:24 -08001274 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001275 out.indent();
1276 out.indent();
Yifan Hong859e53f2016-11-14 19:08:24 -08001277 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1278 out << "_hidl_reply);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001279 out.unindent();
1280 out.unindent();
1281
1282 out.unindent();
1283 out << "}\n\n";
1284
Iliyan Malchev549e2592016-08-10 08:59:12 -07001285 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001286
1287 out.unindent();
1288 out << "}\n\n";
1289
1290 return OK;
1291}
1292
1293status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001294 Formatter &out, const Interface *iface, const Method *method) const {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001295 out << "if (!_hidl_data.enforceInterface(";
1296
Yifan Hongc8934042016-11-17 17:10:52 -08001297 out << iface->fqName().cppNamespace()
1298 << "::I"
1299 << iface->getBaseName();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001300
1301 out << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001302
Andreas Huber881227d2016-08-02 14:20:21 -07001303 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001304 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001305 out << "break;\n";
1306 out.unindent();
1307 out << "}\n\n";
1308
Andreas Huber5e44a292016-09-27 14:52:39 -07001309 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001310
Yifan Hongbf459bc2016-08-23 16:50:37 -07001311 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001312 for (const auto &arg : method->args()) {
1313 emitCppReaderWriter(
1314 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001315 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001316 false /* parcelObjIsPointer */,
1317 arg,
1318 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001319 Type::ErrorMode_Break,
1320 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001321 }
1322
Yifan Hongbf459bc2016-08-23 16:50:37 -07001323 // Second DFS: resolve references
1324 for (const auto &arg : method->args()) {
1325 emitCppResolveReferences(
1326 out,
1327 "_hidl_data",
1328 false /* parcelObjIsPointer */,
1329 arg,
1330 true /* reader */,
1331 Type::ErrorMode_Break,
1332 false /* addPrefixToName */);
1333 }
1334
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001335 status_t status = generateCppInstrumentationCall(
1336 out,
1337 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001338 method);
1339 if (status != OK) {
1340 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001341 }
1342
Andreas Huber881227d2016-08-02 14:20:21 -07001343 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001344 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001345
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001346 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001347 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001348 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001349 << elidedReturn->name()
Yifan Honga47eef32016-12-12 10:38:54 -08001350 << " = this->"
Yifan Hong3b320f82016-11-01 15:15:54 -07001351 << method->name()
1352 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001353
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001354 bool first = true;
1355 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001356 if (!first) {
1357 out << ", ";
1358 }
1359
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001360 if (arg->type().resultNeedsDeref()) {
1361 out << "*";
1362 }
1363
1364 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001365
1366 first = false;
1367 }
1368
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001369 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001370 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1371 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001372
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001373 elidedReturn->type().emitReaderWriter(
1374 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001375 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001376 "_hidl_reply",
1377 true, /* parcelObjIsPointer */
1378 false, /* isReader */
1379 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001380
Yifan Hongbf459bc2016-08-23 16:50:37 -07001381 emitCppResolveReferences(
1382 out,
1383 "_hidl_reply",
1384 true /* parcelObjIsPointer */,
1385 elidedReturn,
1386 false /* reader */,
1387 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001388 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001389
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001390 status_t status = generateCppInstrumentationCall(
1391 out,
1392 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001393 method);
1394 if (status != OK) {
1395 return status;
1396 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001397
Iliyan Malchev549e2592016-08-10 08:59:12 -07001398 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001399 } else {
1400 if (returnsValue) {
1401 out << "bool _hidl_callbackCalled = false;\n\n";
1402 }
Andreas Huber881227d2016-08-02 14:20:21 -07001403
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001404 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001405
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001406 bool first = true;
1407 for (const auto &arg : method->args()) {
1408 if (!first) {
1409 out << ", ";
1410 }
Andreas Huber881227d2016-08-02 14:20:21 -07001411
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001412 if (arg->type().resultNeedsDeref()) {
1413 out << "*";
1414 }
1415
1416 out << arg->name();
1417
1418 first = false;
1419 }
1420
1421 if (returnsValue) {
1422 if (!first) {
1423 out << ", ";
1424 }
1425
1426 out << "[&](";
1427
1428 first = true;
1429 for (const auto &arg : method->results()) {
1430 if (!first) {
1431 out << ", ";
1432 }
1433
Yifan Honga47eef32016-12-12 10:38:54 -08001434 out << "const auto &_hidl_out_" << arg->name();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001435
1436 first = false;
1437 }
1438
1439 out << ") {\n";
1440 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001441 out << "if (_hidl_callbackCalled) {\n";
1442 out.indent();
1443 out << "LOG_ALWAYS_FATAL(\""
1444 << method->name()
1445 << ": _hidl_cb called a second time, but must be called once.\");\n";
1446 out.unindent();
1447 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001448 out << "_hidl_callbackCalled = true;\n\n";
1449
Yifan Hong859e53f2016-11-14 19:08:24 -08001450 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1451 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001452
Yifan Hongbf459bc2016-08-23 16:50:37 -07001453 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001454 for (const auto &arg : method->results()) {
1455 emitCppReaderWriter(
1456 out,
1457 "_hidl_reply",
1458 true /* parcelObjIsPointer */,
1459 arg,
1460 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001461 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001462 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001463 }
1464
Yifan Hongbf459bc2016-08-23 16:50:37 -07001465 // Second DFS: resolve references
1466 for (const auto &arg : method->results()) {
1467 emitCppResolveReferences(
1468 out,
1469 "_hidl_reply",
1470 true /* parcelObjIsPointer */,
1471 arg,
1472 false /* reader */,
1473 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001474 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001475 }
1476
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001477 status_t status = generateCppInstrumentationCall(
1478 out,
1479 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001480 method);
1481 if (status != OK) {
1482 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001483 }
1484
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001485 out << "_hidl_cb(*_hidl_reply);\n";
1486
1487 out.unindent();
1488 out << "}\n";
1489 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001490 out << ");\n\n";
1491
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001492 if (returnsValue) {
1493 out << "if (!_hidl_callbackCalled) {\n";
1494 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001495 out << "LOG_ALWAYS_FATAL(\""
1496 << method->name()
1497 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001498 out.unindent();
1499 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001500 } else {
1501 out << "::android::hardware::writeToParcel("
1502 << "::android::hardware::Status::ok(), "
1503 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001504 }
Andreas Huber881227d2016-08-02 14:20:21 -07001505 }
1506
1507 out << "break;\n";
1508
1509 return OK;
1510}
1511
Steven Moreland69e7c702016-09-09 11:16:32 -07001512status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1513 std::string ifaceName;
1514 if (!AST::isInterface(&ifaceName)) {
1515 // types.hal does not get a stub header.
1516 return OK;
1517 }
1518
1519 const Interface *iface = mRootScope->getInterface();
1520
1521 const std::string baseName = iface->getBaseName();
1522 const std::string klassName = "Bs" + baseName;
1523
1524 bool supportOneway = iface->hasOnewayMethods();
1525
1526 std::string path = outputPath;
1527 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1528 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1529 path.append(klassName);
1530 path.append(".h");
1531
1532 CHECK(Coordinator::MakeParentHierarchy(path));
1533 FILE *file = fopen(path.c_str(), "w");
1534
1535 if (file == NULL) {
1536 return -errno;
1537 }
1538
1539 Formatter out(file);
1540
1541 const std::string guard = makeHeaderGuard(klassName);
1542
1543 out << "#ifndef " << guard << "\n";
1544 out << "#define " << guard << "\n\n";
1545
1546 std::vector<std::string> packageComponents;
1547 getPackageAndVersionComponents(
1548 &packageComponents, false /* cpp_compatible */);
1549
1550 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001551
1552 generateCppPackageInclude(out, mPackage, ifaceName);
1553 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001554
1555 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001556 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001557 }
1558
1559 enterLeaveNamespace(out, true /* enter */);
1560 out << "\n";
1561
1562 out << "struct "
1563 << klassName
1564 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001565 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001566
1567 out.indent();
1568 out << "explicit "
1569 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001570 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001571 << ifaceName
1572 << "> impl);\n";
1573
Yifan Hong068c5522016-10-31 14:07:25 -07001574 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1575 return generatePassthroughMethod(out, method);
1576 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001577
1578 if (err != OK) {
1579 return err;
1580 }
1581
1582 out.unindent();
1583 out << "private:\n";
1584 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001585 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001586
1587 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001588 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001589
1590 out << "\n";
1591
1592 out << "::android::hardware::Return<void> addOnewayTask("
1593 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001594 }
1595
1596 out.unindent();
1597
1598 out << "};\n\n";
1599
1600 enterLeaveNamespace(out, false /* enter */);
1601
1602 out << "\n#endif // " << guard << "\n";
1603
1604 return OK;
1605}
1606
Yifan Hongfe95aa22016-10-19 17:26:45 -07001607status_t AST::generateInterfaceSource(Formatter &out) const {
1608 const Interface *iface = mRootScope->getInterface();
1609
Yifan Hong2d7126b2016-10-20 15:12:57 -07001610 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001611 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001612
Yifan Hong3d746092016-12-07 14:26:33 -08001613 for (const Interface *superType : iface->typeChain()) {
1614 out << "// static \n"
1615 << childTypeResult
1616 << " I"
1617 << iface->getBaseName()
1618 << "::castFrom("
1619 << superType->getCppArgumentType()
1620 << " parent) {\n";
1621 out.indent();
1622 if (iface == superType) {
1623 out << "return parent;\n";
1624 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001625 out << "return ::android::hardware::castInterface<";
1626 out << "I" << iface->getBaseName() << ", "
1627 << superType->fqName().cppName() << ", "
Yifan Hong158655a2016-11-08 12:34:07 -08001628 << "Bp" << iface->getBaseName() << ", "
1629 << superType->getHwName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001630 << ">(\n";
1631 out.indent();
1632 out.indent();
1633 out << "parent, \""
1634 << iface->fqName().string()
1635 << "\");\n";
1636 out.unindent();
1637 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001638 }
Yifan Hong3d746092016-12-07 14:26:33 -08001639 out.unindent();
1640 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001641 }
1642
1643 return OK;
1644}
1645
Steven Moreland69e7c702016-09-09 11:16:32 -07001646status_t AST::generatePassthroughSource(Formatter &out) const {
1647 const Interface *iface = mRootScope->getInterface();
1648
1649 const std::string baseName = iface->getBaseName();
1650 const std::string klassName = "Bs" + baseName;
1651
1652 out << klassName
1653 << "::"
1654 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001655 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001656 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001657 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001658 << iface->fqName().string()
1659 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001660 if (iface->hasOnewayMethods()) {
1661 out << "\n";
1662 out.indentBlock([&] {
1663 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1664 });
1665 }
1666 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001667
1668 if (iface->hasOnewayMethods()) {
1669 out << "::android::hardware::Return<void> "
1670 << klassName
1671 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1672 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001673 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001674 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001675 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1676 out.indent();
1677 out.indent();
1678 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1679 out.unindent();
1680 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001681 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001682 out << "}\n";
1683
Steven Morelandd366c262016-10-11 15:29:10 -07001684 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001685
1686 out.unindent();
1687 out << "}\n\n";
1688
1689
1690 }
1691
1692 return OK;
1693}
1694
Martijn Coenen7b295242016-11-04 16:52:56 +01001695status_t AST::generateCppAtraceCall(Formatter &out,
1696 InstrumentationEvent event,
1697 const Method *method) const {
1698 const Interface *iface = mRootScope->getInterface();
1699 std::string baseString = "HIDL::I" + iface->getBaseName() + "::" + method->name();
1700 switch (event) {
1701 case SERVER_API_ENTRY:
1702 {
1703 out << "atrace_begin(ATRACE_TAG_HAL, \""
1704 << baseString + "::server\");\n";
1705 break;
1706 }
1707 case CLIENT_API_ENTRY:
1708 {
1709 out << "atrace_begin(ATRACE_TAG_HAL, \""
1710 << baseString + "::client\");\n";
1711 break;
1712 }
1713 case PASSTHROUGH_ENTRY:
1714 {
1715 out << "atrace_begin(ATRACE_TAG_HAL, \""
1716 << baseString + "::passthrough\");\n";
1717 break;
1718 }
1719 case SERVER_API_EXIT:
1720 case CLIENT_API_EXIT:
1721 case PASSTHROUGH_EXIT:
1722 {
1723 out << "atrace_end(ATRACE_TAG_HAL);\n";
1724 break;
1725 }
1726 default:
1727 {
1728 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1729 return UNKNOWN_ERROR;
1730 }
1731 }
1732
1733 return OK;
1734}
1735
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001736status_t AST::generateCppInstrumentationCall(
1737 Formatter &out,
1738 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001739 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001740 status_t err = generateCppAtraceCall(out, event, method);
1741 if (err != OK) {
1742 return err;
1743 }
1744
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001745 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1746 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001747 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001748 std::string event_str = "";
1749 switch (event) {
1750 case SERVER_API_ENTRY:
1751 {
1752 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1753 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001754 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001755 << (arg->type().resultNeedsDeref() ? "" : "&")
1756 << arg->name()
1757 << ");\n";
1758 }
1759 break;
1760 }
1761 case SERVER_API_EXIT:
1762 {
1763 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001764 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001765 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001766 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001767 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001768 }
1769 break;
1770 }
1771 case CLIENT_API_ENTRY:
1772 {
1773 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1774 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001775 out << "_hidl_args.push_back((void *)&"
1776 << arg->name()
1777 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001778 }
1779 break;
1780 }
1781 case CLIENT_API_EXIT:
1782 {
1783 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1784 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001785 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001786 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001787 << "_hidl_out_"
1788 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001789 << ");\n";
1790 }
1791 break;
1792 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001793 case PASSTHROUGH_ENTRY:
1794 {
1795 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1796 for (const auto &arg : method->args()) {
1797 out << "_hidl_args.push_back((void *)&"
1798 << arg->name()
1799 << ");\n";
1800 }
1801 break;
1802 }
1803 case PASSTHROUGH_EXIT:
1804 {
1805 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001806 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001807 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001808 << arg->name()
1809 << ");\n";
1810 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001811 break;
1812 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001813 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001814 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001815 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001816 return UNKNOWN_ERROR;
1817 }
1818 }
1819
Steven Moreland031ccf12016-10-31 15:54:38 -07001820 const Interface *iface = mRootScope->getInterface();
1821
Steven Moreland1ab31442016-11-03 18:37:51 -07001822 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001823 out.indent();
1824 out << "callback("
1825 << event_str
1826 << ", \""
1827 << mPackage.package()
1828 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07001829 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001830 << "\", \""
1831 << iface->localName()
1832 << "\", \""
1833 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001834 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001835 out.unindent();
1836 out << "}\n";
1837 out.unindent();
1838 out << "}\n\n";
1839
1840 return OK;
1841}
1842
Andreas Huber881227d2016-08-02 14:20:21 -07001843} // namespace android
1844