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