• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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             << "&notification);\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             << "&notification) ";
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