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 
makeHeaderGuard(const std::string & baseName,bool indicateGenerated) const38 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 
generateCppPackageInclude(Formatter & out,const FQName & package,const std::string & klass)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 
enterLeaveNamespace(Formatter & out,bool enter) const72 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 
declareGetService(Formatter & out,const std::string & interfaceName,bool isTry)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 
declareServiceManagerInteractions(Formatter & out,const std::string & interfaceName)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 
implementGetService(Formatter & out,const FQName & fqName,bool isTry)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 
implementServiceManagerInteractions(Formatter & out,const FQName & fqName,const std::string & package)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 
generateInterfaceHeader(Formatter & out) const218 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 
generateHwBinderHeader(Formatter & out) const392 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 
wrapPassthroughArg(Formatter & out,const NamedReference<Type> * arg,std::string name,std::function<void (void)> handleError)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 
generatePassthroughMethod(Formatter & out,const Method * method,const Interface * superInterface) const458 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 
generateMethods(Formatter & out,const MethodGenerator & gen,bool includeParent) const599 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 
generateTemplatizationLink(Formatter & out) const626 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 
generateCppTag(Formatter & out,const std::string & tag) const631 void AST::generateCppTag(Formatter& out, const std::string& tag) const {
632     out << "typedef " << tag << " _hidl_tag;\n\n";
633 }
634 
generateStubHeader(Formatter & out) const635 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     generateMethods(out,
694                     [&](const Method* method, const Interface*) {
695                         if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
696                             return;
697                         }
698 
699                         out << "static ::android::status_t _hidl_" << method->name() << "(\n";
700 
701                         out.indent(2,
702                                    [&] {
703                                        out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
704                                            << "const ::android::hardware::Parcel &_hidl_data,\n"
705                                            << "::android::hardware::Parcel *_hidl_reply,\n"
706                                            << "TransactCallback _hidl_cb);\n";
707                                    })
708                             .endl()
709                             .endl();
710                     },
711                     false /* include parents */);
712 
713     out.unindent();
714     out << "private:\n";
715     out.indent();
716 
717     generateMethods(out, [&](const Method* method, const Interface* iface) {
718         if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
719             return;
720         }
721         const bool returnsValue = !method->results().empty();
722         const NamedReference<Type>* elidedReturn = method->canElideCallback();
723 
724         if (elidedReturn == nullptr && returnsValue) {
725             out << "using " << method->name() << "_cb = "
726                 << iface->fqName().cppName()
727                 << "::" << method->name() << "_cb;\n";
728         }
729         method->generateCppSignature(out);
730         out << ";\n";
731     });
732 
733     out << "::android::sp<" << iface->definedName() << "> _hidl_mImpl;\n";
734     out.unindent();
735     out << "};\n\n";
736 
737     enterLeaveNamespace(out, false /* enter */);
738 
739     out << "\n#endif  // " << guard << "\n";
740 }
741 
generateProxyHeader(Formatter & out) const742 void AST::generateProxyHeader(Formatter& out) const {
743     if (!AST::isInterface()) {
744         // types.hal does not get a proxy header.
745         return;
746     }
747 
748     const Interface* iface = mRootScope.getInterface();
749     const std::string proxyName = iface->getProxyName();
750     const std::string guard = makeHeaderGuard(proxyName);
751 
752     out << "#ifndef " << guard << "\n";
753     out << "#define " << guard << "\n\n";
754 
755     out << "#include <hidl/HidlTransportSupport.h>\n\n";
756 
757     generateCppPackageInclude(out, mPackage, iface->getHwName());
758     out << "\n";
759 
760     enterLeaveNamespace(out, true /* enter */);
761     out << "\n";
762 
763     out << "struct " << proxyName << " : public ::android::hardware::BpInterface<"
764         << iface->definedName() << ">, public ::android::hardware::details::HidlInstrumentor {\n";
765 
766     out.indent();
767 
768     out << "explicit "
769         << proxyName
770         << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
771         << "\n\n";
772 
773     generateTemplatizationLink(out);
774     DocComment("Type tag for use in template logic that indicates this is a 'proxy' class.",
775                HIDL_LOCATION_HERE)
776             .emit(out);
777     generateCppTag(out, "::android::hardware::details::bphw_tag");
778 
779     out << "virtual bool isRemote() const override { return true; }\n\n";
780 
781     out << "void onLastStrongRef(const void* id) override;\n\n";
782 
783     generateMethods(
784         out,
785         [&](const Method* method, const Interface*) {
786             if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
787                 return;
788             }
789 
790             out << "static ";
791             method->generateCppReturnType(out);
792             out << " _hidl_" << method->name() << "("
793                 << "::android::hardware::IInterface* _hidl_this, "
794                 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
795 
796             if (!method->hasEmptyCppArgSignature()) {
797                 out << ", ";
798             }
799             method->emitCppArgSignature(out);
800             out << ");\n";
801         },
802         false /* include parents */);
803 
804     generateMethods(out, [&](const Method* method, const Interface*) {
805         method->generateCppSignature(out);
806         out << " override;\n";
807     });
808 
809     out.unindent();
810     out << "private:\n";
811     out.indent();
812     out << "std::mutex _hidl_mMutex;\n"
813         << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
814         << " _hidl_mDeathRecipients;\n";
815     out.unindent();
816     out << "};\n\n";
817 
818     enterLeaveNamespace(out, false /* enter */);
819 
820     out << "\n#endif  // " << guard << "\n";
821 }
822 
generateCppSource(Formatter & out) const823 void AST::generateCppSource(Formatter& out) const {
824     std::string baseName = getBaseName();
825     const Interface *iface = getInterface();
826 
827     const std::string klassName = baseName + (baseName == "types" ? "" : "All");
828 
829     out << "#define LOG_TAG \""
830         << mPackage.string() << "::" << baseName
831         << "\"\n\n";
832 
833     out << "#include <log/log.h>\n";
834     out << "#include <cutils/trace.h>\n";
835     out << "#include <hidl/HidlTransportSupport.h>\n\n";
836     out << "#include <hidl/Static.h>\n";
837     out << "#include <hwbinder/ProcessState.h>\n";
838     out << "#include <utils/Trace.h>\n";
839     if (iface) {
840         // This is a no-op for IServiceManager itself.
841         out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
842 
843         generateCppPackageInclude(out, mPackage, iface->getProxyName());
844         generateCppPackageInclude(out, mPackage, iface->getStubName());
845         generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
846 
847         for (const Interface *superType : iface->superTypeChain()) {
848             generateCppPackageInclude(out,
849                                       superType->fqName(),
850                                       superType->fqName().getInterfaceProxyName());
851         }
852 
853         out << "#include <hidl/ServiceManagement.h>\n";
854     } else {
855         generateCppPackageInclude(out, mPackage, "types");
856         generateCppPackageInclude(out, mPackage, "hwtypes");
857     }
858 
859     out << "\n";
860 
861     enterLeaveNamespace(out, true /* enter */);
862     out << "\n";
863 
864     generateTypeSource(out, iface ? iface->definedName() : "");
865 
866     if (iface) {
867         const Interface* iface = mRootScope.getInterface();
868 
869         // need to be put here, generateStubSource is using this.
870         out << "const char* " << iface->definedName() << "::descriptor(\""
871             << iface->fqName().string() << "\");\n\n";
872         out << "__attribute__((constructor)) ";
873         out << "static void static_constructor() {\n";
874         out.indent([&] {
875             out << "::android::hardware::details::getBnConstructorMap().set("
876                 << iface->definedName() << "::descriptor,\n";
877             out.indent(2, [&] {
878                 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
879                 out.indent([&] {
880                     out << "return new " << iface->getStubName() << "(static_cast<"
881                         << iface->definedName() << " *>(iIntf));\n";
882                 });
883                 out << "});\n";
884             });
885             out << "::android::hardware::details::getBsConstructorMap().set("
886                 << iface->definedName() << "::descriptor,\n";
887             out.indent(2, [&] {
888                 out << "[](void *iIntf) -> ::android::sp<"
889                     << gIBaseFqName.cppName()
890                     << "> {\n";
891                 out.indent([&] {
892                     out << "return new " << iface->getPassthroughName() << "(static_cast<"
893                         << iface->definedName() << " *>(iIntf));\n";
894                 });
895                 out << "});\n";
896             });
897         });
898         out << "}\n\n";
899         out << "__attribute__((destructor))";
900         out << "static void static_destructor() {\n";
901         out.indent([&] {
902             out << "::android::hardware::details::getBnConstructorMap().erase("
903                 << iface->definedName() << "::descriptor);\n";
904             out << "::android::hardware::details::getBsConstructorMap().erase("
905                 << iface->definedName() << "::descriptor);\n";
906         });
907         out << "}\n\n";
908 
909         generateInterfaceSource(out);
910         generateProxySource(out, iface->fqName());
911         generateStubSource(out, iface);
912         generatePassthroughSource(out);
913 
914         if (isIBase()) {
915             out << "// skipped getService, registerAsService, registerForNotifications\n";
916         } else {
917             std::string package = iface->fqName().package()
918                     + iface->fqName().atVersion();
919 
920             implementServiceManagerInteractions(out, iface->fqName(), package);
921         }
922     }
923 
924     HidlTypeAssertion::EmitAll(out);
925     out << "\n";
926 
927     enterLeaveNamespace(out, false /* enter */);
928 }
929 
generateTypeSource(Formatter & out,const std::string & ifaceName) const930 void AST::generateTypeSource(Formatter& out, const std::string& ifaceName) const {
931     mRootScope.emitTypeDefinitions(out, ifaceName);
932 }
933 
declareCppReaderLocals(Formatter & out,const std::vector<NamedReference<Type> * > & args,bool forResults) const934 void AST::declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& args,
935                                  bool forResults) const {
936     if (args.empty()) {
937         return;
938     }
939 
940     for (const auto &arg : args) {
941         const Type &type = arg->type();
942 
943         out << type.getCppResultType()
944             << " "
945             << (forResults ? "_hidl_out_" : "") + arg->name()
946             << ";\n";
947     }
948 
949     out << "\n";
950 }
951 
emitCppReaderWriter(Formatter & out,const std::string & parcelObj,bool parcelObjIsPointer,const NamedReference<Type> * arg,bool isReader,Type::ErrorMode mode,bool addPrefixToName) const952 void AST::emitCppReaderWriter(Formatter& out, const std::string& parcelObj, bool parcelObjIsPointer,
953                               const NamedReference<Type>* arg, bool isReader, Type::ErrorMode mode,
954                               bool addPrefixToName) const {
955     const Type &type = arg->type();
956 
957     type.emitReaderWriter(
958             out,
959             addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
960             parcelObj,
961             parcelObjIsPointer,
962             isReader,
963             mode);
964 }
965 
generateProxyMethodSource(Formatter & out,const std::string & klassName,const Method * method,const Interface * superInterface) const966 void AST::generateProxyMethodSource(Formatter& out, const std::string& klassName,
967                                     const Method* method, const Interface* superInterface) const {
968     method->generateCppSignature(out,
969                                  klassName,
970                                  true /* specify namespaces */);
971 
972     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
973         out.block([&] {
974             method->cppImpl(IMPL_PROXY, out);
975         }).endl().endl();
976         return;
977     }
978 
979     out.block([&] {
980         const bool returnsValue = !method->results().empty();
981         const NamedReference<Type>* elidedReturn = method->canElideCallback();
982 
983         method->generateCppReturnType(out);
984 
985         out << " _hidl_out = "
986             << superInterface->fqName().cppNamespace()
987             << "::"
988             << superInterface->getProxyName()
989             << "::_hidl_"
990             << method->name()
991             << "(this, this";
992 
993         if (!method->hasEmptyCppArgSignature()) {
994             out << ", ";
995         }
996 
997         out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
998             out << arg->name();
999         });
1000 
1001         if (returnsValue && elidedReturn == nullptr) {
1002             if (!method->args().empty()) {
1003                 out << ", ";
1004             }
1005             out << "_hidl_cb";
1006         }
1007 
1008         out << ");\n\n";
1009 
1010         out << "return _hidl_out;\n";
1011     }).endl().endl();
1012 }
1013 
generateStaticProxyMethodSource(Formatter & out,const std::string & klassName,const Method * method,const Interface * superInterface) const1014 void AST::generateStaticProxyMethodSource(Formatter& out, const std::string& klassName,
1015                                           const Method* method, const Interface* superInterface) const {
1016     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1017         return;
1018     }
1019 
1020     method->generateCppReturnType(out);
1021 
1022     out << klassName
1023         << "::_hidl_"
1024         << method->name()
1025         << "("
1026         << "::android::hardware::IInterface *_hidl_this, "
1027         << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
1028 
1029     if (!method->hasEmptyCppArgSignature()) {
1030         out << ", ";
1031     }
1032 
1033     method->emitCppArgSignature(out);
1034     out << ") {\n";
1035 
1036     out.indent();
1037 
1038     out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1039     out << "bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();\n";
1040     out << "const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();\n";
1041     out << "#else\n";
1042     out << "(void) _hidl_this_instrumentor;\n";
1043     out << "#endif // __ANDROID_DEBUGGABLE__\n";
1044 
1045     const bool returnsValue = !method->results().empty();
1046     const NamedReference<Type>* elidedReturn = method->canElideCallback();
1047     const bool hasCallback = returnsValue && elidedReturn == nullptr;
1048 
1049     generateCppInstrumentationCall(
1050             out,
1051             InstrumentationEvent::CLIENT_API_ENTRY,
1052             method,
1053             superInterface);
1054 
1055     out << "::android::hardware::Parcel _hidl_data;\n";
1056     out << "::android::hardware::Parcel _hidl_reply;\n";
1057     out << "::android::status_t _hidl_err;\n";
1058     out << "::android::status_t _hidl_transact_err;\n";
1059     out << "::android::hardware::Status _hidl_status;\n\n";
1060 
1061     if (!hasCallback) {
1062         declareCppReaderLocals(
1063                 out, method->results(), true /* forResults */);
1064     }
1065 
1066     out << "_hidl_err = _hidl_data.writeInterfaceToken(";
1067     out << klassName;
1068     out << "::descriptor);\n";
1069     out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1070 
1071     bool hasInterfaceArgument = false;
1072 
1073     for (const auto &arg : method->args()) {
1074         if (arg->type().isInterface()) {
1075             hasInterfaceArgument = true;
1076         }
1077         emitCppReaderWriter(
1078                 out,
1079                 "_hidl_data",
1080                 false /* parcelObjIsPointer */,
1081                 arg,
1082                 false /* reader */,
1083                 Type::ErrorMode_Goto,
1084                 false /* addPrefixToName */);
1085     }
1086 
1087     if (hasInterfaceArgument) {
1088         // Start binder threadpool to handle incoming transactions
1089         out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1090     }
1091     out << "_hidl_transact_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact("
1092         << method->getSerialId()
1093         << " /* "
1094         << method->name()
1095         << " */, _hidl_data, &_hidl_reply";
1096 
1097     if (method->isOneway()) {
1098         out << ", " << Interface::FLAG_ONE_WAY->cppValue();
1099     } else {
1100         out << ", 0";
1101     }
1102 
1103     if (hasCallback) {
1104         out << ", [&] (::android::hardware::Parcel& _hidl_reply) {\n";
1105         out.indent();
1106         declareCppReaderLocals(
1107                 out, method->results(), true /* forResults */);
1108         out.endl();
1109     } else {
1110         out << ");\n";
1111         out << "if (_hidl_transact_err != ::android::OK) \n";
1112         out.block([&] {
1113             out << "_hidl_err = _hidl_transact_err;\n";
1114             out << "goto _hidl_error;\n";
1115         }).endl().endl();
1116     }
1117 
1118     if (!method->isOneway()) {
1119         Type::ErrorMode errorMode = hasCallback ? Type::ErrorMode_ReturnNothing : Type::ErrorMode_Goto;
1120 
1121         out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
1122         Type::handleError(out, errorMode);
1123 
1124         if (hasCallback) {
1125             out << "if (!_hidl_status.isOk()) { return; }\n\n";
1126         } else {
1127             out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1128         }
1129 
1130         for (const auto &arg : method->results()) {
1131             emitCppReaderWriter(
1132                     out,
1133                     "_hidl_reply",
1134                     false /* parcelObjIsPointer */,
1135                     arg,
1136                     true /* reader */,
1137                     errorMode,
1138                     true /* addPrefixToName */);
1139         }
1140 
1141         if (returnsValue && elidedReturn == nullptr) {
1142             out << "_hidl_cb(";
1143 
1144             out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
1145                 if (arg->type().resultNeedsDeref()) {
1146                     out << "*";
1147                 }
1148                 out << "_hidl_out_" << arg->name();
1149             });
1150 
1151             out << ");\n\n";
1152         }
1153     }
1154 
1155     generateCppInstrumentationCall(
1156             out,
1157             InstrumentationEvent::CLIENT_API_EXIT,
1158             method,
1159             superInterface);
1160 
1161     if (hasCallback) {
1162         out.unindent();
1163         out << "});\n";
1164         out << "if (_hidl_transact_err != ::android::OK) ";
1165         out.block([&] {
1166             out << "_hidl_err = _hidl_transact_err;\n";
1167             out << "goto _hidl_error;\n";
1168         }).endl().endl();
1169         out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n";
1170     }
1171 
1172     if (elidedReturn != nullptr) {
1173         out << "return ::android::hardware::Return<";
1174         out << elidedReturn->type().getCppResultType()
1175             << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1176     } else {
1177         out << "return ::android::hardware::Return<void>();\n\n";
1178     }
1179 
1180     out.unindent();
1181     out << "_hidl_error:\n";
1182     out.indent();
1183     out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1184     out << "return ::android::hardware::Return<";
1185     if (elidedReturn != nullptr) {
1186         out << method->results().at(0)->type().getCppResultType();
1187     } else {
1188         out << "void";
1189     }
1190     out << ">(_hidl_status);\n";
1191 
1192     out.unindent();
1193     out << "}\n\n";
1194 }
1195 
generateProxySource(Formatter & out,const FQName & fqName) const1196 void AST::generateProxySource(Formatter& out, const FQName& fqName) const {
1197     const std::string klassName = fqName.getInterfaceProxyName();
1198 
1199     out << klassName
1200         << "::"
1201         << klassName
1202         << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
1203 
1204     out.indent();
1205     out.indent();
1206 
1207     out << ": BpInterface"
1208         << "<"
1209         << fqName.getInterfaceName()
1210         << ">(_hidl_impl),\n"
1211         << "  ::android::hardware::details::HidlInstrumentor(\""
1212         << mPackage.string()
1213         << "\", \""
1214         << fqName.getInterfaceName()
1215         << "\") {\n";
1216 
1217     out.unindent();
1218     out.unindent();
1219     out << "}\n\n";
1220 
1221     out << "void " << klassName << "::onLastStrongRef(const void* id) ";
1222     out.block([&] {
1223         out.block([&] {
1224             // if unlinkToDeath is not used, remove strong cycle between
1225             // this and hidl_binder_death_recipient
1226             out << "std::unique_lock<std::mutex> lock(_hidl_mMutex);\n";
1227             out << "_hidl_mDeathRecipients.clear();\n";
1228         }).endl().endl();
1229 
1230         out << "BpInterface<" << fqName.getInterfaceName() << ">::onLastStrongRef(id);\n";
1231     }).endl();
1232 
1233     generateMethods(out,
1234                     [&](const Method* method, const Interface* superInterface) {
1235                         generateStaticProxyMethodSource(out, klassName, method, superInterface);
1236                     },
1237                     false /* include parents */);
1238 
1239     generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1240         generateProxyMethodSource(out, klassName, method, superInterface);
1241     });
1242 }
1243 
generateStubSource(Formatter & out,const Interface * iface) const1244 void AST::generateStubSource(Formatter& out, const Interface* iface) const {
1245     const std::string interfaceName = iface->definedName();
1246     const std::string klassName = iface->getStubName();
1247 
1248     out << klassName
1249         << "::"
1250         << klassName
1251         << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
1252 
1253     out.indent();
1254     out.indent();
1255 
1256     if (iface->isIBase()) {
1257         out << ": ::android::hardware::details::HidlInstrumentor(\"";
1258     } else {
1259         out << ": "
1260             << gIBaseFqName.getInterfaceStubFqName().cppName()
1261             << "(_hidl_impl, \"";
1262     }
1263 
1264     out << mPackage.string()
1265         << "\", \""
1266         << interfaceName
1267         << "\") { \n";
1268     out.indent();
1269     out << "_hidl_mImpl = _hidl_impl;\n";
1270     out << "auto prio = ::android::hardware::getMinSchedulerPolicy(_hidl_impl);\n";
1271     out << "mSchedPolicy = prio.sched_policy;\n";
1272     out << "mSchedPriority = prio.prio;\n";
1273     out << "setRequestingSid(::android::hardware::getRequestingSid(_hidl_impl));\n";
1274     out.unindent();
1275 
1276     out.unindent();
1277     out.unindent();
1278     out << "}\n\n";
1279 
1280     if (iface->isIBase()) {
1281         // BnHwBase has a constructor to initialize the HidlInstrumentor
1282         // class properly.
1283         out << klassName
1284             << "::"
1285             << klassName
1286             << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1287             << " const std::string &HidlInstrumentor_package,"
1288             << " const std::string &HidlInstrumentor_interface)\n";
1289 
1290         out.indent();
1291         out.indent();
1292 
1293         out << ": ::android::hardware::details::HidlInstrumentor("
1294             << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
1295         out.indent();
1296         out << "_hidl_mImpl = _hidl_impl;\n";
1297         out.unindent();
1298 
1299         out.unindent();
1300         out.unindent();
1301         out << "}\n\n";
1302     }
1303 
1304     out << klassName << "::~" << klassName << "() ";
1305     out.block([&]() {
1306            out << "::android::hardware::details::gBnMap->eraseIfEqual(_hidl_mImpl.get(), this);\n";
1307        })
1308             .endl()
1309             .endl();
1310 
1311     generateMethods(out,
1312                     [&](const Method* method, const Interface* superInterface) {
1313                         return generateStaticStubMethodSource(out, iface->fqName(), method, superInterface);
1314                     },
1315                     false /* include parents */);
1316 
1317     generateMethods(out, [&](const Method* method, const Interface*) {
1318         if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1319             return;
1320         }
1321         method->generateCppSignature(out, iface->getStubName());
1322         out << " ";
1323         out.block([&] {
1324             method->cppImpl(IMPL_STUB_IMPL, out);
1325         }).endl();
1326     });
1327 
1328     out << "::android::status_t " << klassName << "::onTransact(\n";
1329 
1330     out.indent();
1331     out.indent();
1332 
1333     out << "uint32_t _hidl_code,\n"
1334         << "const ::android::hardware::Parcel &_hidl_data,\n"
1335         << "::android::hardware::Parcel *_hidl_reply,\n"
1336         << "uint32_t _hidl_flags,\n"
1337         << "TransactCallback _hidl_cb) {\n";
1338 
1339     out.unindent();
1340 
1341     out << "::android::status_t _hidl_err = ::android::OK;\n\n";
1342     out << "switch (_hidl_code) {\n";
1343     out.indent();
1344 
1345     for (const auto &tuple : iface->allMethodsFromRoot()) {
1346         const Method *method = tuple.method();
1347         const Interface *superInterface = tuple.interface();
1348 
1349         if (!isIBase() && method->isHidlReserved()) {
1350             continue;
1351         }
1352         out << "case "
1353             << method->getSerialId()
1354             << " /* "
1355             << method->name()
1356             << " */:\n{\n";
1357 
1358         out.indent();
1359 
1360         generateStubSourceForMethod(out, method, superInterface);
1361 
1362         out.unindent();
1363         out << "}\n\n";
1364     }
1365 
1366     out << "default:\n{\n";
1367     out.indent();
1368 
1369     if (iface->isIBase()) {
1370         out << "(void)_hidl_flags;\n";
1371         out << "return ::android::UNKNOWN_TRANSACTION;\n";
1372     } else {
1373         out << "return ";
1374         out << gIBaseFqName.getInterfaceStubFqName().cppName();
1375         out << "::onTransact(\n";
1376 
1377         out.indent();
1378         out.indent();
1379 
1380         out << "_hidl_code, _hidl_data, _hidl_reply, "
1381             << "_hidl_flags, _hidl_cb);\n";
1382 
1383         out.unindent();
1384         out.unindent();
1385     }
1386 
1387     out.unindent();
1388     out << "}\n";
1389 
1390     out.unindent();
1391     out << "}\n\n";
1392 
1393     out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1394         out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1395         out.indent(2, [&] {
1396             out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1397             out << "_hidl_reply);\n";
1398         });
1399     });
1400 
1401     out << "return _hidl_err;\n";
1402 
1403     out.unindent();
1404     out << "}\n\n";
1405 }
1406 
generateStubSourceForMethod(Formatter & out,const Method * method,const Interface * superInterface) const1407 void AST::generateStubSourceForMethod(Formatter& out, const Method* method,
1408                                       const Interface* superInterface) const {
1409     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1410         method->cppImpl(IMPL_STUB, out);
1411         out << "break;\n";
1412         return;
1413     }
1414 
1415     out << "_hidl_err = "
1416         << superInterface->fqName().cppNamespace()
1417         << "::"
1418         << superInterface->getStubName()
1419         << "::_hidl_"
1420         << method->name()
1421         << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
1422     out << "break;\n";
1423 }
1424 
generateStaticStubMethodSource(Formatter & out,const FQName & fqName,const Method * method,const Interface * superInterface) const1425 void AST::generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
1426                                          const Method* method, const Interface* superInterface) const {
1427     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1428         return;
1429     }
1430 
1431     const std::string& klassName = fqName.getInterfaceStubName();
1432 
1433     out << "::android::status_t " << klassName << "::_hidl_" << method->name() << "(\n";
1434 
1435     out.indent();
1436     out.indent();
1437 
1438     out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
1439         << "const ::android::hardware::Parcel &_hidl_data,\n"
1440         << "::android::hardware::Parcel *_hidl_reply,\n"
1441         << "TransactCallback _hidl_cb) {\n";
1442 
1443     out.unindent();
1444 
1445     out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1446     out << "bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();\n";
1447     out << "const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();\n";
1448     out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1449 
1450     out << "::android::status_t _hidl_err = ::android::OK;\n";
1451 
1452     out << "if (!_hidl_data.enforceInterface("
1453         << klassName
1454         << "::Pure::descriptor)) {\n";
1455 
1456     out.indent();
1457     out << "_hidl_err = ::android::BAD_TYPE;\n";
1458     out << "return _hidl_err;\n";
1459     out.unindent();
1460     out << "}\n\n";
1461 
1462     declareCppReaderLocals(out, method->args(), false /* forResults */);
1463 
1464     for (const auto &arg : method->args()) {
1465         emitCppReaderWriter(
1466                 out,
1467                 "_hidl_data",
1468                 false /* parcelObjIsPointer */,
1469                 arg,
1470                 true /* reader */,
1471                 Type::ErrorMode_Return,
1472                 false /* addPrefixToName */);
1473     }
1474 
1475     generateCppInstrumentationCall(
1476             out,
1477             InstrumentationEvent::SERVER_API_ENTRY,
1478             method,
1479             superInterface);
1480 
1481     const bool returnsValue = !method->results().empty();
1482     const NamedReference<Type>* elidedReturn = method->canElideCallback();
1483 
1484     std::string callee;
1485 
1486     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL)) {
1487         callee = "_hidl_this";
1488     } else {
1489         callee = "static_cast<" + fqName.getInterfaceName() + "*>(_hidl_this->getImpl().get())";
1490     }
1491 
1492     if (elidedReturn != nullptr) {
1493         out << elidedReturn->type().getCppResultType()
1494             << " _hidl_out_"
1495             << elidedReturn->name()
1496             << " = "
1497             << callee << "->" << method->name()
1498             << "(";
1499 
1500         out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
1501             if (arg->type().resultNeedsDeref()) {
1502                 out << "*";
1503             }
1504             out << arg->name();
1505         });
1506 
1507         out << ");\n\n";
1508 
1509         out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1510             << "_hidl_reply);\n\n";
1511 
1512         elidedReturn->type().emitReaderWriter(
1513                 out,
1514                 "_hidl_out_" + elidedReturn->name(),
1515                 "_hidl_reply",
1516                 true, /* parcelObjIsPointer */
1517                 false, /* isReader */
1518                 Type::ErrorMode_Goto);
1519 
1520         out.unindent();
1521         out << "_hidl_error:\n";
1522         out.indent();
1523 
1524         generateCppInstrumentationCall(
1525                 out,
1526                 InstrumentationEvent::SERVER_API_EXIT,
1527                 method,
1528             superInterface);
1529 
1530         out << "if (_hidl_err != ::android::OK) { return _hidl_err; }\n";
1531         out << "_hidl_cb(*_hidl_reply);\n";
1532     } else {
1533         if (returnsValue) {
1534             out << "bool _hidl_callbackCalled = false;\n\n";
1535         }
1536 
1537         out << "::android::hardware::Return<void> _hidl_ret = " << callee << "->" << method->name()
1538             << "(";
1539 
1540         out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
1541             if (arg->type().resultNeedsDeref()) {
1542                 out << "*";
1543             }
1544 
1545             out << arg->name();
1546         });
1547 
1548         if (returnsValue) {
1549             if (!method->args().empty()) {
1550                 out << ", ";
1551             }
1552 
1553             out << "[&](";
1554 
1555             out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
1556                 out << "const auto &_hidl_out_" << arg->name();
1557             });
1558 
1559             out << ") {\n";
1560             out.indent();
1561             out << "if (_hidl_callbackCalled) {\n";
1562             out.indent();
1563             out << "LOG_ALWAYS_FATAL(\""
1564                 << method->name()
1565                 << ": _hidl_cb called a second time, but must be called once.\");\n";
1566             out.unindent();
1567             out << "}\n";
1568             out << "_hidl_callbackCalled = true;\n\n";
1569 
1570             out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1571                 << "_hidl_reply);\n\n";
1572 
1573             for (const auto &arg : method->results()) {
1574                 emitCppReaderWriter(
1575                         out,
1576                         "_hidl_reply",
1577                         true /* parcelObjIsPointer */,
1578                         arg,
1579                         false /* reader */,
1580                         Type::ErrorMode_Goto,
1581                         true /* addPrefixToName */);
1582             }
1583 
1584             if (!method->results().empty()) {
1585                 out.unindent();
1586                 out << "_hidl_error:\n";
1587                 out.indent();
1588             }
1589 
1590             generateCppInstrumentationCall(
1591                     out,
1592                     InstrumentationEvent::SERVER_API_EXIT,
1593                     method,
1594                     superInterface);
1595 
1596             out << "if (_hidl_err != ::android::OK) { return; }\n";
1597             out << "_hidl_cb(*_hidl_reply);\n";
1598 
1599             out.unindent();
1600             out << "});\n\n";
1601         } else {
1602             out << ");\n\n";
1603             out << "(void) _hidl_cb;\n\n";
1604             generateCppInstrumentationCall(
1605                     out,
1606                     InstrumentationEvent::SERVER_API_EXIT,
1607                     method,
1608                     superInterface);
1609         }
1610 
1611         out << "_hidl_ret.assertOk();\n";
1612 
1613         if (returnsValue) {
1614             out << "if (!_hidl_callbackCalled) {\n";
1615             out.indent();
1616             out << "LOG_ALWAYS_FATAL(\""
1617                 << method->name()
1618                 << ": _hidl_cb not called, but must be called once.\");\n";
1619             out.unindent();
1620             out << "}\n\n";
1621         } else {
1622             out << "::android::hardware::writeToParcel("
1623                 << "::android::hardware::Status::ok(), "
1624                 << "_hidl_reply);\n\n";
1625         }
1626     }
1627 
1628     out << "return _hidl_err;\n";
1629     out.unindent();
1630     out << "}\n\n";
1631 }
1632 
generatePassthroughHeader(Formatter & out) const1633 void AST::generatePassthroughHeader(Formatter& out) const {
1634     if (!AST::isInterface()) {
1635         // types.hal does not get a stub header.
1636         return;
1637     }
1638 
1639     const Interface* iface = mRootScope.getInterface();
1640     CHECK(iface != nullptr);
1641 
1642     const std::string klassName = iface->getPassthroughName();
1643 
1644     const std::string guard = makeHeaderGuard(klassName);
1645 
1646     out << "#ifndef " << guard << "\n";
1647     out << "#define " << guard << "\n\n";
1648 
1649     out << "#include <android-base/macros.h>\n";
1650     out << "#include <cutils/trace.h>\n";
1651     out << "#include <future>\n";
1652 
1653     generateCppPackageInclude(out, mPackage, iface->definedName());
1654     out << "\n";
1655 
1656     out << "#include <hidl/HidlPassthroughSupport.h>\n";
1657     out << "#include <hidl/TaskRunner.h>\n";
1658 
1659     enterLeaveNamespace(out, true /* enter */);
1660     out << "\n";
1661 
1662     out << "struct " << klassName << " : " << iface->definedName()
1663         << ", ::android::hardware::details::HidlInstrumentor {\n";
1664 
1665     out.indent();
1666     out << "explicit " << klassName << "(const ::android::sp<" << iface->definedName()
1667         << "> impl);\n";
1668 
1669     out.endl();
1670     generateTemplatizationLink(out);
1671     generateCppTag(out, "::android::hardware::details::bs_tag");
1672 
1673     generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1674         generatePassthroughMethod(out, method, superInterface);
1675     });
1676 
1677     out.unindent();
1678     out << "private:\n";
1679     out.indent();
1680     out << "const ::android::sp<" << iface->definedName() << "> mImpl;\n";
1681 
1682     out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
1683 
1684     out << "\n";
1685 
1686     out << "::android::hardware::Return<void> addOnewayTask("
1687            "std::function<void(void)>);\n\n";
1688 
1689     out.unindent();
1690 
1691     out << "};\n\n";
1692 
1693     enterLeaveNamespace(out, false /* enter */);
1694 
1695     out << "\n#endif  // " << guard << "\n";
1696 }
1697 
generateInterfaceSource(Formatter & out) const1698 void AST::generateInterfaceSource(Formatter& out) const {
1699     const Interface* iface = mRootScope.getInterface();
1700 
1701     // generate castFrom functions
1702     std::string childTypeResult = iface->getCppResultType();
1703 
1704     generateMethods(out, [&](const Method* method, const Interface*) {
1705         bool reserved = method->isHidlReserved();
1706 
1707         if (!reserved) {
1708             out << "// no default implementation for: ";
1709         }
1710         method->generateCppSignature(out, iface->definedName());
1711         if (reserved) {
1712             out.block([&]() {
1713                 method->cppImpl(IMPL_INTERFACE, out);
1714             }).endl();
1715         }
1716 
1717         out << "\n";
1718 
1719         return;
1720     });
1721 
1722     for (const Interface *superType : iface->typeChain()) {
1723         out << "::android::hardware::Return<" << childTypeResult << "> " << iface->definedName()
1724             << "::castFrom(" << superType->getCppArgumentType() << " parent, bool "
1725             << (iface == superType ? "/* emitError */" : "emitError") << ") {\n";
1726         out.indent();
1727         if (iface == superType) {
1728             out << "return parent;\n";
1729         } else {
1730             out << "return ::android::hardware::details::castInterface<";
1731             out << iface->definedName() << ", " << superType->fqName().cppName() << ", "
1732                 << iface->getProxyName() << ">(\n";
1733             out.indent();
1734             out.indent();
1735             out << "parent, \""
1736                 << iface->fqName().string()
1737                 << "\", emitError);\n";
1738             out.unindent();
1739             out.unindent();
1740         }
1741         out.unindent();
1742         out << "}\n\n";
1743     }
1744 }
1745 
generatePassthroughSource(Formatter & out) const1746 void AST::generatePassthroughSource(Formatter& out) const {
1747     const Interface* iface = mRootScope.getInterface();
1748 
1749     const std::string klassName = iface->getPassthroughName();
1750 
1751     out << klassName << "::" << klassName << "(const ::android::sp<" << iface->fullName()
1752         << "> impl) : ::android::hardware::details::HidlInstrumentor(\"" << mPackage.string()
1753         << "\", \"" << iface->definedName() << "\"), mImpl(impl) {\n";
1754 
1755     out.indent([&] { out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n"; });
1756 
1757     out << "}\n\n";
1758 
1759     out << "::android::hardware::Return<void> " << klassName
1760         << "::addOnewayTask(std::function<void(void)> fun) {\n";
1761     out.indent();
1762     out << "if (!mOnewayQueue.push(fun)) {\n";
1763     out.indent();
1764     out << "return ::android::hardware::Status::fromExceptionCode(\n";
1765     out.indent();
1766     out.indent();
1767     out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
1768         << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
1769     out.unindent();
1770     out.unindent();
1771     out.unindent();
1772     out << "}\n";
1773 
1774     out << "return ::android::hardware::Status();\n";
1775 
1776     out.unindent();
1777     out << "}\n\n";
1778 }
1779 
generateCppAtraceCall(Formatter & out,InstrumentationEvent event,const Method * method) const1780 void AST::generateCppAtraceCall(Formatter &out,
1781                                     InstrumentationEvent event,
1782                                     const Method *method) const {
1783     const Interface* iface = mRootScope.getInterface();
1784     std::string baseString = "HIDL::" + iface->definedName() + "::" + method->name();
1785     switch (event) {
1786         case SERVER_API_ENTRY:
1787         {
1788             out << "atrace_begin(ATRACE_TAG_HAL, \""
1789                 << baseString + "::server\");\n";
1790             break;
1791         }
1792         case PASSTHROUGH_ENTRY:
1793         {
1794             out << "atrace_begin(ATRACE_TAG_HAL, \""
1795                 << baseString + "::passthrough\");\n";
1796             break;
1797         }
1798         case SERVER_API_EXIT:
1799         case PASSTHROUGH_EXIT:
1800         {
1801             out << "atrace_end(ATRACE_TAG_HAL);\n";
1802             break;
1803         }
1804         // client uses scope because of gotos
1805         // this isn't done for server because the profiled code isn't alone in its scope
1806         // this isn't done for passthrough becuase the profiled boundary isn't even in the same code
1807         case CLIENT_API_ENTRY: {
1808             out << "::android::ScopedTrace PASTE(___tracer, __LINE__) (ATRACE_TAG_HAL, \""
1809                 << baseString + "::client\");\n";
1810             break;
1811         }
1812         case CLIENT_API_EXIT:
1813             break;
1814         default:
1815         {
1816             CHECK(false) << "Unsupported instrumentation event: " << event;
1817         }
1818     }
1819 }
1820 
generateCppInstrumentationCall(Formatter & out,InstrumentationEvent event,const Method * method,const Interface * superInterface) const1821 void AST::generateCppInstrumentationCall(
1822         Formatter &out,
1823         InstrumentationEvent event,
1824         const Method *method,
1825         const Interface* superInterface) const {
1826     generateCppAtraceCall(out, event, method);
1827 
1828     out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1829     out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1830     out.indent();
1831     out << "std::vector<void *> _hidl_args;\n";
1832     std::string event_str = "";
1833     switch (event) {
1834         case SERVER_API_ENTRY:
1835         {
1836             event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1837             for (const auto &arg : method->args()) {
1838                 out << "_hidl_args.push_back((void *)"
1839                     << (arg->type().resultNeedsDeref() ? "" : "&")
1840                     << arg->name()
1841                     << ");\n";
1842             }
1843             break;
1844         }
1845         case SERVER_API_EXIT:
1846         {
1847             event_str = "InstrumentationEvent::SERVER_API_EXIT";
1848             for (const auto &arg : method->results()) {
1849                 out << "_hidl_args.push_back((void *)&_hidl_out_"
1850                     << arg->name()
1851                     << ");\n";
1852             }
1853             break;
1854         }
1855         case CLIENT_API_ENTRY:
1856         {
1857             event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1858             for (const auto &arg : method->args()) {
1859                 out << "_hidl_args.push_back((void *)&"
1860                     << arg->name()
1861                     << ");\n";
1862             }
1863             break;
1864         }
1865         case CLIENT_API_EXIT:
1866         {
1867             event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1868             for (const auto &arg : method->results()) {
1869                 out << "_hidl_args.push_back((void *)"
1870                     << (arg->type().resultNeedsDeref() ? "" : "&")
1871                     << "_hidl_out_"
1872                     << arg->name()
1873                     << ");\n";
1874             }
1875             break;
1876         }
1877         case PASSTHROUGH_ENTRY:
1878         {
1879             event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1880             for (const auto &arg : method->args()) {
1881                 out << "_hidl_args.push_back((void *)&"
1882                     << arg->name()
1883                     << ");\n";
1884             }
1885             break;
1886         }
1887         case PASSTHROUGH_EXIT:
1888         {
1889             event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
1890             for (const auto &arg : method->results()) {
1891                 out << "_hidl_args.push_back((void *)&_hidl_out_"
1892                     << arg->name()
1893                     << ");\n";
1894             }
1895             break;
1896         }
1897         default:
1898         {
1899             CHECK(false) << "Unsupported instrumentation event: " << event;
1900         }
1901     }
1902 
1903     out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
1904     out.indent();
1905     out << "callback(" << event_str << ", \"" << superInterface->fqName().package() << "\", \""
1906         << superInterface->fqName().version() << "\", \"" << superInterface->definedName()
1907         << "\", \"" << method->name() << "\", &_hidl_args);\n";
1908     out.unindent();
1909     out << "}\n";
1910     out.unindent();
1911     out << "}\n";
1912     out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1913 }
1914 
1915 }  // namespace android
1916