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 "AST.h"
18
19 #include "Coordinator.h"
20 #include "EnumType.h"
21 #include "Interface.h"
22 #include "HidlTypeAssertion.h"
23 #include "Method.h"
24 #include "ScalarType.h"
25 #include "Scope.h"
26
27 #include <algorithm>
28 #include <hidl-util/Formatter.h>
29 #include <hidl-util/StringHelper.h>
30 #include <android-base/logging.h>
31 #include <string>
32 #include <vector>
33
34 namespace android {
35
generateCpp(const std::string & outputPath) const36 status_t AST::generateCpp(const std::string &outputPath) const {
37 status_t err = generateCppHeaders(outputPath);
38
39 if (err == OK) {
40 err = generateCppSources(outputPath);
41 }
42
43 return err;
44 }
45
generateCppHeaders(const std::string & outputPath) const46 status_t AST::generateCppHeaders(const std::string &outputPath) const {
47 status_t err = generateInterfaceHeader(outputPath);
48
49 if (err == OK) {
50 err = generateStubHeader(outputPath);
51 }
52
53 if (err == OK) {
54 err = generateHwBinderHeader(outputPath);
55 }
56
57 if (err == OK) {
58 err = generateProxyHeader(outputPath);
59 }
60
61 if (err == OK) {
62 err = generatePassthroughHeader(outputPath);
63 }
64
65 return err;
66 }
67
getPackageComponents(std::vector<std::string> * components) const68 void AST::getPackageComponents(
69 std::vector<std::string> *components) const {
70 mPackage.getPackageComponents(components);
71 }
72
getPackageAndVersionComponents(std::vector<std::string> * components,bool cpp_compatible) const73 void AST::getPackageAndVersionComponents(
74 std::vector<std::string> *components, bool cpp_compatible) const {
75 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
76 }
77
makeHeaderGuard(const std::string & baseName,bool indicateGenerated) const78 std::string AST::makeHeaderGuard(const std::string &baseName,
79 bool indicateGenerated) const {
80 std::string guard;
81
82 if (indicateGenerated) {
83 guard += "HIDL_GENERATED_";
84 }
85
86 guard += StringHelper::Uppercase(mPackage.tokenName());
87 guard += "_";
88 guard += StringHelper::Uppercase(baseName);
89 guard += "_H";
90
91 return guard;
92 }
93
generateCppPackageInclude(Formatter & out,const FQName & package,const std::string & klass)94 void AST::generateCppPackageInclude(
95 Formatter &out,
96 const FQName &package,
97 const std::string &klass) {
98
99 out << "#include <";
100
101 std::vector<std::string> components;
102 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
103
104 for (const auto &component : components) {
105 out << component << "/";
106 }
107
108 out << klass
109 << ".h>\n";
110 }
111
enterLeaveNamespace(Formatter & out,bool enter) const112 void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
113 std::vector<std::string> packageComponents;
114 getPackageAndVersionComponents(
115 &packageComponents, true /* cpp_compatible */);
116
117 if (enter) {
118 for (const auto &component : packageComponents) {
119 out << "namespace " << component << " {\n";
120 }
121
122 out.setNamespace(mPackage.cppNamespace() + "::");
123 } else {
124 out.setNamespace(std::string());
125
126 for (auto it = packageComponents.rbegin();
127 it != packageComponents.rend();
128 ++it) {
129 out << "} // namespace " << *it << "\n";
130 }
131 }
132 }
133
declareGetService(Formatter & out,const std::string & interfaceName,bool isTry)134 static void declareGetService(Formatter &out, const std::string &interfaceName, bool isTry) {
135 const std::string functionName = isTry ? "tryGetService" : "getService";
136
137 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
138 << "const std::string &serviceName=\"default\", bool getStub=false);\n";
139 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
140 << "const char serviceName[], bool getStub=false)"
141 << " { std::string str(serviceName ? serviceName : \"\");"
142 << " return " << functionName << "(str, getStub); }\n";
143 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
144 << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
145 // without c_str the std::string constructor is ambiguous
146 << " { std::string str(serviceName.c_str());"
147 << " return " << functionName << "(str, getStub); }\n";
148 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
149 << "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
150 }
151
declareServiceManagerInteractions(Formatter & out,const std::string & interfaceName)152 static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
153 declareGetService(out, interfaceName, true /* isTry */);
154 declareGetService(out, interfaceName, false /* isTry */);
155
156 out << "__attribute__ ((warn_unused_result))"
157 << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
158 out << "static bool registerForNotifications(\n";
159 out.indent(2, [&] {
160 out << "const std::string &serviceName,\n"
161 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
162 << "¬ification);\n";
163 });
164
165 }
166
implementGetService(Formatter & out,const FQName & fqName,bool isTry)167 static void implementGetService(Formatter &out,
168 const FQName &fqName,
169 bool isTry) {
170
171 const std::string interfaceName = fqName.getInterfaceName();
172 const std::string functionName = isTry ? "tryGetService" : "getService";
173
174 out << "// static\n"
175 << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
176 << "const std::string &serviceName, const bool getStub) ";
177 out.block([&] {
178 out << "using ::android::hardware::defaultServiceManager;\n";
179 out << "using ::android::hardware::details::waitForHwService;\n";
180 out << "using ::android::hardware::getPassthroughServiceManager;\n";
181 out << "using ::android::hardware::Return;\n";
182 out << "using ::android::sp;\n";
183 out << "using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;\n\n";
184
185 out << "sp<" << interfaceName << "> iface = nullptr;\n";
186
187 out.endl();
188
189 out << "const sp<::android::hidl::manager::V1_0::IServiceManager> sm"
190 << " = defaultServiceManager();\n";
191
192 out.sIf("sm == nullptr", [&] {
193 // hwbinder is not available on this device, so future tries
194 // would also be null. I can only return nullptr.
195 out << "ALOGE(\"getService: defaultServiceManager() is null\");\n"
196 << "return nullptr;\n";
197 }).endl().endl();
198
199 out << "Return<Transport> transportRet = sm->getTransport("
200 << interfaceName << "::descriptor, serviceName);\n\n";
201
202 out.sIf("!transportRet.isOk()", [&] {
203 out << "ALOGE(\"getService: defaultServiceManager()->getTransport returns %s\", "
204 << "transportRet.description().c_str());\n";
205 out << "return nullptr;\n";
206 }).endl();
207
208 out << "Transport transport = transportRet;\n";
209 out << "const bool vintfHwbinder = (transport == Transport::HWBINDER);\n"
210 << "const bool vintfPassthru = (transport == Transport::PASSTHROUGH);\n\n";
211
212 // This means that you must set TREBLE_TESTING_OVERRIDE when running a test such
213 // as hidl_test. Ideally these binaries set this value themselves. This allows
214 // test modules to dynamically add and unset services even though they are not
215 // declared in the device manifest. This prevents a problem where framework
216 // changes are accidentally made in a way that is not backwards compatible. For
217 // instance, consider the following situation for two devices developed in the
218 // same tree:
219 // A: serves @1.1::IFoo, declares @1.0::IFoo (incorrect)
220 // B: serves @1.0::IFoo, declares @1.0::IFoo (correct configuration)
221 // If development is done on device A, then framework code like: "V1_1::IFoo::
222 // getService()->doV1_0Api()" will work. However, this will unintentionally break
223 // the feature for devices like device B for which "V1_1::IFoo::getService()
224 // will return nullptr. In order to prevent problems like this, we only allow
225 // fetching an interface if it is declared in a VINTF manifest.
226 out << "#ifdef __ANDROID_TREBLE__\n\n"
227 << "#ifdef __ANDROID_DEBUGGABLE__\n"
228 << "const char* env = std::getenv(\"TREBLE_TESTING_OVERRIDE\");\n"
229 << "const bool trebleTestingOverride = env && !strcmp(env, \"true\");\n"
230 << "const bool vintfLegacy = (transport == Transport::EMPTY) && trebleTestingOverride;\n"
231 << "#else // __ANDROID_TREBLE__ but not __ANDROID_DEBUGGABLE__\n"
232 << "const bool trebleTestingOverride = false;\n"
233 << "const bool vintfLegacy = false;\n"
234 << "#endif // __ANDROID_DEBUGGABLE__\n\n"
235 << "#else // not __ANDROID_TREBLE__\n"
236 << "const char* env = std::getenv(\"TREBLE_TESTING_OVERRIDE\");\n"
237 << "const bool trebleTestingOverride = env && !strcmp(env, \"true\");\n"
238 << "const bool vintfLegacy = (transport == Transport::EMPTY);\n\n"
239 << "#endif // __ANDROID_TREBLE__\n\n";
240
241 // if (getStub) {
242 // getPassthroughServiceManager()->get only once.
243 // } else {
244 // if (vintfHwbinder) {
245 // while (no alive service) {
246 // if (have already tried to get service)
247 // waitForHwService
248 // defaultServiceManager()->get
249 // }
250 // } else if (vintfLegacy) {
251 // defaultServiceManager()->get only once.
252 // getPassthroughServiceManager()->get only once.
253 // } else if (vintfPassthru) {
254 // getPassthroughServiceManager()->get only once.
255 // }
256 // }
257
258 out.sFor("int tries = 0; !getStub && (vintfHwbinder || (vintfLegacy && tries == 0)); tries++", [&] {
259 if (!isTry) {
260 out.sIf("tries > 1", [&] {
261 // sleep only after the first time we've called waitForHwService.
262 out << "ALOGI(\"" << functionName << ": Will do try %d for %s/%s in 1s...\", tries, "
263 << interfaceName << "::descriptor, serviceName.c_str());\n"
264 << "sleep(1);\n";
265 }).endl();
266
267 out.sIf("vintfHwbinder && tries > 0", [&] {
268 out << "waitForHwService("
269 << interfaceName << "::descriptor, serviceName);\n";
270 }).endl();
271 }
272
273 out << "Return<sp<" << gIBaseFqName.cppName() << ">> ret = \n";
274 out.indent(2, [&] {
275 out << "sm->get(" << interfaceName << "::descriptor, serviceName);\n";
276 });
277
278 out.sIf("!ret.isOk()", [&] {
279 // hwservicemanager fails, may be security issue
280 out << "ALOGE(\"" << interfaceName << ": defaultServiceManager()->get returns %s\", "
281 << "ret.description().c_str());\n"
282 << "break;\n";
283 }).endl();
284
285 out << "sp<" << gIBaseFqName.cppName() << "> base = ret;\n";
286 out.sIf("base == nullptr", [&] {
287 // if tries > 0: race condition. hwservicemanager drops the service
288 // from waitForHwService to here
289 out.sIf("tries > 0", [&] {
290 out << "ALOGW(\"" << interfaceName << ": found null hwbinder interface\");\n";
291 });
292 out << (isTry ? "break" : "continue")
293 << ";\n";
294 }).endl();
295 out << "Return<sp<" << interfaceName
296 << ">> castRet = " << interfaceName << "::castFrom(base, true /* emitError */);\n";
297 out.sIf("!castRet.isOk()", [&] {
298 out.sIf("castRet.isDeadObject()", [&] {
299 // service is dead (castFrom cannot call interfaceChain)
300 out << "ALOGW(\"" << interfaceName << ": found dead hwbinder service\");\n"
301 << (isTry ? "break" : "continue")
302 << ";\n";
303 }).sElse([&] {
304 out << "ALOGW(\"" << interfaceName << ": cannot call into hwbinder service: %s"
305 << "; No permission? Check for selinux denials.\", "
306 << "castRet.description().c_str());\n"
307 << "break;\n";
308 }).endl();
309 }).endl();
310 out << "iface = castRet;\n";
311 out.sIf("iface == nullptr", [&] {
312 // returned service isn't of correct type; this is a bug
313 // to hwservicemanager or to the service itself (interfaceChain
314 // is not consistent).
315 out << "ALOGW(\"" << interfaceName << ": received incompatible service; bug in hwservicemanager?\");\n"
316 << "break;\n";
317 }).endl();
318
319 out << "return iface;\n";
320 }).endl();
321
322 out.sIf("getStub || vintfPassthru || vintfLegacy", [&] {
323 out << "const sp<::android::hidl::manager::V1_0::IServiceManager> pm"
324 << " = getPassthroughServiceManager();\n";
325
326 out.sIf("pm != nullptr", [&] () {
327 out << "Return<sp<" << gIBaseFqName.cppName() << ">> ret = \n";
328 out.indent(2, [&] {
329 out << "pm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
330 });
331 out.sIf("ret.isOk()", [&] {
332 out << "sp<" << gIBaseFqName.cppName()
333 << "> baseInterface = ret;\n";
334 out.sIf("baseInterface != nullptr", [&]() {
335 out << "iface = " << interfaceName << "::castFrom(baseInterface);\n";
336 out.sIf("!getStub || trebleTestingOverride", [&] () {
337 out << "iface = new " << fqName.getInterfacePassthroughName() << "(iface);\n";
338 }).endl();
339 }).endl();
340 }).endl();
341 }).endl();
342 }).endl();
343
344 out << "return iface;\n";
345 }).endl().endl();
346 }
347
implementServiceManagerInteractions(Formatter & out,const FQName & fqName,const std::string & package)348 static void implementServiceManagerInteractions(Formatter &out,
349 const FQName &fqName, const std::string &package) {
350
351 const std::string interfaceName = fqName.getInterfaceName();
352
353 implementGetService(out, fqName, true /* isTry */);
354 implementGetService(out, fqName, false /* isTry */);
355
356 out << "::android::status_t " << interfaceName << "::registerAsService("
357 << "const std::string &serviceName) ";
358 out.block([&] {
359 out << "::android::hardware::details::onRegistration(\""
360 << fqName.getPackageAndVersion().string() << "\", \""
361 << interfaceName
362 << "\", serviceName);\n\n";
363 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
364 out.indent(2, [&] {
365 out << "= ::android::hardware::defaultServiceManager();\n";
366 });
367 out.sIf("sm == nullptr", [&] {
368 out << "return ::android::INVALID_OPERATION;\n";
369 }).endl();
370 out << "::android::hardware::Return<bool> ret = "
371 << "sm->add(serviceName.c_str(), this);\n"
372 << "return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
373 }).endl().endl();
374
375 out << "bool " << interfaceName << "::registerForNotifications(\n";
376 out.indent(2, [&] {
377 out << "const std::string &serviceName,\n"
378 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
379 << "¬ification) ";
380 });
381 out.block([&] {
382 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
383 out.indent(2, [&] {
384 out << "= ::android::hardware::defaultServiceManager();\n";
385 });
386 out.sIf("sm == nullptr", [&] {
387 out << "return false;\n";
388 }).endl();
389 out << "::android::hardware::Return<bool> success =\n";
390 out.indent(2, [&] {
391 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
392 out.indent(2, [&] {
393 out << "serviceName, notification);\n";
394 });
395 });
396 out << "return success.isOk() && success;\n";
397 }).endl().endl();
398 }
399
generateInterfaceHeader(const std::string & outputPath) const400 status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
401 const Interface *iface = getInterface();
402 std::string ifaceName = iface ? iface->localName() : "types";
403
404 std::string path = outputPath;
405 path.append(mCoordinator->convertPackageRootToPath(mPackage));
406 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
407 path.append(ifaceName);
408 path.append(".h");
409
410 CHECK(Coordinator::MakeParentHierarchy(path));
411 FILE *file = fopen(path.c_str(), "w");
412
413 if (file == NULL) {
414 return -errno;
415 }
416
417 Formatter out(file);
418
419 const std::string guard = makeHeaderGuard(ifaceName);
420
421 out << "#ifndef " << guard << "\n";
422 out << "#define " << guard << "\n\n";
423
424 for (const auto &item : mImportedNames) {
425 generateCppPackageInclude(out, item, item.name());
426 }
427
428 if (!mImportedNames.empty()) {
429 out << "\n";
430 }
431
432 if (iface) {
433 if (isIBase()) {
434 out << "// skipped #include IServiceNotification.h\n\n";
435 } else {
436 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
437 }
438 }
439
440 out << "#include <hidl/HidlSupport.h>\n";
441 out << "#include <hidl/MQDescriptor.h>\n";
442
443 if (iface) {
444 out << "#include <hidl/Status.h>\n";
445 }
446
447 out << "#include <utils/NativeHandle.h>\n";
448 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
449
450 enterLeaveNamespace(out, true /* enter */);
451 out << "\n";
452
453 if (iface) {
454 out << "struct "
455 << ifaceName;
456
457 const Interface *superType = iface->superType();
458
459 if (superType == NULL) {
460 out << " : virtual public ::android::RefBase";
461 } else {
462 out << " : public "
463 << superType->fullName();
464 }
465
466 out << " {\n";
467
468 out.indent();
469
470 }
471
472 status_t err = emitTypeDeclarations(out);
473
474 if (err != OK) {
475 return err;
476 }
477
478 if (iface) {
479 out << "virtual bool isRemote() const ";
480 if (!isIBase()) {
481 out << "override ";
482 }
483 out << "{ return false; }\n\n";
484
485 for (const auto& tuple : iface->allMethodsFromRoot()) {
486 const Method* method = tuple.method();
487
488 out << "\n";
489
490 const bool returnsValue = !method->results().empty();
491 const TypedVar *elidedReturn = method->canElideCallback();
492
493 if (elidedReturn == nullptr && returnsValue) {
494 out << "using "
495 << method->name()
496 << "_cb = std::function<void(";
497 method->emitCppResultSignature(out, true /* specify namespaces */);
498 out << ")>;\n";
499 }
500
501 method->dumpAnnotations(out);
502
503 if (elidedReturn) {
504 out << "virtual ::android::hardware::Return<";
505 out << elidedReturn->type().getCppResultType() << "> ";
506 } else {
507 out << "virtual ::android::hardware::Return<void> ";
508 }
509
510 out << method->name()
511 << "(";
512 method->emitCppArgSignature(out, true /* specify namespaces */);
513 out << ")";
514 if (method->isHidlReserved()) {
515 if (!isIBase()) {
516 out << " override";
517 }
518 } else {
519 out << " = 0";
520 }
521 out << ";\n";
522 }
523
524 out << "// cast static functions\n";
525 std::string childTypeResult = iface->getCppResultType();
526
527 for (const Interface *superType : iface->typeChain()) {
528 out << "static ::android::hardware::Return<"
529 << childTypeResult
530 << "> castFrom("
531 << superType->getCppArgumentType()
532 << " parent"
533 << ", bool emitError = false);\n";
534 }
535
536 out << "\nstatic const char* descriptor;\n\n";
537
538 if (isIBase()) {
539 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
540 } else {
541 declareServiceManagerInteractions(out, iface->localName());
542 }
543 }
544
545 if (iface) {
546 out.unindent();
547
548 out << "};\n\n";
549 }
550
551 err = mRootScope.emitGlobalTypeDeclarations(out);
552
553 if (err != OK) {
554 return err;
555 }
556
557 out << "\n";
558 enterLeaveNamespace(out, false /* enter */);
559
560 out << "\n#endif // " << guard << "\n";
561
562 return OK;
563 }
564
generateHwBinderHeader(const std::string & outputPath) const565 status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
566 const Interface *iface = getInterface();
567 std::string klassName = iface ? iface->getHwName() : "hwtypes";
568
569 std::string path = outputPath;
570 path.append(mCoordinator->convertPackageRootToPath(mPackage));
571 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
572 path.append(klassName + ".h");
573
574 FILE *file = fopen(path.c_str(), "w");
575
576 if (file == NULL) {
577 return -errno;
578 }
579
580 Formatter out(file);
581
582 const std::string guard = makeHeaderGuard(klassName);
583
584 out << "#ifndef " << guard << "\n";
585 out << "#define " << guard << "\n\n";
586
587 generateCppPackageInclude(out, mPackage, iface ? iface->localName() : "types");
588
589 out << "\n";
590
591 for (const auto &item : mImportedNames) {
592 if (item.name() == "types") {
593 generateCppPackageInclude(out, item, "hwtypes");
594 } else {
595 generateCppPackageInclude(out, item, item.getInterfaceStubName());
596 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
597 }
598 }
599
600 out << "\n";
601
602 out << "#include <hidl/Status.h>\n";
603 out << "#include <hwbinder/IBinder.h>\n";
604 out << "#include <hwbinder/Parcel.h>\n";
605
606 out << "\n";
607
608 enterLeaveNamespace(out, true /* enter */);
609
610 status_t err = mRootScope.emitGlobalHwDeclarations(out);
611 if (err != OK) {
612 return err;
613 }
614
615 enterLeaveNamespace(out, false /* enter */);
616
617 out << "\n#endif // " << guard << "\n";
618
619 return OK;
620 }
621
emitTypeDeclarations(Formatter & out) const622 status_t AST::emitTypeDeclarations(Formatter &out) const {
623 return mRootScope.emitTypeDeclarations(out);
624 }
625
wrapPassthroughArg(Formatter & out,const TypedVar * arg,bool addPrefixToName,std::function<void (void)> handleError)626 static void wrapPassthroughArg(Formatter &out,
627 const TypedVar *arg, bool addPrefixToName,
628 std::function<void(void)> handleError) {
629 if (!arg->type().isInterface()) {
630 return;
631 }
632 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
633 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
634 + arg->name();
635 const Interface &iface = static_cast<const Interface &>(arg->type());
636 out << iface.getCppStackType() << " " << wrappedName << ";\n";
637 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
638 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
639 out << wrappedName
640 << " = "
641 << iface.fqName().cppName()
642 << "::castFrom(::android::hardware::details::wrapPassthrough<"
643 << iface.fqName().cppName()
644 << ">("
645 << name << "));\n";
646 out.sIf(wrappedName + " == nullptr", [&] {
647 // Fatal error. Happens when the BsFoo class is not found in the binary
648 // or any dynamic libraries.
649 handleError();
650 }).endl();
651 }).sElse([&] {
652 out << wrappedName << " = " << name << ";\n";
653 }).endl().endl();
654 }
655
generatePassthroughMethod(Formatter & out,const Method * method) const656 status_t AST::generatePassthroughMethod(Formatter &out,
657 const Method *method) const {
658 method->generateCppSignature(out);
659
660 out << " {\n";
661 out.indent();
662
663 if (method->isHidlReserved()
664 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
665 method->cppImpl(IMPL_PASSTHROUGH, out);
666 out.unindent();
667 out << "}\n\n";
668 return OK;
669 }
670
671 const bool returnsValue = !method->results().empty();
672 const TypedVar *elidedReturn = method->canElideCallback();
673
674 if (returnsValue && elidedReturn == nullptr) {
675 generateCheckNonNull(out, "_hidl_cb");
676 }
677
678 generateCppInstrumentationCall(
679 out,
680 InstrumentationEvent::PASSTHROUGH_ENTRY,
681 method);
682
683
684 for (const auto &arg : method->args()) {
685 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
686 out << "return ::android::hardware::Status::fromExceptionCode(\n";
687 out.indent(2, [&] {
688 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
689 << "\"Cannot wrap passthrough interface.\");\n";
690 });
691 });
692 }
693
694 out << "auto _hidl_error = ::android::hardware::Void();\n";
695 out << "auto _hidl_return = ";
696
697 if (method->isOneway()) {
698 out << "addOnewayTask([mImpl = this->mImpl\n"
699 << "#ifdef __ANDROID_DEBUGGABLE__\n"
700 ", mEnableInstrumentation = this->mEnableInstrumentation, "
701 "mInstrumentationCallbacks = this->mInstrumentationCallbacks\n"
702 << "#endif // __ANDROID_DEBUGGABLE__\n";
703 for (const auto &arg : method->args()) {
704 out << ", "
705 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
706 << arg->name();
707 }
708 out << "] {\n";
709 out.indent();
710 }
711
712 out << "mImpl->"
713 << method->name()
714 << "(";
715
716 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
717 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
718 });
719 if (returnsValue && elidedReturn == nullptr) {
720 // never true if oneway since oneway methods don't return values
721
722 if (!method->args().empty()) {
723 out << ", ";
724 }
725 out << "[&](";
726 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
727 out << "const auto &_hidl_out_"
728 << arg->name();
729 });
730
731 out << ") {\n";
732 out.indent();
733 generateCppInstrumentationCall(
734 out,
735 InstrumentationEvent::PASSTHROUGH_EXIT,
736 method);
737
738 for (const auto &arg : method->results()) {
739 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
740 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
741 out.indent(2, [&] {
742 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
743 << "\"Cannot wrap passthrough interface.\");\n";
744 });
745 out << "return;\n";
746 });
747 }
748
749 out << "_hidl_cb(";
750 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
751 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
752 << arg->name();
753 });
754 out << ");\n";
755 out.unindent();
756 out << "});\n\n";
757 } else {
758 out << ");\n\n";
759
760 // used by generateCppInstrumentationCall
761 if (elidedReturn != nullptr) {
762 out << "#ifdef __ANDROID_DEBUGGABLE__\n"
763 << elidedReturn->type().getCppResultType() << " _hidl_out_" << elidedReturn->name()
764 << " = _hidl_return;\n"
765 << "#endif // __ANDROID_DEBUGGABLE__\n";
766 }
767 generateCppInstrumentationCall(
768 out,
769 InstrumentationEvent::PASSTHROUGH_EXIT,
770 method);
771 }
772
773 if (method->isOneway()) {
774 out.unindent();
775 out << "});\n";
776 }
777
778 out << "return _hidl_return;\n";
779
780 out.unindent();
781 out << "}\n";
782
783 return OK;
784 }
785
generateMethods(Formatter & out,MethodGenerator gen,bool includeParent) const786 status_t AST::generateMethods(Formatter &out, MethodGenerator gen, bool includeParent) const {
787 const Interface* iface = mRootScope.getInterface();
788
789 const Interface *prevIterface = nullptr;
790 for (const auto &tuple : iface->allMethodsFromRoot()) {
791 const Method *method = tuple.method();
792 const Interface *superInterface = tuple.interface();
793
794 if (!includeParent && superInterface != iface) {
795 continue;
796 }
797
798 if(prevIterface != superInterface) {
799 if (prevIterface != nullptr) {
800 out << "\n";
801 }
802 out << "// Methods from "
803 << superInterface->fullName()
804 << " follow.\n";
805 prevIterface = superInterface;
806 }
807 status_t err = gen(method, superInterface);
808
809 if (err != OK) {
810 return err;
811 }
812 }
813
814 out << "\n";
815
816 return OK;
817 }
818
generateTemplatizationLink(Formatter & out) const819 void AST::generateTemplatizationLink(Formatter& out) const {
820 out << "typedef " << mRootScope.getInterface()->localName() << " Pure;\n\n";
821 }
822
generateStubHeader(const std::string & outputPath) const823 status_t AST::generateStubHeader(const std::string &outputPath) const {
824 if (!AST::isInterface()) {
825 // types.hal does not get a stub header.
826 return OK;
827 }
828
829 const Interface* iface = mRootScope.getInterface();
830 const std::string klassName = iface->getStubName();
831
832 std::string path = outputPath;
833 path.append(mCoordinator->convertPackageRootToPath(mPackage));
834 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
835 path.append(klassName);
836 path.append(".h");
837
838 CHECK(Coordinator::MakeParentHierarchy(path));
839 FILE *file = fopen(path.c_str(), "w");
840
841 if (file == NULL) {
842 return -errno;
843 }
844
845 Formatter out(file);
846
847 const std::string guard = makeHeaderGuard(klassName);
848
849 out << "#ifndef " << guard << "\n";
850 out << "#define " << guard << "\n\n";
851
852 generateCppPackageInclude(out, mPackage, iface->getHwName());
853 out << "\n";
854
855 enterLeaveNamespace(out, true /* enter */);
856 out << "\n";
857
858 out << "struct "
859 << klassName;
860 if (iface->isIBase()) {
861 out << " : public ::android::hardware::BHwBinder";
862 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
863 } else {
864 out << " : public "
865 << gIBaseFqName.getInterfaceStubFqName().cppName()
866 << " {\n";
867 }
868
869 out.indent();
870 out << "explicit "
871 << klassName
872 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl);"
873 << "\n";
874 out << "explicit "
875 << klassName
876 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl,"
877 << " const std::string& HidlInstrumentor_package,"
878 << " const std::string& HidlInstrumentor_interface);"
879 << "\n\n";
880 out << "virtual ~" << klassName << "();\n\n";
881 out << "::android::status_t onTransact(\n";
882 out.indent();
883 out.indent();
884 out << "uint32_t _hidl_code,\n";
885 out << "const ::android::hardware::Parcel &_hidl_data,\n";
886 out << "::android::hardware::Parcel *_hidl_reply,\n";
887 out << "uint32_t _hidl_flags = 0,\n";
888 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
889 out.unindent();
890 out.unindent();
891
892 out.endl();
893 generateTemplatizationLink(out);
894
895 out << "::android::sp<" << iface->localName() << "> getImpl() { return _hidl_mImpl; };\n";
896
897 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
898 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
899 return OK;
900 }
901
902 out << "static ::android::status_t _hidl_" << method->name() << "(\n";
903
904 out.indent(2, [&] {
905 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
906 << "const ::android::hardware::Parcel &_hidl_data,\n"
907 << "::android::hardware::Parcel *_hidl_reply,\n"
908 << "TransactCallback _hidl_cb);\n";
909 }).endl().endl();
910
911 return OK;
912 }, false /* include parents */);
913
914 if (err != OK) {
915 return err;
916 }
917
918 out.unindent();
919 out << "private:\n";
920 out.indent();
921
922
923 err = generateMethods(out, [&](const Method *method, const Interface *iface) {
924 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
925 return OK;
926 }
927 const bool returnsValue = !method->results().empty();
928 const TypedVar *elidedReturn = method->canElideCallback();
929
930 if (elidedReturn == nullptr && returnsValue) {
931 out << "using " << method->name() << "_cb = "
932 << iface->fqName().cppName()
933 << "::" << method->name() << "_cb;\n";
934 }
935 method->generateCppSignature(out);
936 out << ";\n";
937 return OK;
938 });
939 if (err != OK) {
940 return err;
941 }
942
943 out << "::android::sp<" << iface->localName() << "> _hidl_mImpl;\n";
944 out.unindent();
945 out << "};\n\n";
946
947 enterLeaveNamespace(out, false /* enter */);
948
949 out << "\n#endif // " << guard << "\n";
950
951 return OK;
952 }
953
generateProxyHeader(const std::string & outputPath) const954 status_t AST::generateProxyHeader(const std::string &outputPath) const {
955 if (!AST::isInterface()) {
956 // types.hal does not get a proxy header.
957 return OK;
958 }
959
960 const Interface* iface = mRootScope.getInterface();
961 const std::string proxyName = iface->getProxyName();
962
963 std::string path = outputPath;
964 path.append(mCoordinator->convertPackageRootToPath(mPackage));
965 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
966 path.append(proxyName);
967 path.append(".h");
968
969 CHECK(Coordinator::MakeParentHierarchy(path));
970 FILE *file = fopen(path.c_str(), "w");
971
972 if (file == NULL) {
973 return -errno;
974 }
975
976 Formatter out(file);
977
978 const std::string guard = makeHeaderGuard(proxyName);
979
980 out << "#ifndef " << guard << "\n";
981 out << "#define " << guard << "\n\n";
982
983 out << "#include <hidl/HidlTransportSupport.h>\n\n";
984
985 std::vector<std::string> packageComponents;
986 getPackageAndVersionComponents(
987 &packageComponents, false /* cpp_compatible */);
988
989 generateCppPackageInclude(out, mPackage, iface->getHwName());
990 out << "\n";
991
992 enterLeaveNamespace(out, true /* enter */);
993 out << "\n";
994
995 out << "struct "
996 << proxyName
997 << " : public ::android::hardware::BpInterface<"
998 << iface->localName()
999 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
1000
1001 out.indent();
1002
1003 out << "explicit "
1004 << proxyName
1005 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
1006 << "\n\n";
1007
1008 generateTemplatizationLink(out);
1009
1010 out << "virtual bool isRemote() const override { return true; }\n\n";
1011
1012 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1013 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1014 return OK;
1015 }
1016
1017 out << "static ";
1018 method->generateCppReturnType(out);
1019 out << " _hidl_"
1020 << method->name()
1021 << "("
1022 << "::android::hardware::IInterface* _hidl_this, "
1023 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
1024
1025 if (!method->hasEmptyCppArgSignature()) {
1026 out << ", ";
1027 }
1028 method->emitCppArgSignature(out);
1029 out << ");\n";
1030 return OK;
1031 }, false /* include parents */);
1032
1033 if (err != OK) {
1034 return err;
1035 }
1036
1037 err = generateMethods(out, [&](const Method *method, const Interface *) {
1038 method->generateCppSignature(out);
1039 out << " override;\n";
1040 return OK;
1041 });
1042
1043 if (err != OK) {
1044 return err;
1045 }
1046
1047 out.unindent();
1048 out << "private:\n";
1049 out.indent();
1050 out << "std::mutex _hidl_mMutex;\n"
1051 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
1052 << " _hidl_mDeathRecipients;\n";
1053 out.unindent();
1054 out << "};\n\n";
1055
1056 enterLeaveNamespace(out, false /* enter */);
1057
1058 out << "\n#endif // " << guard << "\n";
1059
1060 return OK;
1061 }
1062
generateCppSources(const std::string & outputPath) const1063 status_t AST::generateCppSources(const std::string &outputPath) const {
1064 std::string baseName = getBaseName();
1065 const Interface *iface = getInterface();
1066
1067 std::string path = outputPath;
1068 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1069 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1070 path.append(baseName);
1071
1072 if (baseName != "types") {
1073 path.append("All");
1074 }
1075
1076 path.append(".cpp");
1077
1078 CHECK(Coordinator::MakeParentHierarchy(path));
1079 FILE *file = fopen(path.c_str(), "w");
1080
1081 if (file == NULL) {
1082 return -errno;
1083 }
1084
1085 Formatter out(file);
1086
1087 out << "#define LOG_TAG \""
1088 << mPackage.string() << "::" << baseName
1089 << "\"\n\n";
1090
1091 out << "#include <android/log.h>\n";
1092 out << "#include <cutils/trace.h>\n";
1093 out << "#include <hidl/HidlTransportSupport.h>\n\n";
1094 if (iface) {
1095 // This is a no-op for IServiceManager itself.
1096 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
1097
1098 generateCppPackageInclude(out, mPackage, iface->getProxyName());
1099 generateCppPackageInclude(out, mPackage, iface->getStubName());
1100 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
1101
1102 for (const Interface *superType : iface->superTypeChain()) {
1103 generateCppPackageInclude(out,
1104 superType->fqName(),
1105 superType->fqName().getInterfaceProxyName());
1106 }
1107
1108 out << "#include <hidl/ServiceManagement.h>\n";
1109 } else {
1110 generateCppPackageInclude(out, mPackage, "types");
1111 generateCppPackageInclude(out, mPackage, "hwtypes");
1112 }
1113
1114 out << "\n";
1115
1116 enterLeaveNamespace(out, true /* enter */);
1117 out << "\n";
1118
1119 status_t err = generateTypeSource(out, iface ? iface->localName() : "");
1120
1121 if (err == OK && iface) {
1122 const Interface* iface = mRootScope.getInterface();
1123
1124 // need to be put here, generateStubSource is using this.
1125 out << "const char* "
1126 << iface->localName()
1127 << "::descriptor(\""
1128 << iface->fqName().string()
1129 << "\");\n\n";
1130 out << "__attribute__((constructor))";
1131 out << "static void static_constructor() {\n";
1132 out.indent([&] {
1133 out << "::android::hardware::details::gBnConstructorMap.set("
1134 << iface->localName()
1135 << "::descriptor,\n";
1136 out.indent(2, [&] {
1137 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
1138 out.indent([&] {
1139 out << "return new "
1140 << iface->getStubName()
1141 << "(static_cast<"
1142 << iface->localName()
1143 << " *>(iIntf));\n";
1144 });
1145 out << "});\n";
1146 });
1147 out << "::android::hardware::details::gBsConstructorMap.set("
1148 << iface->localName()
1149 << "::descriptor,\n";
1150 out.indent(2, [&] {
1151 out << "[](void *iIntf) -> ::android::sp<"
1152 << gIBaseFqName.cppName()
1153 << "> {\n";
1154 out.indent([&] {
1155 out << "return new "
1156 << iface->getPassthroughName()
1157 << "(static_cast<"
1158 << iface->localName()
1159 << " *>(iIntf));\n";
1160 });
1161 out << "});\n";
1162 });
1163 });
1164 out << "};\n\n";
1165 out << "__attribute__((destructor))";
1166 out << "static void static_destructor() {\n";
1167 out.indent([&] {
1168 out << "::android::hardware::details::gBnConstructorMap.erase("
1169 << iface->localName()
1170 << "::descriptor);\n";
1171 out << "::android::hardware::details::gBsConstructorMap.erase("
1172 << iface->localName()
1173 << "::descriptor);\n";
1174 });
1175 out << "};\n\n";
1176
1177 err = generateInterfaceSource(out);
1178 }
1179
1180 if (err == OK && iface) {
1181 err = generateProxySource(out, iface->fqName());
1182 }
1183
1184 if (err == OK && iface) {
1185 err = generateStubSource(out, iface);
1186 }
1187
1188 if (err == OK && iface) {
1189 err = generatePassthroughSource(out);
1190 }
1191
1192 if (err == OK && iface) {
1193 const Interface* iface = mRootScope.getInterface();
1194
1195 if (isIBase()) {
1196 out << "// skipped getService, registerAsService, registerForNotifications\n";
1197 } else {
1198 std::string package = iface->fqName().package()
1199 + iface->fqName().atVersion();
1200
1201 implementServiceManagerInteractions(out, iface->fqName(), package);
1202 }
1203 }
1204
1205 HidlTypeAssertion::EmitAll(out);
1206 out << "\n";
1207
1208 enterLeaveNamespace(out, false /* enter */);
1209
1210 return err;
1211 }
1212
generateCheckNonNull(Formatter & out,const std::string & nonNull)1213 void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
1214 out.sIf(nonNull + " == nullptr", [&] {
1215 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1216 out.indent(2, [&] {
1217 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT,\n"
1218 << "\"Null synchronous callback passed.\");\n";
1219 });
1220 }).endl().endl();
1221 }
1222
generateTypeSource(Formatter & out,const std::string & ifaceName) const1223 status_t AST::generateTypeSource(
1224 Formatter &out, const std::string &ifaceName) const {
1225 return mRootScope.emitTypeDefinitions(out, ifaceName);
1226 }
1227
declareCppReaderLocals(Formatter & out,const std::vector<TypedVar * > & args,bool forResults) const1228 void AST::declareCppReaderLocals(
1229 Formatter &out,
1230 const std::vector<TypedVar *> &args,
1231 bool forResults) const {
1232 if (args.empty()) {
1233 return;
1234 }
1235
1236 for (const auto &arg : args) {
1237 const Type &type = arg->type();
1238
1239 out << type.getCppResultType()
1240 << " "
1241 << (forResults ? "_hidl_out_" : "") + arg->name()
1242 << ";\n";
1243 }
1244
1245 out << "\n";
1246 }
1247
emitCppReaderWriter(Formatter & out,const std::string & parcelObj,bool parcelObjIsPointer,const TypedVar * arg,bool isReader,Type::ErrorMode mode,bool addPrefixToName) const1248 void AST::emitCppReaderWriter(
1249 Formatter &out,
1250 const std::string &parcelObj,
1251 bool parcelObjIsPointer,
1252 const TypedVar *arg,
1253 bool isReader,
1254 Type::ErrorMode mode,
1255 bool addPrefixToName) const {
1256 const Type &type = arg->type();
1257
1258 type.emitReaderWriter(
1259 out,
1260 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1261 parcelObj,
1262 parcelObjIsPointer,
1263 isReader,
1264 mode);
1265 }
1266
emitCppResolveReferences(Formatter & out,const std::string & parcelObj,bool parcelObjIsPointer,const TypedVar * arg,bool isReader,Type::ErrorMode mode,bool addPrefixToName) const1267 void AST::emitCppResolveReferences(
1268 Formatter &out,
1269 const std::string &parcelObj,
1270 bool parcelObjIsPointer,
1271 const TypedVar *arg,
1272 bool isReader,
1273 Type::ErrorMode mode,
1274 bool addPrefixToName) const {
1275 const Type &type = arg->type();
1276 if(type.needsResolveReferences()) {
1277 type.emitResolveReferences(
1278 out,
1279 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1280 isReader, // nameIsPointer
1281 parcelObj,
1282 parcelObjIsPointer,
1283 isReader,
1284 mode);
1285 }
1286 }
1287
generateProxyMethodSource(Formatter & out,const std::string & klassName,const Method * method,const Interface * superInterface) const1288 status_t AST::generateProxyMethodSource(Formatter &out,
1289 const std::string &klassName,
1290 const Method *method,
1291 const Interface *superInterface) const {
1292 method->generateCppSignature(out,
1293 klassName,
1294 true /* specify namespaces */);
1295
1296 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1297 out.block([&] {
1298 method->cppImpl(IMPL_PROXY, out);
1299 }).endl().endl();
1300 return OK;
1301 }
1302
1303 status_t err = OK;
1304
1305 out.block([&] {
1306 const bool returnsValue = !method->results().empty();
1307 const TypedVar *elidedReturn = method->canElideCallback();
1308
1309 method->generateCppReturnType(out);
1310
1311 out << " _hidl_out = "
1312 << superInterface->fqName().cppNamespace()
1313 << "::"
1314 << superInterface->getProxyName()
1315 << "::_hidl_"
1316 << method->name()
1317 << "(this, this";
1318
1319 if (!method->hasEmptyCppArgSignature()) {
1320 out << ", ";
1321 }
1322
1323 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
1324 out << arg->name();
1325 });
1326
1327 if (returnsValue && elidedReturn == nullptr) {
1328 if (!method->args().empty()) {
1329 out << ", ";
1330 }
1331 out << "_hidl_cb";
1332 }
1333
1334 out << ");\n\n";
1335
1336 out << "return _hidl_out;\n";
1337 }).endl().endl();
1338
1339 return err;
1340 }
1341
generateStaticProxyMethodSource(Formatter & out,const std::string & klassName,const Method * method) const1342 status_t AST::generateStaticProxyMethodSource(Formatter &out,
1343 const std::string &klassName,
1344 const Method *method) const {
1345 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1346 return OK;
1347 }
1348
1349 method->generateCppReturnType(out);
1350
1351 out << klassName
1352 << "::_hidl_"
1353 << method->name()
1354 << "("
1355 << "::android::hardware::IInterface *_hidl_this, "
1356 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
1357
1358 if (!method->hasEmptyCppArgSignature()) {
1359 out << ", ";
1360 }
1361
1362 method->emitCppArgSignature(out);
1363 out << ") {\n";
1364
1365 out.indent();
1366
1367 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1368 out << "bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();\n";
1369 out << "const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();\n";
1370 out << "#else\n";
1371 out << "(void) _hidl_this_instrumentor;\n";
1372 out << "#endif // __ANDROID_DEBUGGABLE__\n";
1373
1374 const bool returnsValue = !method->results().empty();
1375 const TypedVar *elidedReturn = method->canElideCallback();
1376 if (returnsValue && elidedReturn == nullptr) {
1377 generateCheckNonNull(out, "_hidl_cb");
1378 }
1379
1380 generateCppInstrumentationCall(
1381 out,
1382 InstrumentationEvent::CLIENT_API_ENTRY,
1383 method);
1384
1385 out << "::android::hardware::Parcel _hidl_data;\n";
1386 out << "::android::hardware::Parcel _hidl_reply;\n";
1387 out << "::android::status_t _hidl_err;\n";
1388 out << "::android::hardware::Status _hidl_status;\n\n";
1389
1390 declareCppReaderLocals(
1391 out, method->results(), true /* forResults */);
1392
1393 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
1394 out << klassName;
1395 out << "::descriptor);\n";
1396 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1397
1398 bool hasInterfaceArgument = false;
1399 // First DFS: write all buffers and resolve pointers for parent
1400 for (const auto &arg : method->args()) {
1401 if (arg->type().isInterface()) {
1402 hasInterfaceArgument = true;
1403 }
1404 emitCppReaderWriter(
1405 out,
1406 "_hidl_data",
1407 false /* parcelObjIsPointer */,
1408 arg,
1409 false /* reader */,
1410 Type::ErrorMode_Goto,
1411 false /* addPrefixToName */);
1412 }
1413
1414 // Second DFS: resolve references.
1415 for (const auto &arg : method->args()) {
1416 emitCppResolveReferences(
1417 out,
1418 "_hidl_data",
1419 false /* parcelObjIsPointer */,
1420 arg,
1421 false /* reader */,
1422 Type::ErrorMode_Goto,
1423 false /* addPrefixToName */);
1424 }
1425
1426 if (hasInterfaceArgument) {
1427 // Start binder threadpool to handle incoming transactions
1428 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1429 }
1430 out << "_hidl_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact("
1431 << method->getSerialId()
1432 << " /* "
1433 << method->name()
1434 << " */, _hidl_data, &_hidl_reply";
1435
1436 if (method->isOneway()) {
1437 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1438 }
1439 out << ");\n";
1440
1441 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1442
1443 if (!method->isOneway()) {
1444 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
1445 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1446 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1447
1448
1449 // First DFS: write all buffers and resolve pointers for parent
1450 for (const auto &arg : method->results()) {
1451 emitCppReaderWriter(
1452 out,
1453 "_hidl_reply",
1454 false /* parcelObjIsPointer */,
1455 arg,
1456 true /* reader */,
1457 Type::ErrorMode_Goto,
1458 true /* addPrefixToName */);
1459 }
1460
1461 // Second DFS: resolve references.
1462 for (const auto &arg : method->results()) {
1463 emitCppResolveReferences(
1464 out,
1465 "_hidl_reply",
1466 false /* parcelObjIsPointer */,
1467 arg,
1468 true /* reader */,
1469 Type::ErrorMode_Goto,
1470 true /* addPrefixToName */);
1471 }
1472
1473 if (returnsValue && elidedReturn == nullptr) {
1474 out << "_hidl_cb(";
1475
1476 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
1477 if (arg->type().resultNeedsDeref()) {
1478 out << "*";
1479 }
1480 out << "_hidl_out_" << arg->name();
1481 });
1482
1483 out << ");\n\n";
1484 }
1485 }
1486
1487 generateCppInstrumentationCall(
1488 out,
1489 InstrumentationEvent::CLIENT_API_EXIT,
1490 method);
1491
1492 if (elidedReturn != nullptr) {
1493 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1494 out << "return ::android::hardware::Return<";
1495 out << elidedReturn->type().getCppResultType()
1496 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1497 } else {
1498 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1499 out << "return ::android::hardware::Return<void>();\n\n";
1500 }
1501
1502 out.unindent();
1503 out << "_hidl_error:\n";
1504 out.indent();
1505 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1506 out << "return ::android::hardware::Return<";
1507 if (elidedReturn != nullptr) {
1508 out << method->results().at(0)->type().getCppResultType();
1509 } else {
1510 out << "void";
1511 }
1512 out << ">(_hidl_status);\n";
1513
1514 out.unindent();
1515 out << "}\n\n";
1516 return OK;
1517 }
1518
generateProxySource(Formatter & out,const FQName & fqName) const1519 status_t AST::generateProxySource(
1520 Formatter &out, const FQName &fqName) const {
1521 const std::string klassName = fqName.getInterfaceProxyName();
1522
1523 out << klassName
1524 << "::"
1525 << klassName
1526 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
1527
1528 out.indent();
1529 out.indent();
1530
1531 out << ": BpInterface"
1532 << "<"
1533 << fqName.getInterfaceName()
1534 << ">(_hidl_impl),\n"
1535 << " ::android::hardware::details::HidlInstrumentor(\""
1536 << mPackage.string()
1537 << "\", \""
1538 << fqName.getInterfaceName()
1539 << "\") {\n";
1540
1541 out.unindent();
1542 out.unindent();
1543 out << "}\n\n";
1544
1545 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1546 return generateStaticProxyMethodSource(out, klassName, method);
1547 }, false /* include parents */);
1548
1549 if (err != OK) {
1550 return err;
1551 }
1552
1553 err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1554 return generateProxyMethodSource(out, klassName, method, superInterface);
1555 });
1556
1557 return err;
1558 }
1559
generateStubSource(Formatter & out,const Interface * iface) const1560 status_t AST::generateStubSource(
1561 Formatter &out,
1562 const Interface *iface) const {
1563 const std::string interfaceName = iface->localName();
1564 const std::string klassName = iface->getStubName();
1565
1566 out << klassName
1567 << "::"
1568 << klassName
1569 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
1570
1571 out.indent();
1572 out.indent();
1573
1574 if (iface->isIBase()) {
1575 out << ": ::android::hardware::details::HidlInstrumentor(\"";
1576 } else {
1577 out << ": "
1578 << gIBaseFqName.getInterfaceStubFqName().cppName()
1579 << "(_hidl_impl, \"";
1580 }
1581
1582 out << mPackage.string()
1583 << "\", \""
1584 << interfaceName
1585 << "\") { \n";
1586 out.indent();
1587 out << "_hidl_mImpl = _hidl_impl;\n";
1588 out << "auto prio = ::android::hardware::details::gServicePrioMap.get("
1589 << "_hidl_impl, {SCHED_NORMAL, 0});\n";
1590 out << "mSchedPolicy = prio.sched_policy;\n";
1591 out << "mSchedPriority = prio.prio;\n";
1592 out << "setRequestingSid(::android::hardware::details::gServiceSidMap.get(_hidl_impl, false));\n";
1593 out.unindent();
1594
1595 out.unindent();
1596 out.unindent();
1597 out << "}\n\n";
1598
1599 if (iface->isIBase()) {
1600 // BnHwBase has a constructor to initialize the HidlInstrumentor
1601 // class properly.
1602 out << klassName
1603 << "::"
1604 << klassName
1605 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1606 << " const std::string &HidlInstrumentor_package,"
1607 << " const std::string &HidlInstrumentor_interface)\n";
1608
1609 out.indent();
1610 out.indent();
1611
1612 out << ": ::android::hardware::details::HidlInstrumentor("
1613 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
1614 out.indent();
1615 out << "_hidl_mImpl = _hidl_impl;\n";
1616 out.unindent();
1617
1618 out.unindent();
1619 out.unindent();
1620 out << "}\n\n";
1621 }
1622
1623 out << klassName << "::~" << klassName << "() ";
1624 out.block([&]() {
1625 out << "::android::hardware::details::gBnMap.eraseIfEqual(_hidl_mImpl.get(), this);\n";
1626 }).endl().endl();
1627
1628 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1629 return generateStaticStubMethodSource(out, klassName, method);
1630 }, false /* include parents */);
1631
1632 err = generateMethods(out, [&](const Method *method, const Interface *) {
1633 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1634 return OK;
1635 }
1636 method->generateCppSignature(out, iface->getStubName());
1637 out << " ";
1638 out.block([&] {
1639 method->cppImpl(IMPL_STUB_IMPL, out);
1640 }).endl();
1641 return OK;
1642 });
1643 if (err != OK) {
1644 return err;
1645 }
1646
1647 out << "::android::status_t " << klassName << "::onTransact(\n";
1648
1649 out.indent();
1650 out.indent();
1651
1652 out << "uint32_t _hidl_code,\n"
1653 << "const ::android::hardware::Parcel &_hidl_data,\n"
1654 << "::android::hardware::Parcel *_hidl_reply,\n"
1655 << "uint32_t _hidl_flags,\n"
1656 << "TransactCallback _hidl_cb) {\n";
1657
1658 out.unindent();
1659
1660 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
1661 out << "switch (_hidl_code) {\n";
1662 out.indent();
1663
1664 for (const auto &tuple : iface->allMethodsFromRoot()) {
1665 const Method *method = tuple.method();
1666 const Interface *superInterface = tuple.interface();
1667
1668 out << "case "
1669 << method->getSerialId()
1670 << " /* "
1671 << method->name()
1672 << " */:\n{\n";
1673
1674 out.indent();
1675
1676 out << "bool _hidl_is_oneway = _hidl_flags & ::android::hardware::IBinder::FLAG_ONEWAY;\n";
1677 out << "if (_hidl_is_oneway != " << (method->isOneway() ? "true" : "false") << ") ";
1678 out.block([&] { out << "return ::android::UNKNOWN_ERROR;\n"; }).endl().endl();
1679
1680 status_t err = generateStubSourceForMethod(out, method, superInterface);
1681
1682 if (err != OK) {
1683 return err;
1684 }
1685
1686 out.unindent();
1687 out << "}\n\n";
1688 }
1689
1690 out << "default:\n{\n";
1691 out.indent();
1692
1693 if (iface->isIBase()) {
1694 out << "(void)_hidl_flags;\n";
1695 out << "return ::android::UNKNOWN_TRANSACTION;\n";
1696 } else {
1697 out << "return ";
1698 out << gIBaseFqName.getInterfaceStubFqName().cppName();
1699 out << "::onTransact(\n";
1700
1701 out.indent();
1702 out.indent();
1703
1704 out << "_hidl_code, _hidl_data, _hidl_reply, "
1705 << "_hidl_flags, _hidl_cb);\n";
1706
1707 out.unindent();
1708 out.unindent();
1709 }
1710
1711 out.unindent();
1712 out << "}\n";
1713
1714 out.unindent();
1715 out << "}\n\n";
1716
1717 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1718 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1719 out.indent(2, [&] {
1720 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1721 out << "_hidl_reply);\n";
1722 });
1723 });
1724
1725 out << "return _hidl_err;\n";
1726
1727 out.unindent();
1728 out << "}\n\n";
1729
1730 return OK;
1731 }
1732
generateStubSourceForMethod(Formatter & out,const Method * method,const Interface * superInterface) const1733 status_t AST::generateStubSourceForMethod(
1734 Formatter &out,
1735 const Method *method,
1736 const Interface* superInterface) const {
1737
1738 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1739 method->cppImpl(IMPL_STUB, out);
1740 out << "break;\n";
1741 return OK;
1742 }
1743
1744 out << "_hidl_err = "
1745 << superInterface->fqName().cppNamespace()
1746 << "::"
1747 << superInterface->getStubName()
1748 << "::_hidl_"
1749 << method->name()
1750 << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
1751 out << "break;\n";
1752
1753 return OK;
1754 }
1755
generateStaticStubMethodSource(Formatter & out,const std::string & klassName,const Method * method) const1756 status_t AST::generateStaticStubMethodSource(Formatter &out,
1757 const std::string &klassName,
1758 const Method *method) const {
1759 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1760 return OK;
1761 }
1762
1763 out << "::android::status_t " << klassName << "::_hidl_" << method->name() << "(\n";
1764
1765 out.indent();
1766 out.indent();
1767
1768 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
1769 << "const ::android::hardware::Parcel &_hidl_data,\n"
1770 << "::android::hardware::Parcel *_hidl_reply,\n"
1771 << "TransactCallback _hidl_cb) {\n";
1772
1773 out.unindent();
1774
1775 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1776 out << "bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();\n";
1777 out << "const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();\n";
1778 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1779
1780 out << "::android::status_t _hidl_err = ::android::OK;\n";
1781
1782 out << "if (!_hidl_data.enforceInterface("
1783 << klassName
1784 << "::Pure::descriptor)) {\n";
1785
1786 out.indent();
1787 out << "_hidl_err = ::android::BAD_TYPE;\n";
1788 out << "return _hidl_err;\n";
1789 out.unindent();
1790 out << "}\n\n";
1791
1792 declareCppReaderLocals(out, method->args(), false /* forResults */);
1793
1794 // First DFS: write buffers
1795 for (const auto &arg : method->args()) {
1796 emitCppReaderWriter(
1797 out,
1798 "_hidl_data",
1799 false /* parcelObjIsPointer */,
1800 arg,
1801 true /* reader */,
1802 Type::ErrorMode_Return,
1803 false /* addPrefixToName */);
1804 }
1805
1806 // Second DFS: resolve references
1807 for (const auto &arg : method->args()) {
1808 emitCppResolveReferences(
1809 out,
1810 "_hidl_data",
1811 false /* parcelObjIsPointer */,
1812 arg,
1813 true /* reader */,
1814 Type::ErrorMode_Return,
1815 false /* addPrefixToName */);
1816 }
1817
1818 generateCppInstrumentationCall(
1819 out,
1820 InstrumentationEvent::SERVER_API_ENTRY,
1821 method);
1822
1823 const bool returnsValue = !method->results().empty();
1824 const TypedVar *elidedReturn = method->canElideCallback();
1825
1826 std::string callee;
1827
1828 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL)) {
1829 callee = "_hidl_this";
1830 } else {
1831 callee = "static_cast<" + klassName + "*>(_hidl_this)->_hidl_mImpl";
1832 }
1833
1834 if (elidedReturn != nullptr) {
1835 out << elidedReturn->type().getCppResultType()
1836 << " _hidl_out_"
1837 << elidedReturn->name()
1838 << " = "
1839 << callee << "->" << method->name()
1840 << "(";
1841
1842 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
1843 if (arg->type().resultNeedsDeref()) {
1844 out << "*";
1845 }
1846 out << arg->name();
1847 });
1848
1849 out << ");\n\n";
1850 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1851 << "_hidl_reply);\n\n";
1852
1853 elidedReturn->type().emitReaderWriter(
1854 out,
1855 "_hidl_out_" + elidedReturn->name(),
1856 "_hidl_reply",
1857 true, /* parcelObjIsPointer */
1858 false, /* isReader */
1859 Type::ErrorMode_Ignore);
1860
1861 emitCppResolveReferences(
1862 out,
1863 "_hidl_reply",
1864 true /* parcelObjIsPointer */,
1865 elidedReturn,
1866 false /* reader */,
1867 Type::ErrorMode_Ignore,
1868 true /* addPrefixToName */);
1869
1870 generateCppInstrumentationCall(
1871 out,
1872 InstrumentationEvent::SERVER_API_EXIT,
1873 method);
1874
1875 out << "_hidl_cb(*_hidl_reply);\n";
1876 } else {
1877 if (returnsValue) {
1878 out << "bool _hidl_callbackCalled = false;\n\n";
1879 }
1880
1881 out << callee << "->" << method->name() << "(";
1882
1883 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
1884 if (arg->type().resultNeedsDeref()) {
1885 out << "*";
1886 }
1887
1888 out << arg->name();
1889 });
1890
1891 if (returnsValue) {
1892 if (!method->args().empty()) {
1893 out << ", ";
1894 }
1895
1896 out << "[&](";
1897
1898 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
1899 out << "const auto &_hidl_out_" << arg->name();
1900 });
1901
1902 out << ") {\n";
1903 out.indent();
1904 out << "if (_hidl_callbackCalled) {\n";
1905 out.indent();
1906 out << "LOG_ALWAYS_FATAL(\""
1907 << method->name()
1908 << ": _hidl_cb called a second time, but must be called once.\");\n";
1909 out.unindent();
1910 out << "}\n";
1911 out << "_hidl_callbackCalled = true;\n\n";
1912
1913 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1914 << "_hidl_reply);\n\n";
1915
1916 // First DFS: buffers
1917 for (const auto &arg : method->results()) {
1918 emitCppReaderWriter(
1919 out,
1920 "_hidl_reply",
1921 true /* parcelObjIsPointer */,
1922 arg,
1923 false /* reader */,
1924 Type::ErrorMode_Ignore,
1925 true /* addPrefixToName */);
1926 }
1927
1928 // Second DFS: resolve references
1929 for (const auto &arg : method->results()) {
1930 emitCppResolveReferences(
1931 out,
1932 "_hidl_reply",
1933 true /* parcelObjIsPointer */,
1934 arg,
1935 false /* reader */,
1936 Type::ErrorMode_Ignore,
1937 true /* addPrefixToName */);
1938 }
1939
1940 generateCppInstrumentationCall(
1941 out,
1942 InstrumentationEvent::SERVER_API_EXIT,
1943 method);
1944
1945 out << "_hidl_cb(*_hidl_reply);\n";
1946
1947 out.unindent();
1948 out << "});\n\n";
1949 } else {
1950 out << ");\n\n";
1951 out << "(void) _hidl_cb;\n\n";
1952 generateCppInstrumentationCall(
1953 out,
1954 InstrumentationEvent::SERVER_API_EXIT,
1955 method);
1956 }
1957
1958 if (returnsValue) {
1959 out << "if (!_hidl_callbackCalled) {\n";
1960 out.indent();
1961 out << "LOG_ALWAYS_FATAL(\""
1962 << method->name()
1963 << ": _hidl_cb not called, but must be called once.\");\n";
1964 out.unindent();
1965 out << "}\n\n";
1966 } else {
1967 out << "::android::hardware::writeToParcel("
1968 << "::android::hardware::Status::ok(), "
1969 << "_hidl_reply);\n\n";
1970 }
1971 }
1972
1973 out << "return _hidl_err;\n";
1974 out.unindent();
1975 out << "}\n\n";
1976
1977 return OK;
1978 }
1979
generatePassthroughHeader(const std::string & outputPath) const1980 status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1981 if (!AST::isInterface()) {
1982 // types.hal does not get a stub header.
1983 return OK;
1984 }
1985
1986 const Interface* iface = mRootScope.getInterface();
1987 CHECK(iface != nullptr);
1988
1989 const std::string klassName = iface->getPassthroughName();
1990
1991 bool supportOneway = iface->hasOnewayMethods();
1992
1993 std::string path = outputPath;
1994 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1995 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1996 path.append(klassName);
1997 path.append(".h");
1998
1999 CHECK(Coordinator::MakeParentHierarchy(path));
2000 FILE *file = fopen(path.c_str(), "w");
2001
2002 if (file == NULL) {
2003 return -errno;
2004 }
2005
2006 Formatter out(file);
2007
2008 const std::string guard = makeHeaderGuard(klassName);
2009
2010 out << "#ifndef " << guard << "\n";
2011 out << "#define " << guard << "\n\n";
2012
2013 std::vector<std::string> packageComponents;
2014 getPackageAndVersionComponents(
2015 &packageComponents, false /* cpp_compatible */);
2016
2017 out << "#include <android-base/macros.h>\n";
2018 out << "#include <cutils/trace.h>\n";
2019 out << "#include <future>\n";
2020
2021 generateCppPackageInclude(out, mPackage, iface->localName());
2022 out << "\n";
2023
2024 out << "#include <hidl/HidlPassthroughSupport.h>\n";
2025 if (supportOneway) {
2026 out << "#include <hidl/TaskRunner.h>\n";
2027 }
2028
2029 enterLeaveNamespace(out, true /* enter */);
2030 out << "\n";
2031
2032 out << "struct "
2033 << klassName
2034 << " : " << iface->localName()
2035 << ", ::android::hardware::details::HidlInstrumentor {\n";
2036
2037 out.indent();
2038 out << "explicit "
2039 << klassName
2040 << "(const ::android::sp<"
2041 << iface->localName()
2042 << "> impl);\n";
2043
2044 out.endl();
2045 generateTemplatizationLink(out);
2046
2047 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
2048 return generatePassthroughMethod(out, method);
2049 });
2050
2051 if (err != OK) {
2052 return err;
2053 }
2054
2055 out.unindent();
2056 out << "private:\n";
2057 out.indent();
2058 out << "const ::android::sp<" << iface->localName() << "> mImpl;\n";
2059
2060 if (supportOneway) {
2061 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
2062
2063 out << "\n";
2064
2065 out << "::android::hardware::Return<void> addOnewayTask("
2066 "std::function<void(void)>);\n\n";
2067 }
2068
2069 out.unindent();
2070
2071 out << "};\n\n";
2072
2073 enterLeaveNamespace(out, false /* enter */);
2074
2075 out << "\n#endif // " << guard << "\n";
2076
2077 return OK;
2078 }
2079
generateInterfaceSource(Formatter & out) const2080 status_t AST::generateInterfaceSource(Formatter &out) const {
2081 const Interface* iface = mRootScope.getInterface();
2082
2083 // generate castFrom functions
2084 std::string childTypeResult = iface->getCppResultType();
2085
2086 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
2087 bool reserved = method->isHidlReserved();
2088
2089 if (!reserved) {
2090 out << "// no default implementation for: ";
2091 }
2092 method->generateCppSignature(out, iface->localName());
2093 if (reserved) {
2094 out.block([&]() {
2095 method->cppImpl(IMPL_INTERFACE, out);
2096 }).endl();
2097 }
2098
2099 out << "\n";
2100
2101 return OK;
2102 });
2103 if (err != OK) {
2104 return err;
2105 }
2106
2107 for (const Interface *superType : iface->typeChain()) {
2108 out << "// static \n::android::hardware::Return<"
2109 << childTypeResult
2110 << "> "
2111 << iface->localName()
2112 << "::castFrom("
2113 << superType->getCppArgumentType()
2114 << " parent, bool "
2115 << (iface == superType ? "/* emitError */" : "emitError")
2116 << ") {\n";
2117 out.indent();
2118 if (iface == superType) {
2119 out << "return parent;\n";
2120 } else {
2121 out << "return ::android::hardware::details::castInterface<";
2122 out << iface->localName() << ", "
2123 << superType->fqName().cppName() << ", "
2124 << iface->getProxyName()
2125 << ">(\n";
2126 out.indent();
2127 out.indent();
2128 out << "parent, \""
2129 << iface->fqName().string()
2130 << "\", emitError);\n";
2131 out.unindent();
2132 out.unindent();
2133 }
2134 out.unindent();
2135 out << "}\n\n";
2136 }
2137
2138 return OK;
2139 }
2140
generatePassthroughSource(Formatter & out) const2141 status_t AST::generatePassthroughSource(Formatter &out) const {
2142 const Interface* iface = mRootScope.getInterface();
2143
2144 const std::string klassName = iface->getPassthroughName();
2145
2146 out << klassName
2147 << "::"
2148 << klassName
2149 << "(const ::android::sp<"
2150 << iface->fullName()
2151 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
2152 << mPackage.string()
2153 << "\", \""
2154 << iface->localName()
2155 << "\"), mImpl(impl) {";
2156 if (iface->hasOnewayMethods()) {
2157 out << "\n";
2158 out.indent([&] {
2159 out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
2160 });
2161 }
2162 out << "}\n\n";
2163
2164 if (iface->hasOnewayMethods()) {
2165 out << "::android::hardware::Return<void> "
2166 << klassName
2167 << "::addOnewayTask(std::function<void(void)> fun) {\n";
2168 out.indent();
2169 out << "if (!mOnewayQueue.push(fun)) {\n";
2170 out.indent();
2171 out << "return ::android::hardware::Status::fromExceptionCode(\n";
2172 out.indent();
2173 out.indent();
2174 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
2175 << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
2176 out.unindent();
2177 out.unindent();
2178 out.unindent();
2179 out << "}\n";
2180
2181 out << "return ::android::hardware::Status();\n";
2182
2183 out.unindent();
2184 out << "}\n\n";
2185
2186
2187 }
2188
2189 return OK;
2190 }
2191
generateCppAtraceCall(Formatter & out,InstrumentationEvent event,const Method * method) const2192 void AST::generateCppAtraceCall(Formatter &out,
2193 InstrumentationEvent event,
2194 const Method *method) const {
2195 const Interface* iface = mRootScope.getInterface();
2196 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
2197 switch (event) {
2198 case SERVER_API_ENTRY:
2199 {
2200 out << "atrace_begin(ATRACE_TAG_HAL, \""
2201 << baseString + "::server\");\n";
2202 break;
2203 }
2204 case CLIENT_API_ENTRY:
2205 {
2206 out << "atrace_begin(ATRACE_TAG_HAL, \""
2207 << baseString + "::client\");\n";
2208 break;
2209 }
2210 case PASSTHROUGH_ENTRY:
2211 {
2212 out << "atrace_begin(ATRACE_TAG_HAL, \""
2213 << baseString + "::passthrough\");\n";
2214 break;
2215 }
2216 case SERVER_API_EXIT:
2217 case CLIENT_API_EXIT:
2218 case PASSTHROUGH_EXIT:
2219 {
2220 out << "atrace_end(ATRACE_TAG_HAL);\n";
2221 break;
2222 }
2223 default:
2224 {
2225 LOG(FATAL) << "Unsupported instrumentation event: " << event;
2226 }
2227 }
2228 }
2229
generateCppInstrumentationCall(Formatter & out,InstrumentationEvent event,const Method * method) const2230 void AST::generateCppInstrumentationCall(
2231 Formatter &out,
2232 InstrumentationEvent event,
2233 const Method *method) const {
2234 generateCppAtraceCall(out, event, method);
2235
2236 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
2237 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
2238 out.indent();
2239 out << "std::vector<void *> _hidl_args;\n";
2240 std::string event_str = "";
2241 switch (event) {
2242 case SERVER_API_ENTRY:
2243 {
2244 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
2245 for (const auto &arg : method->args()) {
2246 out << "_hidl_args.push_back((void *)"
2247 << (arg->type().resultNeedsDeref() ? "" : "&")
2248 << arg->name()
2249 << ");\n";
2250 }
2251 break;
2252 }
2253 case SERVER_API_EXIT:
2254 {
2255 event_str = "InstrumentationEvent::SERVER_API_EXIT";
2256 for (const auto &arg : method->results()) {
2257 out << "_hidl_args.push_back((void *)&_hidl_out_"
2258 << arg->name()
2259 << ");\n";
2260 }
2261 break;
2262 }
2263 case CLIENT_API_ENTRY:
2264 {
2265 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2266 for (const auto &arg : method->args()) {
2267 out << "_hidl_args.push_back((void *)&"
2268 << arg->name()
2269 << ");\n";
2270 }
2271 break;
2272 }
2273 case CLIENT_API_EXIT:
2274 {
2275 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2276 for (const auto &arg : method->results()) {
2277 out << "_hidl_args.push_back((void *)"
2278 << (arg->type().resultNeedsDeref() ? "" : "&")
2279 << "_hidl_out_"
2280 << arg->name()
2281 << ");\n";
2282 }
2283 break;
2284 }
2285 case PASSTHROUGH_ENTRY:
2286 {
2287 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2288 for (const auto &arg : method->args()) {
2289 out << "_hidl_args.push_back((void *)&"
2290 << arg->name()
2291 << ");\n";
2292 }
2293 break;
2294 }
2295 case PASSTHROUGH_EXIT:
2296 {
2297 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
2298 for (const auto &arg : method->results()) {
2299 out << "_hidl_args.push_back((void *)&_hidl_out_"
2300 << arg->name()
2301 << ");\n";
2302 }
2303 break;
2304 }
2305 default:
2306 {
2307 LOG(FATAL) << "Unsupported instrumentation event: " << event;
2308 }
2309 }
2310
2311 const Interface* iface = mRootScope.getInterface();
2312
2313 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
2314 out.indent();
2315 out << "callback("
2316 << event_str
2317 << ", \""
2318 << mPackage.package()
2319 << "\", \""
2320 << mPackage.version()
2321 << "\", \""
2322 << iface->localName()
2323 << "\", \""
2324 << method->name()
2325 << "\", &_hidl_args);\n";
2326 out.unindent();
2327 out << "}\n";
2328 out.unindent();
2329 out << "}\n";
2330 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
2331 }
2332
2333 } // namespace android
2334