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