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 "HidlTypeAssertion.h"
22 #include "Interface.h"
23 #include "Location.h"
24 #include "Method.h"
25 #include "Reference.h"
26 #include "ScalarType.h"
27 #include "Scope.h"
28 
29 #include <algorithm>
30 #include <hidl-util/Formatter.h>
31 #include <hidl-util/StringHelper.h>
32 #include <android-base/logging.h>
33 #include <string>
34 #include <vector>
35 
36 namespace android {
37 
38 std::string AST::makeHeaderGuard(const std::string &baseName,
39                                  bool indicateGenerated) const {
40     std::string guard;
41 
42     if (indicateGenerated) {
43         guard += "HIDL_GENERATED_";
44     }
45 
46     guard += StringHelper::Uppercase(mPackage.tokenName());
47     guard += "_";
48     guard += StringHelper::Uppercase(baseName);
49     guard += "_H";
50 
51     return guard;
52 }
53 
54 void AST::generateCppPackageInclude(
55         Formatter &out,
56         const FQName &package,
57         const std::string &klass) {
58 
59     out << "#include <";
60 
61     std::vector<std::string> components =
62             package.getPackageAndVersionComponents(false /* sanitized */);
63 
64     for (const auto &component : components) {
65         out << component << "/";
66     }
67 
68     out << klass
69         << ".h>\n";
70 }
71 
72 void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
73     std::vector<std::string> packageComponents =
74             mPackage.getPackageAndVersionComponents(true /* sanitized */);
75 
76     if (enter) {
77         for (const auto &component : packageComponents) {
78             out << "namespace " << component << " {\n";
79         }
80     } else {
81         for (auto it = packageComponents.rbegin();
82                 it != packageComponents.rend();
83                 ++it) {
84             out << "}  // namespace " << *it << "\n";
85         }
86     }
87 }
88 
89 static void declareGetService(Formatter &out, const std::string &interfaceName, bool isTry) {
90     const std::string functionName = isTry ? "tryGetService" : "getService";
91 
92     if (isTry) {
93         DocComment(
94                 "This gets the service of this type with the specified instance name. If the\n"
95                 "service is currently not available or not in the VINTF manifest on a Trebilized\n"
96                 "device, this will return nullptr. This is useful when you don't want to block\n"
97                 "during device boot. If getStub is true, this will try to return an unwrapped\n"
98                 "passthrough implementation in the same process. This is useful when getting an\n"
99                 "implementation from the same partition/compilation group.\n\n"
100                 "In general, prefer getService(std::string,bool)",
101                 HIDL_LOCATION_HERE)
102                 .emit(out);
103     } else {
104         DocComment(
105                 "This gets the service of this type with the specified instance name. If the\n"
106                 "service is not in the VINTF manifest on a Trebilized device, this will return\n"
107                 "nullptr. If the service is not available, this will wait for the service to\n"
108                 "become available. If the service is a lazy service, this will start the service\n"
109                 "and return when it becomes available. If getStub is true, this will try to\n"
110                 "return an unwrapped passthrough implementation in the same process. This is\n"
111                 "useful when getting an implementation from the same partition/compilation group.",
112                 HIDL_LOCATION_HERE)
113                 .emit(out);
114     }
115     out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
116         << "const std::string &serviceName=\"default\", bool getStub=false);\n";
117     DocComment("Deprecated. See " + functionName + "(std::string, bool)", HIDL_LOCATION_HERE)
118             .emit(out);
119     out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
120         << "const char serviceName[], bool getStub=false)"
121         << "  { std::string str(serviceName ? serviceName : \"\");"
122         << "      return " << functionName << "(str, getStub); }\n";
123     DocComment("Deprecated. See " + functionName + "(std::string, bool)", HIDL_LOCATION_HERE)
124             .emit(out);
125     out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
126         << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
127         // without c_str the std::string constructor is ambiguous
128         << "  { std::string str(serviceName.c_str());"
129         << "      return " << functionName << "(str, getStub); }\n";
130     DocComment("Calls " + functionName +
131                        "(\"default\", bool). This is the recommended instance name for singleton "
132                        "services.",
133                HIDL_LOCATION_HERE)
134             .emit(out);
135     out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
136         << "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
137 }
138 
139 static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
140     declareGetService(out, interfaceName, true /* isTry */);
141     declareGetService(out, interfaceName, false /* isTry */);
142 
143     DocComment(
144             "Registers a service with the service manager. For Trebilized devices, the service\n"
145             "must also be in the VINTF manifest.",
146             HIDL_LOCATION_HERE)
147             .emit(out);
148     out << "__attribute__ ((warn_unused_result))"
149         << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
150     DocComment("Registers for notifications for when a service is registered.", HIDL_LOCATION_HERE)
151             .emit(out);
152     out << "static bool registerForNotifications(\n";
153     out.indent(2, [&] {
154         out << "const std::string &serviceName,\n"
155             << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
156             << "&notification);\n";
157     });
158 
159 }
160 
161 static void implementGetService(Formatter &out,
162         const FQName &fqName,
163         bool isTry) {
164 
165     const std::string interfaceName = fqName.getInterfaceName();
166     const std::string functionName = isTry ? "tryGetService" : "getService";
167 
168     out << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
169         << "const std::string &serviceName, const bool getStub) ";
170     out.block([&] {
171         out << "return ::android::hardware::details::getServiceInternal<"
172             << fqName.getInterfaceProxyName()
173             << ">(serviceName, "
174             << (!isTry ? "true" : "false") // retry
175             << ", getStub);\n";
176     }).endl().endl();
177 }
178 
179 static void implementServiceManagerInteractions(Formatter &out,
180         const FQName &fqName, const std::string &package) {
181 
182     const std::string interfaceName = fqName.getInterfaceName();
183 
184     implementGetService(out, fqName, true /* isTry */);
185     implementGetService(out, fqName, false /* isTry */);
186 
187     out << "::android::status_t " << interfaceName << "::registerAsService("
188         << "const std::string &serviceName) ";
189     out.block([&] {
190         out << "return ::android::hardware::details::registerAsServiceInternal(this, serviceName);\n";
191     }).endl().endl();
192 
193     out << "bool " << interfaceName << "::registerForNotifications(\n";
194     out.indent(2, [&] {
195         out << "const std::string &serviceName,\n"
196             << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
197             << "&notification) ";
198     });
199     out.block([&] {
200         out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
201         out.indent(2, [&] {
202             out << "= ::android::hardware::defaultServiceManager();\n";
203         });
204         out.sIf("sm == nullptr", [&] {
205             out << "return false;\n";
206         }).endl();
207         out << "::android::hardware::Return<bool> success =\n";
208         out.indent(2, [&] {
209             out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
210             out.indent(2, [&] {
211                 out << "serviceName, notification);\n";
212             });
213         });
214         out << "return success.isOk() && success;\n";
215     }).endl().endl();
216 }
217 
218 void AST::generateInterfaceHeader(Formatter& out) const {
219     const Interface *iface = getInterface();
220     std::string ifaceName = iface ? iface->definedName() : "types";
221     const std::string guard = makeHeaderGuard(ifaceName);
222 
223     out << "#ifndef " << guard << "\n";
224     out << "#define " << guard << "\n\n";
225 
226     for (const auto &item : mImportedNames) {
227         generateCppPackageInclude(out, item, item.name());
228     }
229 
230     if (!mImportedNames.empty()) {
231         out << "\n";
232     }
233 
234     if (iface) {
235         if (isIBase()) {
236             out << "// skipped #include IServiceNotification.h\n\n";
237         } else {
238             out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
239         }
240     }
241 
242     out << "#include <hidl/HidlSupport.h>\n";
243     out << "#include <hidl/MQDescriptor.h>\n";
244 
245     if (iface) {
246         out << "#include <hidl/Status.h>\n";
247     }
248 
249     out << "#include <utils/NativeHandle.h>\n";
250     out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
251 
252     enterLeaveNamespace(out, true /* enter */);
253     out << "\n";
254 
255     if (iface) {
256         iface->emitDocComment(out);
257 
258         out << "struct "
259             << ifaceName;
260 
261         const Interface *superType = iface->superType();
262 
263         if (superType == nullptr) {
264             out << " : virtual public ::android::RefBase";
265         } else {
266             out << " : public "
267                 << superType->fullName();
268         }
269 
270         out << " {\n";
271 
272         out.indent();
273 
274         DocComment("Type tag for use in template logic that indicates this is a 'pure' class.",
275                    HIDL_LOCATION_HERE)
276                 .emit(out);
277         generateCppTag(out, "::android::hardware::details::i_tag");
278 
279         DocComment("Fully qualified interface name: \"" + iface->fqName().string() + "\"",
280                    HIDL_LOCATION_HERE)
281                 .emit(out);
282         out << "static const char* descriptor;\n\n";
283 
284         iface->emitTypeDeclarations(out);
285     } else {
286         mRootScope.emitTypeDeclarations(out);
287     }
288 
289     if (iface) {
290         DocComment(
291                 "Returns whether this object's implementation is outside of the current process.",
292                 HIDL_LOCATION_HERE)
293                 .emit(out);
294         out << "virtual bool isRemote() const ";
295         if (!isIBase()) {
296             out << "override ";
297         }
298         out << "{ return false; }\n";
299 
300         for (const auto& tuple : iface->allMethodsFromRoot()) {
301             const Method* method = tuple.method();
302 
303             out << "\n";
304 
305             const bool returnsValue = !method->results().empty();
306             const NamedReference<Type>* elidedReturn = method->canElideCallback();
307 
308             if (elidedReturn == nullptr && returnsValue) {
309                 DocComment("Return callback for " + method->name(), HIDL_LOCATION_HERE).emit(out);
310                 out << "using "
311                     << method->name()
312                     << "_cb = std::function<void(";
313                 method->emitCppResultSignature(out, true /* specify namespaces */);
314                 out << ")>;\n";
315             }
316 
317             method->emitDocComment(out);
318 
319             if (elidedReturn) {
320                 out << "virtual ::android::hardware::Return<";
321                 out << elidedReturn->type().getCppResultType() << "> ";
322             } else {
323                 out << "virtual ::android::hardware::Return<void> ";
324             }
325 
326             out << method->name()
327                 << "(";
328             method->emitCppArgSignature(out, true /* specify namespaces */);
329             out << ")";
330             if (method->isHidlReserved()) {
331                 if (!isIBase()) {
332                     out << " override";
333                 }
334             } else {
335                 out << " = 0";
336             }
337             out << ";\n";
338         }
339 
340         out << "\n// cast static functions\n";
341         std::string childTypeResult = iface->getCppResultType();
342 
343         for (const Interface *superType : iface->typeChain()) {
344             DocComment(
345                     "This performs a checked cast based on what the underlying implementation "
346                     "actually is.",
347                     HIDL_LOCATION_HERE)
348                     .emit(out);
349             out << "static ::android::hardware::Return<"
350                 << childTypeResult
351                 << "> castFrom("
352                 << superType->getCppArgumentType()
353                 << " parent"
354                 << ", bool emitError = false);\n";
355         }
356 
357         if (isIBase()) {
358             out << "\n// skipped getService, registerAsService, registerForNotifications\n\n";
359         } else {
360             out << "\n// helper methods for interactions with the hwservicemanager\n";
361             declareServiceManagerInteractions(out, iface->definedName());
362         }
363     }
364 
365     if (iface) {
366         out.unindent();
367 
368         out << "};\n\n";
369     }
370 
371     out << "//\n";
372     out << "// type declarations for package\n";
373     out << "//\n\n";
374     mRootScope.emitPackageTypeDeclarations(out);
375     out << "//\n";
376     out << "// type header definitions for package\n";
377     out << "//\n\n";
378     mRootScope.emitPackageTypeHeaderDefinitions(out);
379 
380     out << "\n";
381     enterLeaveNamespace(out, false /* enter */);
382     out << "\n";
383 
384     out << "//\n";
385     out << "// global type declarations for package\n";
386     out << "//\n\n";
387     mRootScope.emitGlobalTypeDeclarations(out);
388 
389     out << "\n#endif  // " << guard << "\n";
390 }
391 
392 void AST::generateHwBinderHeader(Formatter& out) const {
393     const Interface *iface = getInterface();
394     std::string klassName = iface ? iface->getHwName() : "hwtypes";
395 
396     const std::string guard = makeHeaderGuard(klassName);
397 
398     out << "#ifndef " << guard << "\n";
399     out << "#define " << guard << "\n\n";
400 
401     generateCppPackageInclude(out, mPackage, iface ? iface->definedName() : "types");
402 
403     out << "\n";
404 
405     for (const auto &item : mImportedNames) {
406         if (item.name() == "types") {
407             generateCppPackageInclude(out, item, "hwtypes");
408         } else {
409             generateCppPackageInclude(out, item, item.getInterfaceStubName());
410             generateCppPackageInclude(out, item, item.getInterfaceProxyName());
411         }
412     }
413 
414     out << "\n";
415 
416     out << "#include <hidl/Status.h>\n";
417     out << "#include <hwbinder/IBinder.h>\n";
418     out << "#include <hwbinder/Parcel.h>\n";
419 
420     out << "\n";
421 
422     enterLeaveNamespace(out, true /* enter */);
423 
424     mRootScope.emitPackageHwDeclarations(out);
425 
426     enterLeaveNamespace(out, false /* enter */);
427 
428     out << "\n#endif  // " << guard << "\n";
429 }
430 
431 static std::string wrapPassthroughArg(Formatter& out, const NamedReference<Type>* arg,
432                                       std::string name, std::function<void(void)> handleError) {
433     if (!arg->type().isInterface()) {
434         return name;
435     }
436     std::string wrappedName = "_hidl_wrapped_" + name;
437     const Interface &iface = static_cast<const Interface &>(arg->type());
438     out << iface.getCppStackType() << " " << wrappedName << ";\n";
439     // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
440     out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
441         out << wrappedName
442             << " = "
443             << "::android::hardware::details::wrapPassthrough("
444             << name
445             << ");\n";
446         out.sIf(wrappedName + " == nullptr", [&] {
447             // Fatal error. Happens when the BsFoo class is not found in the binary
448             // or any dynamic libraries.
449             handleError();
450         }).endl();
451     }).sElse([&] {
452         out << wrappedName << " = " << name << ";\n";
453     }).endl().endl();
454 
455     return wrappedName;
456 }
457 
458 void AST::generatePassthroughMethod(Formatter& out, const Method* method, const Interface* superInterface) const {
459     method->generateCppSignature(out);
460 
461     out << " override {\n";
462     out.indent();
463 
464     if (method->isHidlReserved()
465         && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
466         method->cppImpl(IMPL_PASSTHROUGH, out);
467         out.unindent();
468         out << "}\n\n";
469         return;
470     }
471 
472     const bool returnsValue = !method->results().empty();
473     const NamedReference<Type>* elidedReturn = method->canElideCallback();
474 
475     generateCppInstrumentationCall(
476             out,
477             InstrumentationEvent::PASSTHROUGH_ENTRY,
478             method,
479             superInterface);
480 
481     std::vector<std::string> wrappedArgNames;
482     for (const auto &arg : method->args()) {
483         std::string name = wrapPassthroughArg(out, arg, arg->name(), [&] {
484             out << "return ::android::hardware::Status::fromExceptionCode(\n";
485             out.indent(2, [&] {
486                 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
487                     << "\"Cannot wrap passthrough interface.\");\n";
488             });
489         });
490 
491         wrappedArgNames.push_back(name);
492     }
493 
494     out << "::android::hardware::Status _hidl_error = ::android::hardware::Status::ok();\n";
495     out << "auto _hidl_return = ";
496 
497     if (method->isOneway()) {
498         out << "addOnewayTask([mImpl = this->mImpl\n"
499             << "#ifdef __ANDROID_DEBUGGABLE__\n"
500                ", mEnableInstrumentation = this->mEnableInstrumentation, "
501                "mInstrumentationCallbacks = this->mInstrumentationCallbacks\n"
502             << "#endif // __ANDROID_DEBUGGABLE__\n";
503         for (const std::string& arg : wrappedArgNames) {
504             out << ", " << arg;
505         }
506         out << "] {\n";
507         out.indent();
508     }
509 
510     out << "mImpl->"
511         << method->name()
512         << "(";
513 
514     out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
515         out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
516     });
517 
518     std::function<void(void)> kHandlePassthroughError = [&] {
519         out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
520         out.indent(2, [&] {
521             out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
522                 << "\"Cannot wrap passthrough interface.\");\n";
523         });
524     };
525 
526     if (returnsValue && elidedReturn == nullptr) {
527         // never true if oneway since oneway methods don't return values
528 
529         if (!method->args().empty()) {
530             out << ", ";
531         }
532         out << "[&](";
533         out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
534             out << "const auto &_hidl_out_"
535                 << arg->name();
536         });
537 
538         out << ") {\n";
539         out.indent();
540         generateCppInstrumentationCall(
541                 out,
542                 InstrumentationEvent::PASSTHROUGH_EXIT,
543                 method,
544                 superInterface);
545 
546         std::vector<std::string> wrappedOutNames;
547         for (const auto &arg : method->results()) {
548             wrappedOutNames.push_back(
549                 wrapPassthroughArg(out, arg, "_hidl_out_" + arg->name(), kHandlePassthroughError));
550         }
551 
552         out << "_hidl_cb(";
553         out.join(wrappedOutNames.begin(), wrappedOutNames.end(), ", ",
554                  [&](const std::string& arg) { out << arg; });
555         out << ");\n";
556         out.unindent();
557         out << "});\n\n";
558     } else {
559         out << ");\n\n";
560 
561         if (elidedReturn != nullptr) {
562             const std::string outName = "_hidl_out_" + elidedReturn->name();
563 
564             out << elidedReturn->type().getCppResultType() << " " << outName
565                 << " = _hidl_return;\n";
566             out << "(void) " << outName << ";\n";
567 
568             const std::string wrappedName =
569                 wrapPassthroughArg(out, elidedReturn, outName, kHandlePassthroughError);
570 
571             if (outName != wrappedName) {
572                 // update the original value since it is used by generateCppInstrumentationCall
573                 out << outName << " = " << wrappedName << ";\n\n";
574 
575                 // update the value to be returned
576                 out << "_hidl_return = " << outName << "\n;";
577             }
578         }
579         generateCppInstrumentationCall(
580                 out,
581                 InstrumentationEvent::PASSTHROUGH_EXIT,
582                 method,
583                 superInterface);
584     }
585 
586     if (method->isOneway()) {
587         out.unindent();
588         out << "});\n";
589     } else {
590         out << "if (!_hidl_error.isOk()) return _hidl_error;\n";
591     }
592 
593     out << "return _hidl_return;\n";
594 
595     out.unindent();
596     out << "}\n";
597 }
598 
599 void AST::generateMethods(Formatter& out, const MethodGenerator& gen, bool includeParent) const {
600     const Interface* iface = mRootScope.getInterface();
601 
602     const Interface *prevIterface = nullptr;
603     for (const auto &tuple : iface->allMethodsFromRoot()) {
604         const Method *method = tuple.method();
605         const Interface *superInterface = tuple.interface();
606 
607         if (!includeParent && superInterface != iface) {
608             continue;
609         }
610 
611         if(prevIterface != superInterface) {
612             if (prevIterface != nullptr) {
613                 out << "\n";
614             }
615             out << "// Methods from "
616                 << superInterface->fullName()
617                 << " follow.\n";
618             prevIterface = superInterface;
619         }
620         gen(method, superInterface);
621     }
622 
623     out << "\n";
624 }
625 
626 void AST::generateTemplatizationLink(Formatter& out) const {
627     DocComment("The pure class is what this class wraps.", HIDL_LOCATION_HERE).emit(out);
628     out << "typedef " << mRootScope.getInterface()->definedName() << " Pure;\n\n";
629 }
630 
631 void AST::generateCppTag(Formatter& out, const std::string& tag) const {
632     out << "typedef " << tag << " _hidl_tag;\n\n";
633 }
634 
635 void AST::generateStubHeader(Formatter& out) const {
636     CHECK(AST::isInterface());
637 
638     const Interface* iface = mRootScope.getInterface();
639     const std::string klassName = iface->getStubName();
640     const std::string guard = makeHeaderGuard(klassName);
641 
642     out << "#ifndef " << guard << "\n";
643     out << "#define " << guard << "\n\n";
644 
645     generateCppPackageInclude(out, mPackage, iface->getHwName());
646 
647     out << "\n";
648 
649     enterLeaveNamespace(out, true /* enter */);
650     out << "\n";
651 
652     out << "struct "
653         << klassName;
654     if (iface->isIBase()) {
655         out << " : public ::android::hardware::BHwBinder";
656         out << ", public ::android::hardware::details::HidlInstrumentor {\n";
657     } else {
658         out << " : public "
659             << gIBaseFqName.getInterfaceStubFqName().cppName()
660             << " {\n";
661     }
662 
663     out.indent();
664     out << "explicit " << klassName << "(const ::android::sp<" << iface->definedName()
665         << "> &_hidl_impl);"
666         << "\n";
667     out << "explicit " << klassName << "(const ::android::sp<" << iface->definedName()
668         << "> &_hidl_impl,"
669         << " const std::string& HidlInstrumentor_package,"
670         << " const std::string& HidlInstrumentor_interface);"
671         << "\n\n";
672     out << "virtual ~" << klassName << "();\n\n";
673     out << "::android::status_t onTransact(\n";
674     out.indent();
675     out.indent();
676     out << "uint32_t _hidl_code,\n";
677     out << "const ::android::hardware::Parcel &_hidl_data,\n";
678     out << "::android::hardware::Parcel *_hidl_reply,\n";
679     out << "uint32_t _hidl_flags = 0,\n";
680     out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
681     out.unindent();
682     out.unindent();
683 
684     out.endl();
685     generateTemplatizationLink(out);
686     DocComment("Type tag for use in template logic that indicates this is a 'native' class.",
687                HIDL_LOCATION_HERE)
688             .emit(out);
689     generateCppTag(out, "::android::hardware::details::bnhw_tag");
690 
691     out << "::android::sp<" << iface->definedName() << "> getImpl() { return _hidl_mImpl; }\n";
692 
693     // Because the Bn class hierarchy always inherits from BnHwBase (and no other parent classes)
694     // and also no HIDL-specific things exist in the base binder classes, whenever we want to do
695     // C++ HIDL things with a binder, we only have the choice to convert it into a BnHwBase.
696     // Other hwbinder C++ class hierarchies (namely the one used for Java binder) will still
697     // be libhwbinder binders, but they are not instances of BnHwBase.
698     if (isIBase()) {
699         out << "bool checkSubclass(const void* subclassID) const;\n";
700     }
701 
702     generateMethods(out,
703                     [&](const Method* method, const Interface*) {
704                         if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
705                             return;
706                         }
707 
708                         out << "static ::android::status_t _hidl_" << method->name() << "(\n";
709 
710                         out.indent(2,
711                                    [&] {
712                                        out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
713                                            << "const ::android::hardware::Parcel &_hidl_data,\n"
714                                            << "::android::hardware::Parcel *_hidl_reply,\n"
715                                            << "TransactCallback _hidl_cb);\n";
716                                    })
717                             .endl()
718                             .endl();
719                     },
720                     false /* include parents */);
721 
722     out.unindent();
723     out << "private:\n";
724     out.indent();
725 
726     generateMethods(out, [&](const Method* method, const Interface* iface) {
727         if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
728             return;
729         }
730         const bool returnsValue = !method->results().empty();
731         const NamedReference<Type>* elidedReturn = method->canElideCallback();
732 
733         if (elidedReturn == nullptr && returnsValue) {
734             out << "using " << method->name() << "_cb = "
735                 << iface->fqName().cppName()
736                 << "::" << method->name() << "_cb;\n";
737         }
738         method->generateCppSignature(out);
739         out << ";\n";
740     });
741 
742     out << "::android::sp<" << iface->definedName() << "> _hidl_mImpl;\n";
743     out.unindent();
744     out << "};\n\n";
745 
746     enterLeaveNamespace(out, false /* enter */);
747 
748     out << "\n#endif  // " << guard << "\n";
749 }
750 
751 void AST::generateProxyHeader(Formatter& out) const {
752     if (!AST::isInterface()) {
753         // types.hal does not get a proxy header.
754         return;
755     }
756 
757     const Interface* iface = mRootScope.getInterface();
758     const std::string proxyName = iface->getProxyName();
759     const std::string guard = makeHeaderGuard(proxyName);
760 
761     out << "#ifndef " << guard << "\n";
762     out << "#define " << guard << "\n\n";
763 
764     out << "#include <hidl/HidlTransportSupport.h>\n\n";
765 
766     generateCppPackageInclude(out, mPackage, iface->getHwName());
767     out << "\n";
768 
769     enterLeaveNamespace(out, true /* enter */);
770     out << "\n";
771 
772     out << "struct " << proxyName << " : public ::android::hardware::BpInterface<"
773         << iface->definedName() << ">, public ::android::hardware::details::HidlInstrumentor {\n";
774 
775     out.indent();
776 
777     out << "explicit "
778         << proxyName
779         << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
780         << "\n\n";
781 
782     generateTemplatizationLink(out);
783     DocComment("Type tag for use in template logic that indicates this is a 'proxy' class.",
784                HIDL_LOCATION_HERE)
785             .emit(out);
786     generateCppTag(out, "::android::hardware::details::bphw_tag");
787 
788     out << "virtual bool isRemote() const override { return true; }\n\n";
789 
790     out << "void onLastStrongRef(const void* id) override;\n\n";
791 
792     generateMethods(
793         out,
794         [&](const Method* method, const Interface*) {
795             if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
796                 return;
797             }
798 
799             out << "static ";
800             method->generateCppReturnType(out);
801             out << " _hidl_" << method->name() << "("
802                 << "::android::hardware::IInterface* _hidl_this, "
803                 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
804 
805             if (!method->hasEmptyCppArgSignature()) {
806                 out << ", ";
807             }
808             method->emitCppArgSignature(out);
809             out << ");\n";
810         },
811         false /* include parents */);
812 
813     generateMethods(out, [&](const Method* method, const Interface*) {
814         method->generateCppSignature(out);
815         out << " override;\n";
816     });
817 
818     out.unindent();
819     out << "private:\n";
820     out.indent();
821     out << "std::mutex _hidl_mMutex;\n"
822         << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
823         << " _hidl_mDeathRecipients;\n";
824     out.unindent();
825     out << "};\n\n";
826 
827     enterLeaveNamespace(out, false /* enter */);
828 
829     out << "\n#endif  // " << guard << "\n";
830 }
831 
832 void AST::generateCppSource(Formatter& out) const {
833     std::string baseName = getBaseName();
834     const Interface *iface = getInterface();
835 
836     const std::string klassName = baseName + (baseName == "types" ? "" : "All");
837 
838     out << "#define LOG_TAG \""
839         << mPackage.string() << "::" << baseName
840         << "\"\n\n";
841 
842     out << "#include <log/log.h>\n";
843     out << "#include <cutils/trace.h>\n";
844     out << "#include <hidl/HidlTransportSupport.h>\n\n";
845     out << "#include <hidl/Static.h>\n";
846     out << "#include <hwbinder/ProcessState.h>\n";
847     out << "#include <utils/Trace.h>\n";
848     if (iface) {
849         // This is a no-op for IServiceManager itself.
850         out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
851 
852         generateCppPackageInclude(out, mPackage, iface->getProxyName());
853         generateCppPackageInclude(out, mPackage, iface->getStubName());
854         generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
855 
856         for (const Interface *superType : iface->superTypeChain()) {
857             generateCppPackageInclude(out,
858                                       superType->fqName(),
859                                       superType->fqName().getInterfaceProxyName());
860         }
861 
862         out << "#include <hidl/ServiceManagement.h>\n";
863     } else {
864         generateCppPackageInclude(out, mPackage, "types");
865         generateCppPackageInclude(out, mPackage, "hwtypes");
866     }
867 
868     out << "\n";
869 
870     enterLeaveNamespace(out, true /* enter */);
871     out << "\n";
872 
873     generateTypeSource(out, iface ? iface->definedName() : "");
874 
875     if (iface) {
876         const Interface* iface = mRootScope.getInterface();
877 
878         // need to be put here, generateStubSource is using this.
879         out << "const char* " << iface->definedName() << "::descriptor(\""
880             << iface->fqName().string() << "\");\n\n";
881         out << "__attribute__((constructor)) ";
882         out << "static void static_constructor() {\n";
883         out.indent([&] {
884             out << "::android::hardware::details::getBnConstructorMap().set("
885                 << iface->definedName() << "::descriptor,\n";
886             out.indent(2, [&] {
887                 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
888                 out.indent([&] {
889                     out << "return new " << iface->getStubName() << "(static_cast<"
890                         << iface->definedName() << " *>(iIntf));\n";
891                 });
892                 out << "});\n";
893             });
894             out << "::android::hardware::details::getBsConstructorMap().set("
895                 << iface->definedName() << "::descriptor,\n";
896             out.indent(2, [&] {
897                 out << "[](void *iIntf) -> ::android::sp<"
898                     << gIBaseFqName.cppName()
899                     << "> {\n";
900                 out.indent([&] {
901                     out << "return new " << iface->getPassthroughName() << "(static_cast<"
902                         << iface->definedName() << " *>(iIntf));\n";
903                 });
904                 out << "});\n";
905             });
906         });
907         out << "}\n\n";
908         out << "__attribute__((destructor))";
909         out << "static void static_destructor() {\n";
910         out.indent([&] {
911             out << "::android::hardware::details::getBnConstructorMap().erase("
912                 << iface->definedName() << "::descriptor);\n";
913             out << "::android::hardware::details::getBsConstructorMap().erase("
914                 << iface->definedName() << "::descriptor);\n";
915         });
916         out << "}\n\n";
917 
918         generateInterfaceSource(out);
919         generateProxySource(out, iface->fqName());
920         generateStubSource(out, iface);
921         generatePassthroughSource(out);
922 
923         if (isIBase()) {
924             out << "// skipped getService, registerAsService, registerForNotifications\n";
925         } else {
926             std::string package = iface->fqName().package()
927                     + iface->fqName().atVersion();
928 
929             implementServiceManagerInteractions(out, iface->fqName(), package);
930         }
931     }
932 
933     HidlTypeAssertion::EmitAll(out);
934     out << "\n";
935 
936     enterLeaveNamespace(out, false /* enter */);
937 }
938 
939 void AST::generateTypeSource(Formatter& out, const std::string& ifaceName) const {
940     mRootScope.emitTypeDefinitions(out, ifaceName);
941 }
942 
943 void AST::declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& args,
944                                  bool forResults) const {
945     if (args.empty()) {
946         return;
947     }
948 
949     for (const auto &arg : args) {
950         const Type &type = arg->type();
951 
952         out << type.getCppResultType()
953             << " "
954             << (forResults ? "_hidl_out_" : "") + arg->name()
955             << ";\n";
956     }
957 
958     out << "\n";
959 }
960 
961 void AST::emitCppReaderWriter(Formatter& out, const std::string& parcelObj, bool parcelObjIsPointer,
962                               const NamedReference<Type>* arg, bool isReader, Type::ErrorMode mode,
963                               bool addPrefixToName) const {
964     const Type &type = arg->type();
965 
966     type.emitReaderWriter(
967             out,
968             addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
969             parcelObj,
970             parcelObjIsPointer,
971             isReader,
972             mode);
973 }
974 
975 void AST::generateProxyMethodSource(Formatter& out, const std::string& klassName,
976                                     const Method* method, const Interface* superInterface) const {
977     method->generateCppSignature(out,
978                                  klassName,
979                                  true /* specify namespaces */);
980 
981     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
982         out.block([&] {
983             method->cppImpl(IMPL_PROXY, out);
984         }).endl().endl();
985         return;
986     }
987 
988     out.block([&] {
989         const bool returnsValue = !method->results().empty();
990         const NamedReference<Type>* elidedReturn = method->canElideCallback();
991 
992         method->generateCppReturnType(out);
993 
994         out << " _hidl_out = "
995             << superInterface->fqName().cppNamespace()
996             << "::"
997             << superInterface->getProxyName()
998             << "::_hidl_"
999             << method->name()
1000             << "(this, this";
1001 
1002         if (!method->hasEmptyCppArgSignature()) {
1003             out << ", ";
1004         }
1005 
1006         out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
1007             out << arg->name();
1008         });
1009 
1010         if (returnsValue && elidedReturn == nullptr) {
1011             if (!method->args().empty()) {
1012                 out << ", ";
1013             }
1014             out << "_hidl_cb";
1015         }
1016 
1017         out << ");\n\n";
1018 
1019         out << "return _hidl_out;\n";
1020     }).endl().endl();
1021 }
1022 
1023 void AST::generateStaticProxyMethodSource(Formatter& out, const std::string& klassName,
1024                                           const Method* method, const Interface* superInterface) const {
1025     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1026         return;
1027     }
1028 
1029     method->generateCppReturnType(out);
1030 
1031     out << klassName
1032         << "::_hidl_"
1033         << method->name()
1034         << "("
1035         << "::android::hardware::IInterface *_hidl_this, "
1036         << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
1037 
1038     if (!method->hasEmptyCppArgSignature()) {
1039         out << ", ";
1040     }
1041 
1042     method->emitCppArgSignature(out);
1043     out << ") {\n";
1044 
1045     out.indent();
1046 
1047     out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1048     out << "bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();\n";
1049     out << "const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();\n";
1050     out << "#else\n";
1051     out << "(void) _hidl_this_instrumentor;\n";
1052     out << "#endif // __ANDROID_DEBUGGABLE__\n";
1053 
1054     const bool returnsValue = !method->results().empty();
1055     const NamedReference<Type>* elidedReturn = method->canElideCallback();
1056     const bool hasCallback = returnsValue && elidedReturn == nullptr;
1057 
1058     generateCppInstrumentationCall(
1059             out,
1060             InstrumentationEvent::CLIENT_API_ENTRY,
1061             method,
1062             superInterface);
1063 
1064     out << "::android::hardware::Parcel _hidl_data;\n";
1065     out << "::android::hardware::Parcel _hidl_reply;\n";
1066     out << "::android::status_t _hidl_err;\n";
1067     out << "::android::status_t _hidl_transact_err;\n";
1068     out << "::android::hardware::Status _hidl_status;\n\n";
1069 
1070     if (!hasCallback) {
1071         declareCppReaderLocals(
1072                 out, method->results(), true /* forResults */);
1073     }
1074 
1075     out << "_hidl_err = _hidl_data.writeInterfaceToken(";
1076     out << klassName;
1077     out << "::descriptor);\n";
1078     out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1079 
1080     bool hasInterfaceArgument = false;
1081 
1082     for (const auto &arg : method->args()) {
1083         if (arg->type().isInterface()) {
1084             hasInterfaceArgument = true;
1085         }
1086         emitCppReaderWriter(
1087                 out,
1088                 "_hidl_data",
1089                 false /* parcelObjIsPointer */,
1090                 arg,
1091                 false /* reader */,
1092                 Type::ErrorMode_Goto,
1093                 false /* addPrefixToName */);
1094     }
1095 
1096     if (hasInterfaceArgument) {
1097         // Start binder threadpool to handle incoming transactions
1098         out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1099     }
1100     out << "_hidl_transact_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact("
1101         << method->getSerialId()
1102         << " /* "
1103         << method->name()
1104         << " */, _hidl_data, &_hidl_reply";
1105 
1106     if (method->isOneway()) {
1107         out << ", " << Interface::FLAG_ONE_WAY->cppValue();
1108     } else {
1109         out << ", 0";
1110     }
1111 
1112     if (hasCallback) {
1113         out << ", [&] (::android::hardware::Parcel& _hidl_reply) {\n";
1114         out.indent();
1115         declareCppReaderLocals(
1116                 out, method->results(), true /* forResults */);
1117         out.endl();
1118     } else {
1119         out << ");\n";
1120         out << "if (_hidl_transact_err != ::android::OK) \n";
1121         out.block([&] {
1122             out << "_hidl_err = _hidl_transact_err;\n";
1123             out << "goto _hidl_error;\n";
1124         }).endl().endl();
1125     }
1126 
1127     if (!method->isOneway()) {
1128         Type::ErrorMode errorMode = hasCallback ? Type::ErrorMode_ReturnNothing : Type::ErrorMode_Goto;
1129 
1130         out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
1131         Type::handleError(out, errorMode);
1132 
1133         if (hasCallback) {
1134             out << "if (!_hidl_status.isOk()) { return; }\n\n";
1135         } else {
1136             out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1137         }
1138 
1139         for (const auto &arg : method->results()) {
1140             emitCppReaderWriter(
1141                     out,
1142                     "_hidl_reply",
1143                     false /* parcelObjIsPointer */,
1144                     arg,
1145                     true /* reader */,
1146                     errorMode,
1147                     true /* addPrefixToName */);
1148         }
1149 
1150         if (returnsValue && elidedReturn == nullptr) {
1151             out << "_hidl_cb(";
1152 
1153             out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
1154                 if (arg->type().resultNeedsDeref()) {
1155                     out << "*";
1156                 }
1157                 out << "_hidl_out_" << arg->name();
1158             });
1159 
1160             out << ");\n\n";
1161         }
1162     }
1163 
1164     generateCppInstrumentationCall(
1165             out,
1166             InstrumentationEvent::CLIENT_API_EXIT,
1167             method,
1168             superInterface);
1169 
1170     if (hasCallback) {
1171         out.unindent();
1172         out << "});\n";
1173         out << "if (_hidl_transact_err != ::android::OK) ";
1174         out.block([&] {
1175             out << "_hidl_err = _hidl_transact_err;\n";
1176             out << "goto _hidl_error;\n";
1177         }).endl().endl();
1178         out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n";
1179     }
1180 
1181     if (elidedReturn != nullptr) {
1182         out << "return ::android::hardware::Return<";
1183         out << elidedReturn->type().getCppResultType()
1184             << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1185     } else {
1186         out << "return ::android::hardware::Return<void>();\n\n";
1187     }
1188 
1189     out.unindent();
1190     out << "_hidl_error:\n";
1191     out.indent();
1192     out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1193     out << "return ::android::hardware::Return<";
1194     if (elidedReturn != nullptr) {
1195         out << method->results().at(0)->type().getCppResultType();
1196     } else {
1197         out << "void";
1198     }
1199     out << ">(_hidl_status);\n";
1200 
1201     out.unindent();
1202     out << "}\n\n";
1203 }
1204 
1205 void AST::generateProxySource(Formatter& out, const FQName& fqName) const {
1206     const std::string klassName = fqName.getInterfaceProxyName();
1207 
1208     out << klassName
1209         << "::"
1210         << klassName
1211         << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
1212 
1213     out.indent();
1214     out.indent();
1215 
1216     out << ": BpInterface"
1217         << "<"
1218         << fqName.getInterfaceName()
1219         << ">(_hidl_impl),\n"
1220         << "  ::android::hardware::details::HidlInstrumentor(\""
1221         << mPackage.string()
1222         << "\", \""
1223         << fqName.getInterfaceName()
1224         << "\") {\n";
1225 
1226     out.unindent();
1227     out.unindent();
1228     out << "}\n\n";
1229 
1230     out << "void " << klassName << "::onLastStrongRef(const void* id) ";
1231     out.block([&] {
1232         out.block([&] {
1233             // if unlinkToDeath is not used, remove strong cycle between
1234             // this and hidl_binder_death_recipient
1235             out << "std::unique_lock<std::mutex> lock(_hidl_mMutex);\n";
1236             out << "_hidl_mDeathRecipients.clear();\n";
1237         }).endl().endl();
1238 
1239         out << "BpInterface<" << fqName.getInterfaceName() << ">::onLastStrongRef(id);\n";
1240     }).endl();
1241 
1242     generateMethods(out,
1243                     [&](const Method* method, const Interface* superInterface) {
1244                         generateStaticProxyMethodSource(out, klassName, method, superInterface);
1245                     },
1246                     false /* include parents */);
1247 
1248     generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1249         generateProxyMethodSource(out, klassName, method, superInterface);
1250     });
1251 }
1252 
1253 void AST::generateStubSource(Formatter& out, const Interface* iface) const {
1254     const std::string interfaceName = iface->definedName();
1255     const std::string klassName = iface->getStubName();
1256 
1257     out << klassName
1258         << "::"
1259         << klassName
1260         << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
1261 
1262     out.indent();
1263     out.indent();
1264 
1265     if (iface->isIBase()) {
1266         out << ": ::android::hardware::details::HidlInstrumentor(\"";
1267     } else {
1268         out << ": "
1269             << gIBaseFqName.getInterfaceStubFqName().cppName()
1270             << "(_hidl_impl, \"";
1271     }
1272 
1273     out << mPackage.string()
1274         << "\", \""
1275         << interfaceName
1276         << "\") { \n";
1277     out.indent();
1278     out << "_hidl_mImpl = _hidl_impl;\n";
1279     out << "auto prio = ::android::hardware::getMinSchedulerPolicy(_hidl_impl);\n";
1280     out << "mSchedPolicy = prio.sched_policy;\n";
1281     out << "mSchedPriority = prio.prio;\n";
1282     out << "setRequestingSid(::android::hardware::getRequestingSid(_hidl_impl));\n";
1283     out.unindent();
1284 
1285     out.unindent();
1286     out.unindent();
1287     out << "}\n\n";
1288 
1289     if (iface->isIBase()) {
1290         // BnHwBase has a constructor to initialize the HidlInstrumentor
1291         // class properly.
1292         out << klassName
1293             << "::"
1294             << klassName
1295             << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1296             << " const std::string &HidlInstrumentor_package,"
1297             << " const std::string &HidlInstrumentor_interface)\n";
1298 
1299         out.indent();
1300         out.indent();
1301 
1302         out << ": ::android::hardware::details::HidlInstrumentor("
1303             << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
1304         out.indent();
1305         out << "_hidl_mImpl = _hidl_impl;\n";
1306         out.unindent();
1307 
1308         out.unindent();
1309         out.unindent();
1310         out << "}\n\n";
1311     }
1312 
1313     out << klassName << "::~" << klassName << "() ";
1314     out.block([&]() {
1315            out << "::android::hardware::details::gBnMap->eraseIfEqual(_hidl_mImpl.get(), this);\n";
1316        })
1317             .endl()
1318             .endl();
1319 
1320     if (isIBase()) {
1321         out << "bool " << klassName << "::checkSubclass(const void* subclassID) const ";
1322         out.block([&] { out << "return subclassID == " << interfaceName << "::descriptor;\n"; });
1323     }
1324 
1325     generateMethods(out,
1326                     [&](const Method* method, const Interface* superInterface) {
1327                         return generateStaticStubMethodSource(out, iface->fqName(), method, superInterface);
1328                     },
1329                     false /* include parents */);
1330 
1331     generateMethods(out, [&](const Method* method, const Interface*) {
1332         if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1333             return;
1334         }
1335         method->generateCppSignature(out, iface->getStubName());
1336         out << " ";
1337         out.block([&] {
1338             method->cppImpl(IMPL_STUB_IMPL, out);
1339         }).endl();
1340     });
1341 
1342     out << "::android::status_t " << klassName << "::onTransact(\n";
1343 
1344     out.indent();
1345     out.indent();
1346 
1347     out << "uint32_t _hidl_code,\n"
1348         << "const ::android::hardware::Parcel &_hidl_data,\n"
1349         << "::android::hardware::Parcel *_hidl_reply,\n"
1350         << "uint32_t _hidl_flags,\n"
1351         << "TransactCallback _hidl_cb) {\n";
1352 
1353     out.unindent();
1354 
1355     out << "::android::status_t _hidl_err = ::android::OK;\n\n";
1356     out << "switch (_hidl_code) {\n";
1357     out.indent();
1358 
1359     for (const auto &tuple : iface->allMethodsFromRoot()) {
1360         const Method *method = tuple.method();
1361         const Interface *superInterface = tuple.interface();
1362 
1363         if (!isIBase() && method->isHidlReserved()) {
1364             continue;
1365         }
1366         out << "case "
1367             << method->getSerialId()
1368             << " /* "
1369             << method->name()
1370             << " */:\n{\n";
1371 
1372         out.indent();
1373 
1374         generateStubSourceForMethod(out, method, superInterface);
1375 
1376         out.unindent();
1377         out << "}\n\n";
1378     }
1379 
1380     out << "default:\n{\n";
1381     out.indent();
1382 
1383     if (iface->isIBase()) {
1384         out << "(void)_hidl_flags;\n";
1385         out << "return ::android::UNKNOWN_TRANSACTION;\n";
1386     } else {
1387         out << "return ";
1388         out << gIBaseFqName.getInterfaceStubFqName().cppName();
1389         out << "::onTransact(\n";
1390 
1391         out.indent();
1392         out.indent();
1393 
1394         out << "_hidl_code, _hidl_data, _hidl_reply, "
1395             << "_hidl_flags, _hidl_cb);\n";
1396 
1397         out.unindent();
1398         out.unindent();
1399     }
1400 
1401     out.unindent();
1402     out << "}\n";
1403 
1404     out.unindent();
1405     out << "}\n\n";
1406 
1407     out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1408         out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1409         out.indent(2, [&] {
1410             out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1411             out << "_hidl_reply);\n";
1412         });
1413     });
1414 
1415     out << "return _hidl_err;\n";
1416 
1417     out.unindent();
1418     out << "}\n\n";
1419 }
1420 
1421 void AST::generateStubSourceForMethod(Formatter& out, const Method* method,
1422                                       const Interface* superInterface) const {
1423     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1424         method->cppImpl(IMPL_STUB, out);
1425         out << "break;\n";
1426         return;
1427     }
1428 
1429     out << "_hidl_err = "
1430         << superInterface->fqName().cppNamespace()
1431         << "::"
1432         << superInterface->getStubName()
1433         << "::_hidl_"
1434         << method->name()
1435         << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
1436     out << "break;\n";
1437 }
1438 
1439 void AST::generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
1440                                          const Method* method, const Interface* superInterface) const {
1441     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1442         return;
1443     }
1444 
1445     const std::string& klassName = fqName.getInterfaceStubName();
1446 
1447     out << "::android::status_t " << klassName << "::_hidl_" << method->name() << "(\n";
1448 
1449     out.indent();
1450     out.indent();
1451 
1452     out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
1453         << "const ::android::hardware::Parcel &_hidl_data,\n"
1454         << "::android::hardware::Parcel *_hidl_reply,\n"
1455         << "TransactCallback _hidl_cb) {\n";
1456 
1457     out.unindent();
1458 
1459     out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1460     out << "bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();\n";
1461     out << "const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();\n";
1462     out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1463 
1464     out << "::android::status_t _hidl_err = ::android::OK;\n";
1465 
1466     out << "if (!_hidl_data.enforceInterface("
1467         << klassName
1468         << "::Pure::descriptor)) {\n";
1469 
1470     out.indent();
1471     out << "_hidl_err = ::android::BAD_TYPE;\n";
1472     out << "return _hidl_err;\n";
1473     out.unindent();
1474     out << "}\n\n";
1475 
1476     declareCppReaderLocals(out, method->args(), false /* forResults */);
1477 
1478     for (const auto &arg : method->args()) {
1479         emitCppReaderWriter(
1480                 out,
1481                 "_hidl_data",
1482                 false /* parcelObjIsPointer */,
1483                 arg,
1484                 true /* reader */,
1485                 Type::ErrorMode_Return,
1486                 false /* addPrefixToName */);
1487     }
1488 
1489     generateCppInstrumentationCall(
1490             out,
1491             InstrumentationEvent::SERVER_API_ENTRY,
1492             method,
1493             superInterface);
1494 
1495     const bool returnsValue = !method->results().empty();
1496     const NamedReference<Type>* elidedReturn = method->canElideCallback();
1497 
1498     std::string callee;
1499 
1500     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL)) {
1501         callee = "_hidl_this";
1502     } else {
1503         callee = "static_cast<" + fqName.getInterfaceName() + "*>(_hidl_this->getImpl().get())";
1504     }
1505 
1506     if (elidedReturn != nullptr) {
1507         out << elidedReturn->type().getCppResultType()
1508             << " _hidl_out_"
1509             << elidedReturn->name()
1510             << " = "
1511             << callee << "->" << method->name()
1512             << "(";
1513 
1514         out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
1515             if (arg->type().resultNeedsDeref()) {
1516                 out << "*";
1517             }
1518             out << arg->name();
1519         });
1520 
1521         out << ");\n\n";
1522 
1523         out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1524             << "_hidl_reply);\n\n";
1525 
1526         elidedReturn->type().emitReaderWriter(
1527                 out,
1528                 "_hidl_out_" + elidedReturn->name(),
1529                 "_hidl_reply",
1530                 true, /* parcelObjIsPointer */
1531                 false, /* isReader */
1532                 Type::ErrorMode_Goto);
1533 
1534         out.unindent();
1535         out << "_hidl_error:\n";
1536         out.indent();
1537 
1538         generateCppInstrumentationCall(
1539                 out,
1540                 InstrumentationEvent::SERVER_API_EXIT,
1541                 method,
1542             superInterface);
1543 
1544         out << "if (_hidl_err != ::android::OK) { return _hidl_err; }\n";
1545         out << "_hidl_cb(*_hidl_reply);\n";
1546     } else {
1547         if (returnsValue) {
1548             out << "bool _hidl_callbackCalled = false;\n\n";
1549         }
1550 
1551         out << "::android::hardware::Return<void> _hidl_ret = " << callee << "->" << method->name()
1552             << "(";
1553 
1554         out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
1555             if (arg->type().resultNeedsDeref()) {
1556                 out << "*";
1557             }
1558 
1559             out << arg->name();
1560         });
1561 
1562         if (returnsValue) {
1563             if (!method->args().empty()) {
1564                 out << ", ";
1565             }
1566 
1567             out << "[&](";
1568 
1569             out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
1570                 out << "const auto &_hidl_out_" << arg->name();
1571             });
1572 
1573             out << ") {\n";
1574             out.indent();
1575             out << "if (_hidl_callbackCalled) {\n";
1576             out.indent();
1577             out << "LOG_ALWAYS_FATAL(\""
1578                 << method->name()
1579                 << ": _hidl_cb called a second time, but must be called once.\");\n";
1580             out.unindent();
1581             out << "}\n";
1582             out << "_hidl_callbackCalled = true;\n\n";
1583 
1584             out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1585                 << "_hidl_reply);\n\n";
1586 
1587             for (const auto &arg : method->results()) {
1588                 emitCppReaderWriter(
1589                         out,
1590                         "_hidl_reply",
1591                         true /* parcelObjIsPointer */,
1592                         arg,
1593                         false /* reader */,
1594                         Type::ErrorMode_Goto,
1595                         true /* addPrefixToName */);
1596             }
1597 
1598             if (!method->results().empty()) {
1599                 out.unindent();
1600                 out << "_hidl_error:\n";
1601                 out.indent();
1602             }
1603 
1604             generateCppInstrumentationCall(
1605                     out,
1606                     InstrumentationEvent::SERVER_API_EXIT,
1607                     method,
1608                     superInterface);
1609 
1610             out << "if (_hidl_err != ::android::OK) { return; }\n";
1611             out << "_hidl_cb(*_hidl_reply);\n";
1612 
1613             out.unindent();
1614             out << "});\n\n";
1615         } else {
1616             out << ");\n\n";
1617             out << "(void) _hidl_cb;\n\n";
1618             generateCppInstrumentationCall(
1619                     out,
1620                     InstrumentationEvent::SERVER_API_EXIT,
1621                     method,
1622                     superInterface);
1623         }
1624 
1625         out << "_hidl_ret.assertOk();\n";
1626 
1627         if (returnsValue) {
1628             out << "if (!_hidl_callbackCalled) {\n";
1629             out.indent();
1630             out << "LOG_ALWAYS_FATAL(\""
1631                 << method->name()
1632                 << ": _hidl_cb not called, but must be called once.\");\n";
1633             out.unindent();
1634             out << "}\n\n";
1635         } else {
1636             out << "::android::hardware::writeToParcel("
1637                 << "::android::hardware::Status::ok(), "
1638                 << "_hidl_reply);\n\n";
1639         }
1640     }
1641 
1642     out << "return _hidl_err;\n";
1643     out.unindent();
1644     out << "}\n\n";
1645 }
1646 
1647 void AST::generatePassthroughHeader(Formatter& out) const {
1648     if (!AST::isInterface()) {
1649         // types.hal does not get a stub header.
1650         return;
1651     }
1652 
1653     const Interface* iface = mRootScope.getInterface();
1654     CHECK(iface != nullptr);
1655 
1656     const std::string klassName = iface->getPassthroughName();
1657 
1658     const std::string guard = makeHeaderGuard(klassName);
1659 
1660     out << "#ifndef " << guard << "\n";
1661     out << "#define " << guard << "\n\n";
1662 
1663     out << "#include <android-base/macros.h>\n";
1664     out << "#include <cutils/trace.h>\n";
1665     out << "#include <future>\n";
1666 
1667     generateCppPackageInclude(out, mPackage, iface->definedName());
1668     out << "\n";
1669 
1670     out << "#include <hidl/HidlPassthroughSupport.h>\n";
1671     out << "#include <hidl/TaskRunner.h>\n";
1672 
1673     enterLeaveNamespace(out, true /* enter */);
1674     out << "\n";
1675 
1676     out << "struct " << klassName << " : " << iface->definedName()
1677         << ", ::android::hardware::details::HidlInstrumentor {\n";
1678 
1679     out.indent();
1680     out << "explicit " << klassName << "(const ::android::sp<" << iface->definedName()
1681         << "> impl);\n";
1682 
1683     out.endl();
1684     generateTemplatizationLink(out);
1685     generateCppTag(out, "::android::hardware::details::bs_tag");
1686 
1687     generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1688         generatePassthroughMethod(out, method, superInterface);
1689     });
1690 
1691     out.unindent();
1692     out << "private:\n";
1693     out.indent();
1694     out << "const ::android::sp<" << iface->definedName() << "> mImpl;\n";
1695 
1696     out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
1697 
1698     out << "\n";
1699 
1700     out << "::android::hardware::Return<void> addOnewayTask("
1701            "std::function<void(void)>);\n\n";
1702 
1703     out.unindent();
1704 
1705     out << "};\n\n";
1706 
1707     enterLeaveNamespace(out, false /* enter */);
1708 
1709     out << "\n#endif  // " << guard << "\n";
1710 }
1711 
1712 void AST::generateInterfaceSource(Formatter& out) const {
1713     const Interface* iface = mRootScope.getInterface();
1714 
1715     // generate castFrom functions
1716     std::string childTypeResult = iface->getCppResultType();
1717 
1718     generateMethods(out, [&](const Method* method, const Interface*) {
1719         bool reserved = method->isHidlReserved();
1720 
1721         if (!reserved) {
1722             out << "// no default implementation for: ";
1723         }
1724         method->generateCppSignature(out, iface->definedName());
1725         if (reserved) {
1726             out.block([&]() {
1727                 method->cppImpl(IMPL_INTERFACE, out);
1728             }).endl();
1729         }
1730 
1731         out << "\n";
1732 
1733         return;
1734     });
1735 
1736     for (const Interface *superType : iface->typeChain()) {
1737         out << "::android::hardware::Return<" << childTypeResult << "> " << iface->definedName()
1738             << "::castFrom(" << superType->getCppArgumentType() << " parent, bool "
1739             << (iface == superType ? "/* emitError */" : "emitError") << ") {\n";
1740         out.indent();
1741         if (iface == superType) {
1742             out << "return parent;\n";
1743         } else {
1744             out << "return ::android::hardware::details::castInterface<";
1745             out << iface->definedName() << ", " << superType->fqName().cppName() << ", "
1746                 << iface->getProxyName() << ">(\n";
1747             out.indent();
1748             out.indent();
1749             out << "parent, \""
1750                 << iface->fqName().string()
1751                 << "\", emitError);\n";
1752             out.unindent();
1753             out.unindent();
1754         }
1755         out.unindent();
1756         out << "}\n\n";
1757     }
1758 }
1759 
1760 void AST::generatePassthroughSource(Formatter& out) const {
1761     const Interface* iface = mRootScope.getInterface();
1762 
1763     const std::string klassName = iface->getPassthroughName();
1764 
1765     out << klassName << "::" << klassName << "(const ::android::sp<" << iface->fullName()
1766         << "> impl) : ::android::hardware::details::HidlInstrumentor(\"" << mPackage.string()
1767         << "\", \"" << iface->definedName() << "\"), mImpl(impl) {\n";
1768 
1769     out.indent([&] { out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n"; });
1770 
1771     out << "}\n\n";
1772 
1773     out << "::android::hardware::Return<void> " << klassName
1774         << "::addOnewayTask(std::function<void(void)> fun) {\n";
1775     out.indent();
1776     out << "if (!mOnewayQueue.push(fun)) {\n";
1777     out.indent();
1778     out << "return ::android::hardware::Status::fromExceptionCode(\n";
1779     out.indent();
1780     out.indent();
1781     out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
1782         << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
1783     out.unindent();
1784     out.unindent();
1785     out.unindent();
1786     out << "}\n";
1787 
1788     out << "return ::android::hardware::Status();\n";
1789 
1790     out.unindent();
1791     out << "}\n\n";
1792 }
1793 
1794 void AST::generateCppAtraceCall(Formatter &out,
1795                                     InstrumentationEvent event,
1796                                     const Method *method) const {
1797     const Interface* iface = mRootScope.getInterface();
1798     std::string baseString = "HIDL::" + iface->definedName() + "::" + method->name();
1799     switch (event) {
1800         case SERVER_API_ENTRY:
1801         {
1802             out << "atrace_begin(ATRACE_TAG_HAL, \""
1803                 << baseString + "::server\");\n";
1804             break;
1805         }
1806         case PASSTHROUGH_ENTRY:
1807         {
1808             out << "atrace_begin(ATRACE_TAG_HAL, \""
1809                 << baseString + "::passthrough\");\n";
1810             break;
1811         }
1812         case SERVER_API_EXIT:
1813         case PASSTHROUGH_EXIT:
1814         {
1815             out << "atrace_end(ATRACE_TAG_HAL);\n";
1816             break;
1817         }
1818         // client uses scope because of gotos
1819         // this isn't done for server because the profiled code isn't alone in its scope
1820         // this isn't done for passthrough becuase the profiled boundary isn't even in the same code
1821         case CLIENT_API_ENTRY: {
1822             out << "::android::ScopedTrace PASTE(___tracer, __LINE__) (ATRACE_TAG_HAL, \""
1823                 << baseString + "::client\");\n";
1824             break;
1825         }
1826         case CLIENT_API_EXIT:
1827             break;
1828         default:
1829         {
1830             CHECK(false) << "Unsupported instrumentation event: " << event;
1831         }
1832     }
1833 }
1834 
1835 void AST::generateCppInstrumentationCall(
1836         Formatter &out,
1837         InstrumentationEvent event,
1838         const Method *method,
1839         const Interface* superInterface) const {
1840     generateCppAtraceCall(out, event, method);
1841 
1842     out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1843     out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1844     out.indent();
1845     out << "std::vector<void *> _hidl_args;\n";
1846     std::string event_str = "";
1847     switch (event) {
1848         case SERVER_API_ENTRY:
1849         {
1850             event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1851             for (const auto &arg : method->args()) {
1852                 out << "_hidl_args.push_back((void *)"
1853                     << (arg->type().resultNeedsDeref() ? "" : "&")
1854                     << arg->name()
1855                     << ");\n";
1856             }
1857             break;
1858         }
1859         case SERVER_API_EXIT:
1860         {
1861             event_str = "InstrumentationEvent::SERVER_API_EXIT";
1862             for (const auto &arg : method->results()) {
1863                 out << "_hidl_args.push_back((void *)&_hidl_out_"
1864                     << arg->name()
1865                     << ");\n";
1866             }
1867             break;
1868         }
1869         case CLIENT_API_ENTRY:
1870         {
1871             event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1872             for (const auto &arg : method->args()) {
1873                 out << "_hidl_args.push_back((void *)&"
1874                     << arg->name()
1875                     << ");\n";
1876             }
1877             break;
1878         }
1879         case CLIENT_API_EXIT:
1880         {
1881             event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1882             for (const auto &arg : method->results()) {
1883                 out << "_hidl_args.push_back((void *)"
1884                     << (arg->type().resultNeedsDeref() ? "" : "&")
1885                     << "_hidl_out_"
1886                     << arg->name()
1887                     << ");\n";
1888             }
1889             break;
1890         }
1891         case PASSTHROUGH_ENTRY:
1892         {
1893             event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1894             for (const auto &arg : method->args()) {
1895                 out << "_hidl_args.push_back((void *)&"
1896                     << arg->name()
1897                     << ");\n";
1898             }
1899             break;
1900         }
1901         case PASSTHROUGH_EXIT:
1902         {
1903             event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
1904             for (const auto &arg : method->results()) {
1905                 out << "_hidl_args.push_back((void *)&_hidl_out_"
1906                     << arg->name()
1907                     << ");\n";
1908             }
1909             break;
1910         }
1911         default:
1912         {
1913             CHECK(false) << "Unsupported instrumentation event: " << event;
1914         }
1915     }
1916 
1917     out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
1918     out.indent();
1919     out << "callback(" << event_str << ", \"" << superInterface->fqName().package() << "\", \""
1920         << superInterface->fqName().version() << "\", \"" << superInterface->definedName()
1921         << "\", \"" << method->name() << "\", &_hidl_args);\n";
1922     out.unindent();
1923     out << "}\n";
1924     out.unindent();
1925     out << "}\n";
1926     out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1927 }
1928 
1929 }  // namespace android
1930