• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "AST.h"
18 
19 #include "Coordinator.h"
20 #include "EnumType.h"
21 #include "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     // 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 
generateProxyHeader(Formatter & out) const751 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 
generateCppSource(Formatter & out) const832 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 
generateTypeSource(Formatter & out,const std::string & ifaceName) const939 void AST::generateTypeSource(Formatter& out, const std::string& ifaceName) const {
940     mRootScope.emitTypeDefinitions(out, ifaceName);
941 }
942 
declareCppReaderLocals(Formatter & out,const std::vector<NamedReference<Type> * > & args,bool forResults) const943 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 
emitCppReaderWriter(Formatter & out,const std::string & parcelObj,bool parcelObjIsPointer,const NamedReference<Type> * arg,bool isReader,Type::ErrorMode mode,bool addPrefixToName) const961 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 
generateProxyMethodSource(Formatter & out,const std::string & klassName,const Method * method,const Interface * superInterface) const975 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 
generateStaticProxyMethodSource(Formatter & out,const std::string & klassName,const Method * method,const Interface * superInterface) const1023 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     if (superInterface->hasSensitiveDataAnnotation()) {
1075         out << "_hidl_data.markSensitive();\n";
1076     }
1077 
1078     out << "_hidl_err = _hidl_data.writeInterfaceToken(";
1079     out << klassName;
1080     out << "::descriptor);\n";
1081     out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1082 
1083     bool hasInterfaceArgument = false;
1084 
1085     for (const auto &arg : method->args()) {
1086         if (arg->type().isInterface()) {
1087             hasInterfaceArgument = true;
1088         }
1089         emitCppReaderWriter(
1090                 out,
1091                 "_hidl_data",
1092                 false /* parcelObjIsPointer */,
1093                 arg,
1094                 false /* reader */,
1095                 Type::ErrorMode_Goto,
1096                 false /* addPrefixToName */);
1097     }
1098 
1099     if (hasInterfaceArgument) {
1100         // Start binder threadpool to handle incoming transactions
1101         out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1102     }
1103     out << "_hidl_transact_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact("
1104         << method->getSerialId() << " /* " << method->name()
1105         << " */, _hidl_data, &_hidl_reply, 0 /* flags */";
1106 
1107     if (method->isOneway()) {
1108         out << " | " << Interface::FLAG_ONE_WAY->cppValue();
1109     }
1110     if (superInterface->hasSensitiveDataAnnotation()) {
1111         out << " | " << Interface::FLAG_CLEAR_BUF->cppValue();
1112     }
1113 
1114     if (hasCallback) {
1115         out << ", [&] (::android::hardware::Parcel& _hidl_reply) {\n";
1116         out.indent();
1117         declareCppReaderLocals(
1118                 out, method->results(), true /* forResults */);
1119         out.endl();
1120     } else {
1121         out << ");\n";
1122         out << "if (_hidl_transact_err != ::android::OK) \n";
1123         out.block([&] {
1124             out << "_hidl_err = _hidl_transact_err;\n";
1125             out << "goto _hidl_error;\n";
1126         }).endl().endl();
1127     }
1128 
1129     if (!method->isOneway()) {
1130         Type::ErrorMode errorMode = hasCallback ? Type::ErrorMode_ReturnNothing : Type::ErrorMode_Goto;
1131 
1132         out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
1133         Type::handleError(out, errorMode);
1134 
1135         if (hasCallback) {
1136             out << "if (!_hidl_status.isOk()) { return; }\n\n";
1137         } else {
1138             out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1139         }
1140 
1141         for (const auto &arg : method->results()) {
1142             emitCppReaderWriter(
1143                     out,
1144                     "_hidl_reply",
1145                     false /* parcelObjIsPointer */,
1146                     arg,
1147                     true /* reader */,
1148                     errorMode,
1149                     true /* addPrefixToName */);
1150         }
1151 
1152         if (returnsValue && elidedReturn == nullptr) {
1153             out << "_hidl_cb(";
1154 
1155             out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
1156                 if (arg->type().resultNeedsDeref()) {
1157                     out << "*";
1158                 }
1159                 out << "_hidl_out_" << arg->name();
1160             });
1161 
1162             out << ");\n\n";
1163         }
1164     }
1165 
1166     generateCppInstrumentationCall(
1167             out,
1168             InstrumentationEvent::CLIENT_API_EXIT,
1169             method,
1170             superInterface);
1171 
1172     if (hasCallback) {
1173         out.unindent();
1174         out << "});\n";
1175         out << "if (_hidl_transact_err != ::android::OK) ";
1176         out.block([&] {
1177             out << "_hidl_err = _hidl_transact_err;\n";
1178             out << "goto _hidl_error;\n";
1179         }).endl().endl();
1180         out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n";
1181     }
1182 
1183     if (elidedReturn != nullptr) {
1184         out << "return ::android::hardware::Return<";
1185         out << elidedReturn->type().getCppResultType()
1186             << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1187     } else {
1188         out << "return ::android::hardware::Return<void>();\n\n";
1189     }
1190 
1191     out.unindent();
1192     out << "_hidl_error:\n";
1193     out.indent();
1194     out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1195     out << "return ::android::hardware::Return<";
1196     if (elidedReturn != nullptr) {
1197         out << method->results().at(0)->type().getCppResultType();
1198     } else {
1199         out << "void";
1200     }
1201     out << ">(_hidl_status);\n";
1202 
1203     out.unindent();
1204     out << "}\n\n";
1205 }
1206 
generateProxySource(Formatter & out,const FQName & fqName) const1207 void AST::generateProxySource(Formatter& out, const FQName& fqName) const {
1208     const std::string klassName = fqName.getInterfaceProxyName();
1209 
1210     out << klassName
1211         << "::"
1212         << klassName
1213         << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
1214 
1215     out.indent();
1216     out.indent();
1217 
1218     out << ": BpInterface"
1219         << "<"
1220         << fqName.getInterfaceName()
1221         << ">(_hidl_impl),\n"
1222         << "  ::android::hardware::details::HidlInstrumentor(\""
1223         << mPackage.string()
1224         << "\", \""
1225         << fqName.getInterfaceName()
1226         << "\") {\n";
1227 
1228     out.unindent();
1229     out.unindent();
1230     out << "}\n\n";
1231 
1232     out << "void " << klassName << "::onLastStrongRef(const void* id) ";
1233     out.block([&] {
1234         out.block([&] {
1235             // if unlinkToDeath is not used, remove strong cycle between
1236             // this and hidl_binder_death_recipient
1237             out << "std::unique_lock<std::mutex> lock(_hidl_mMutex);\n";
1238             out << "_hidl_mDeathRecipients.clear();\n";
1239         }).endl().endl();
1240 
1241         out << "BpInterface<" << fqName.getInterfaceName() << ">::onLastStrongRef(id);\n";
1242     }).endl();
1243 
1244     generateMethods(out,
1245                     [&](const Method* method, const Interface* superInterface) {
1246                         generateStaticProxyMethodSource(out, klassName, method, superInterface);
1247                     },
1248                     false /* include parents */);
1249 
1250     generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1251         generateProxyMethodSource(out, klassName, method, superInterface);
1252     });
1253 }
1254 
generateStubSource(Formatter & out,const Interface * iface) const1255 void AST::generateStubSource(Formatter& out, const Interface* iface) const {
1256     const std::string interfaceName = iface->definedName();
1257     const std::string klassName = iface->getStubName();
1258 
1259     out << klassName
1260         << "::"
1261         << klassName
1262         << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
1263 
1264     out.indent();
1265     out.indent();
1266 
1267     if (iface->isIBase()) {
1268         out << ": ::android::hardware::details::HidlInstrumentor(\"";
1269     } else {
1270         out << ": "
1271             << gIBaseFqName.getInterfaceStubFqName().cppName()
1272             << "(_hidl_impl, \"";
1273     }
1274 
1275     out << mPackage.string()
1276         << "\", \""
1277         << interfaceName
1278         << "\") { \n";
1279     out.indent();
1280     out << "_hidl_mImpl = _hidl_impl;\n";
1281     out << "auto prio = ::android::hardware::getMinSchedulerPolicy(_hidl_impl);\n";
1282     out << "mSchedPolicy = prio.sched_policy;\n";
1283     out << "mSchedPriority = prio.prio;\n";
1284     out << "setRequestingSid(::android::hardware::getRequestingSid(_hidl_impl));\n";
1285     out.unindent();
1286 
1287     out.unindent();
1288     out.unindent();
1289     out << "}\n\n";
1290 
1291     if (iface->isIBase()) {
1292         // BnHwBase has a constructor to initialize the HidlInstrumentor
1293         // class properly.
1294         out << klassName
1295             << "::"
1296             << klassName
1297             << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1298             << " const std::string &HidlInstrumentor_package,"
1299             << " const std::string &HidlInstrumentor_interface)\n";
1300 
1301         out.indent();
1302         out.indent();
1303 
1304         out << ": ::android::hardware::details::HidlInstrumentor("
1305             << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
1306         out.indent();
1307         out << "_hidl_mImpl = _hidl_impl;\n";
1308         out.unindent();
1309 
1310         out.unindent();
1311         out.unindent();
1312         out << "}\n\n";
1313     }
1314 
1315     out << klassName << "::~" << klassName << "() ";
1316     out.block([&]() {
1317            out << "::android::hardware::details::gBnMap->eraseIfEqual(_hidl_mImpl.get(), this);\n";
1318        })
1319             .endl()
1320             .endl();
1321 
1322     if (isIBase()) {
1323         out << "bool " << klassName << "::checkSubclass(const void* subclassID) const ";
1324         out.block([&] { out << "return subclassID == " << interfaceName << "::descriptor;\n"; });
1325     }
1326 
1327     generateMethods(out,
1328                     [&](const Method* method, const Interface* superInterface) {
1329                         return generateStaticStubMethodSource(out, iface->fqName(), method, superInterface);
1330                     },
1331                     false /* include parents */);
1332 
1333     generateMethods(out, [&](const Method* method, const Interface*) {
1334         if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1335             return;
1336         }
1337         method->generateCppSignature(out, iface->getStubName());
1338         out << " ";
1339         out.block([&] {
1340             method->cppImpl(IMPL_STUB_IMPL, out);
1341         }).endl();
1342     });
1343 
1344     out << "::android::status_t " << klassName << "::onTransact(\n";
1345 
1346     out.indent();
1347     out.indent();
1348 
1349     out << "uint32_t _hidl_code,\n"
1350         << "const ::android::hardware::Parcel &_hidl_data,\n"
1351         << "::android::hardware::Parcel *_hidl_reply,\n"
1352         << "uint32_t _hidl_flags,\n"
1353         << "TransactCallback _hidl_cb) {\n";
1354 
1355     out.unindent();
1356 
1357     out << "::android::status_t _hidl_err = ::android::OK;\n\n";
1358     out << "switch (_hidl_code) {\n";
1359     out.indent();
1360 
1361     for (const auto &tuple : iface->allMethodsFromRoot()) {
1362         const Method *method = tuple.method();
1363         const Interface *superInterface = tuple.interface();
1364 
1365         if (!isIBase() && method->isHidlReserved()) {
1366             continue;
1367         }
1368         out << "case "
1369             << method->getSerialId()
1370             << " /* "
1371             << method->name()
1372             << " */:\n{\n";
1373 
1374         out.indent();
1375 
1376         generateStubSourceForMethod(out, method, superInterface);
1377 
1378         out.unindent();
1379         out << "}\n\n";
1380     }
1381 
1382     out << "default:\n{\n";
1383     out.indent();
1384 
1385     if (iface->isIBase()) {
1386         out << "(void)_hidl_flags;\n";
1387         out << "return ::android::UNKNOWN_TRANSACTION;\n";
1388     } else {
1389         out << "return ";
1390         out << gIBaseFqName.getInterfaceStubFqName().cppName();
1391         out << "::onTransact(\n";
1392 
1393         out.indent();
1394         out.indent();
1395 
1396         out << "_hidl_code, _hidl_data, _hidl_reply, "
1397             << "_hidl_flags, _hidl_cb);\n";
1398 
1399         out.unindent();
1400         out.unindent();
1401     }
1402 
1403     out.unindent();
1404     out << "}\n";
1405 
1406     out.unindent();
1407     out << "}\n\n";
1408 
1409     out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1410         out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1411         out.indent(2, [&] {
1412             out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1413             out << "_hidl_reply);\n";
1414         });
1415     });
1416 
1417     out << "return _hidl_err;\n";
1418 
1419     out.unindent();
1420     out << "}\n\n";
1421 }
1422 
generateStubSourceForMethod(Formatter & out,const Method * method,const Interface * superInterface) const1423 void AST::generateStubSourceForMethod(Formatter& out, const Method* method,
1424                                       const Interface* superInterface) const {
1425     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1426         method->cppImpl(IMPL_STUB, out);
1427         out << "break;\n";
1428         return;
1429     }
1430 
1431     out << "_hidl_err = "
1432         << superInterface->fqName().cppNamespace()
1433         << "::"
1434         << superInterface->getStubName()
1435         << "::_hidl_"
1436         << method->name()
1437         << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
1438     out << "break;\n";
1439 }
1440 
generateStaticStubMethodSource(Formatter & out,const FQName & fqName,const Method * method,const Interface * superInterface) const1441 void AST::generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
1442                                          const Method* method, const Interface* superInterface) const {
1443     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1444         return;
1445     }
1446 
1447     const std::string& klassName = fqName.getInterfaceStubName();
1448 
1449     out << "::android::status_t " << klassName << "::_hidl_" << method->name() << "(\n";
1450 
1451     out.indent();
1452     out.indent();
1453 
1454     out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
1455         << "const ::android::hardware::Parcel &_hidl_data,\n"
1456         << "::android::hardware::Parcel *_hidl_reply,\n"
1457         << "TransactCallback _hidl_cb) {\n";
1458 
1459     out.unindent();
1460 
1461     out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1462     out << "bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();\n";
1463     out << "const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();\n";
1464     out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1465 
1466     out << "::android::status_t _hidl_err = ::android::OK;\n";
1467 
1468     out << "if (!_hidl_data.enforceInterface("
1469         << klassName
1470         << "::Pure::descriptor)) {\n";
1471 
1472     out.indent();
1473     out << "_hidl_err = ::android::BAD_TYPE;\n";
1474     out << "return _hidl_err;\n";
1475     out.unindent();
1476     out << "}\n\n";
1477 
1478     declareCppReaderLocals(out, method->args(), false /* forResults */);
1479 
1480     for (const auto &arg : method->args()) {
1481         emitCppReaderWriter(
1482                 out,
1483                 "_hidl_data",
1484                 false /* parcelObjIsPointer */,
1485                 arg,
1486                 true /* reader */,
1487                 Type::ErrorMode_Return,
1488                 false /* addPrefixToName */);
1489     }
1490 
1491     generateCppInstrumentationCall(
1492             out,
1493             InstrumentationEvent::SERVER_API_ENTRY,
1494             method,
1495             superInterface);
1496 
1497     const bool returnsValue = !method->results().empty();
1498     const NamedReference<Type>* elidedReturn = method->canElideCallback();
1499 
1500     std::string callee;
1501 
1502     if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL)) {
1503         callee = "_hidl_this";
1504     } else {
1505         callee = "static_cast<" + fqName.getInterfaceName() + "*>(_hidl_this->getImpl().get())";
1506     }
1507 
1508     if (elidedReturn != nullptr) {
1509         out << elidedReturn->type().getCppResultType()
1510             << " _hidl_out_"
1511             << elidedReturn->name()
1512             << " = "
1513             << callee << "->" << method->name()
1514             << "(";
1515 
1516         out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
1517             if (arg->type().resultNeedsDeref()) {
1518                 out << "*";
1519             }
1520             out << arg->name();
1521         });
1522 
1523         out << ");\n\n";
1524 
1525         out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1526             << "_hidl_reply);\n\n";
1527 
1528         elidedReturn->type().emitReaderWriter(
1529                 out,
1530                 "_hidl_out_" + elidedReturn->name(),
1531                 "_hidl_reply",
1532                 true, /* parcelObjIsPointer */
1533                 false, /* isReader */
1534                 Type::ErrorMode_Goto);
1535 
1536         out.unindent();
1537         out << "_hidl_error:\n";
1538         out.indent();
1539 
1540         generateCppInstrumentationCall(
1541                 out,
1542                 InstrumentationEvent::SERVER_API_EXIT,
1543                 method,
1544             superInterface);
1545 
1546         out << "if (_hidl_err != ::android::OK) { return _hidl_err; }\n";
1547         out << "_hidl_cb(*_hidl_reply);\n";
1548     } else {
1549         if (returnsValue) {
1550             out << "bool _hidl_callbackCalled = false;\n\n";
1551         }
1552 
1553         out << "::android::hardware::Return<void> _hidl_ret = " << callee << "->" << method->name()
1554             << "(";
1555 
1556         out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
1557             if (arg->type().resultNeedsDeref()) {
1558                 out << "*";
1559             }
1560 
1561             out << arg->name();
1562         });
1563 
1564         if (returnsValue) {
1565             if (!method->args().empty()) {
1566                 out << ", ";
1567             }
1568 
1569             out << "[&](";
1570 
1571             out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
1572                 out << "const auto &_hidl_out_" << arg->name();
1573             });
1574 
1575             out << ") {\n";
1576             out.indent();
1577             out << "if (_hidl_callbackCalled) {\n";
1578             out.indent();
1579             out << "LOG_ALWAYS_FATAL(\""
1580                 << method->name()
1581                 << ": _hidl_cb called a second time, but must be called once.\");\n";
1582             out.unindent();
1583             out << "}\n";
1584             out << "_hidl_callbackCalled = true;\n\n";
1585 
1586             out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1587                 << "_hidl_reply);\n\n";
1588 
1589             for (const auto &arg : method->results()) {
1590                 emitCppReaderWriter(
1591                         out,
1592                         "_hidl_reply",
1593                         true /* parcelObjIsPointer */,
1594                         arg,
1595                         false /* reader */,
1596                         Type::ErrorMode_Goto,
1597                         true /* addPrefixToName */);
1598             }
1599 
1600             if (!method->results().empty()) {
1601                 out.unindent();
1602                 out << "_hidl_error:\n";
1603                 out.indent();
1604             }
1605 
1606             generateCppInstrumentationCall(
1607                     out,
1608                     InstrumentationEvent::SERVER_API_EXIT,
1609                     method,
1610                     superInterface);
1611 
1612             out << "if (_hidl_err != ::android::OK) { return; }\n";
1613             out << "_hidl_cb(*_hidl_reply);\n";
1614 
1615             out.unindent();
1616             out << "});\n\n";
1617         } else {
1618             out << ");\n\n";
1619             out << "(void) _hidl_cb;\n\n";
1620             generateCppInstrumentationCall(
1621                     out,
1622                     InstrumentationEvent::SERVER_API_EXIT,
1623                     method,
1624                     superInterface);
1625         }
1626 
1627         out << "_hidl_ret.assertOk();\n";
1628 
1629         if (returnsValue) {
1630             out << "if (!_hidl_callbackCalled) {\n";
1631             out.indent();
1632             out << "LOG_ALWAYS_FATAL(\""
1633                 << method->name()
1634                 << ": _hidl_cb not called, but must be called once.\");\n";
1635             out.unindent();
1636             out << "}\n\n";
1637         } else {
1638             out << "::android::hardware::writeToParcel("
1639                 << "::android::hardware::Status::ok(), "
1640                 << "_hidl_reply);\n\n";
1641         }
1642     }
1643 
1644     out << "return _hidl_err;\n";
1645     out.unindent();
1646     out << "}\n\n";
1647 }
1648 
generatePassthroughHeader(Formatter & out) const1649 void AST::generatePassthroughHeader(Formatter& out) const {
1650     if (!AST::isInterface()) {
1651         // types.hal does not get a stub header.
1652         return;
1653     }
1654 
1655     const Interface* iface = mRootScope.getInterface();
1656     CHECK(iface != nullptr);
1657 
1658     const std::string klassName = iface->getPassthroughName();
1659 
1660     const std::string guard = makeHeaderGuard(klassName);
1661 
1662     out << "#ifndef " << guard << "\n";
1663     out << "#define " << guard << "\n\n";
1664 
1665     out << "#include <android-base/macros.h>\n";
1666     out << "#include <cutils/trace.h>\n";
1667     out << "#include <future>\n";
1668 
1669     generateCppPackageInclude(out, mPackage, iface->definedName());
1670     out << "\n";
1671 
1672     out << "#include <hidl/HidlPassthroughSupport.h>\n";
1673     out << "#include <hidl/TaskRunner.h>\n";
1674 
1675     enterLeaveNamespace(out, true /* enter */);
1676     out << "\n";
1677 
1678     out << "struct " << klassName << " : " << iface->definedName()
1679         << ", ::android::hardware::details::HidlInstrumentor {\n";
1680 
1681     out.indent();
1682     out << "explicit " << klassName << "(const ::android::sp<" << iface->definedName()
1683         << "> impl);\n";
1684 
1685     out.endl();
1686     generateTemplatizationLink(out);
1687     generateCppTag(out, "::android::hardware::details::bs_tag");
1688 
1689     generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1690         generatePassthroughMethod(out, method, superInterface);
1691     });
1692 
1693     out.unindent();
1694     out << "private:\n";
1695     out.indent();
1696     out << "const ::android::sp<" << iface->definedName() << "> mImpl;\n";
1697 
1698     out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
1699 
1700     out << "\n";
1701 
1702     out << "::android::hardware::Return<void> addOnewayTask("
1703            "std::function<void(void)>);\n\n";
1704 
1705     out.unindent();
1706 
1707     out << "};\n\n";
1708 
1709     enterLeaveNamespace(out, false /* enter */);
1710 
1711     out << "\n#endif  // " << guard << "\n";
1712 }
1713 
generateInterfaceSource(Formatter & out) const1714 void AST::generateInterfaceSource(Formatter& out) const {
1715     const Interface* iface = mRootScope.getInterface();
1716 
1717     // generate castFrom functions
1718     std::string childTypeResult = iface->getCppResultType();
1719 
1720     generateMethods(out, [&](const Method* method, const Interface*) {
1721         bool reserved = method->isHidlReserved();
1722 
1723         if (!reserved) {
1724             out << "// no default implementation for: ";
1725         }
1726         method->generateCppSignature(out, iface->definedName());
1727         if (reserved) {
1728             out.block([&]() {
1729                 method->cppImpl(IMPL_INTERFACE, out);
1730             }).endl();
1731         }
1732 
1733         out << "\n";
1734 
1735         return;
1736     });
1737 
1738     for (const Interface *superType : iface->typeChain()) {
1739         out << "::android::hardware::Return<" << childTypeResult << "> " << iface->definedName()
1740             << "::castFrom(" << superType->getCppArgumentType() << " parent, bool "
1741             << (iface == superType ? "/* emitError */" : "emitError") << ") {\n";
1742         out.indent();
1743         if (iface == superType) {
1744             out << "return parent;\n";
1745         } else {
1746             out << "return ::android::hardware::details::castInterface<";
1747             out << iface->definedName() << ", " << superType->fqName().cppName() << ", "
1748                 << iface->getProxyName() << ">(\n";
1749             out.indent();
1750             out.indent();
1751             out << "parent, \""
1752                 << iface->fqName().string()
1753                 << "\", emitError);\n";
1754             out.unindent();
1755             out.unindent();
1756         }
1757         out.unindent();
1758         out << "}\n\n";
1759     }
1760 }
1761 
generatePassthroughSource(Formatter & out) const1762 void AST::generatePassthroughSource(Formatter& out) const {
1763     const Interface* iface = mRootScope.getInterface();
1764 
1765     const std::string klassName = iface->getPassthroughName();
1766 
1767     out << klassName << "::" << klassName << "(const ::android::sp<" << iface->fullName()
1768         << "> impl) : ::android::hardware::details::HidlInstrumentor(\"" << mPackage.string()
1769         << "\", \"" << iface->definedName() << "\"), mImpl(impl) {\n";
1770 
1771     out.indent([&] { out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n"; });
1772 
1773     out << "}\n\n";
1774 
1775     out << "::android::hardware::Return<void> " << klassName
1776         << "::addOnewayTask(std::function<void(void)> fun) {\n";
1777     out.indent();
1778     out << "if (!mOnewayQueue.push(fun)) {\n";
1779     out.indent();
1780     out << "return ::android::hardware::Status::fromExceptionCode(\n";
1781     out.indent();
1782     out.indent();
1783     out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
1784         << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
1785     out.unindent();
1786     out.unindent();
1787     out.unindent();
1788     out << "}\n";
1789 
1790     out << "return ::android::hardware::Status();\n";
1791 
1792     out.unindent();
1793     out << "}\n\n";
1794 }
1795 
generateCppAtraceCall(Formatter & out,InstrumentationEvent event,const Method * method) const1796 void AST::generateCppAtraceCall(Formatter &out,
1797                                     InstrumentationEvent event,
1798                                     const Method *method) const {
1799     const Interface* iface = mRootScope.getInterface();
1800     std::string baseString = "HIDL::" + iface->definedName() + "::" + method->name();
1801     switch (event) {
1802         case SERVER_API_ENTRY:
1803         {
1804             out << "atrace_begin(ATRACE_TAG_HAL, \""
1805                 << baseString + "::server\");\n";
1806             break;
1807         }
1808         case PASSTHROUGH_ENTRY:
1809         {
1810             out << "atrace_begin(ATRACE_TAG_HAL, \""
1811                 << baseString + "::passthrough\");\n";
1812             break;
1813         }
1814         case SERVER_API_EXIT:
1815         case PASSTHROUGH_EXIT:
1816         {
1817             out << "atrace_end(ATRACE_TAG_HAL);\n";
1818             break;
1819         }
1820         // client uses scope because of gotos
1821         // this isn't done for server because the profiled code isn't alone in its scope
1822         // this isn't done for passthrough becuase the profiled boundary isn't even in the same code
1823         case CLIENT_API_ENTRY: {
1824             out << "::android::ScopedTrace PASTE(___tracer, __LINE__) (ATRACE_TAG_HAL, \""
1825                 << baseString + "::client\");\n";
1826             break;
1827         }
1828         case CLIENT_API_EXIT:
1829             break;
1830         default:
1831         {
1832             CHECK(false) << "Unsupported instrumentation event: " << event;
1833         }
1834     }
1835 }
1836 
generateCppInstrumentationCall(Formatter & out,InstrumentationEvent event,const Method * method,const Interface * superInterface) const1837 void AST::generateCppInstrumentationCall(
1838         Formatter &out,
1839         InstrumentationEvent event,
1840         const Method *method,
1841         const Interface* superInterface) const {
1842     generateCppAtraceCall(out, event, method);
1843 
1844     out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1845     out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1846     out.indent();
1847     out << "std::vector<void *> _hidl_args;\n";
1848     std::string event_str = "";
1849     switch (event) {
1850         case SERVER_API_ENTRY:
1851         {
1852             event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1853             for (const auto &arg : method->args()) {
1854                 out << "_hidl_args.push_back((void *)"
1855                     << (arg->type().resultNeedsDeref() ? "" : "&")
1856                     << arg->name()
1857                     << ");\n";
1858             }
1859             break;
1860         }
1861         case SERVER_API_EXIT:
1862         {
1863             event_str = "InstrumentationEvent::SERVER_API_EXIT";
1864             for (const auto &arg : method->results()) {
1865                 out << "_hidl_args.push_back((void *)&_hidl_out_"
1866                     << arg->name()
1867                     << ");\n";
1868             }
1869             break;
1870         }
1871         case CLIENT_API_ENTRY:
1872         {
1873             event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1874             for (const auto &arg : method->args()) {
1875                 out << "_hidl_args.push_back((void *)&"
1876                     << arg->name()
1877                     << ");\n";
1878             }
1879             break;
1880         }
1881         case CLIENT_API_EXIT:
1882         {
1883             event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1884             for (const auto &arg : method->results()) {
1885                 out << "_hidl_args.push_back((void *)"
1886                     << (arg->type().resultNeedsDeref() ? "" : "&")
1887                     << "_hidl_out_"
1888                     << arg->name()
1889                     << ");\n";
1890             }
1891             break;
1892         }
1893         case PASSTHROUGH_ENTRY:
1894         {
1895             event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1896             for (const auto &arg : method->args()) {
1897                 out << "_hidl_args.push_back((void *)&"
1898                     << arg->name()
1899                     << ");\n";
1900             }
1901             break;
1902         }
1903         case PASSTHROUGH_EXIT:
1904         {
1905             event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
1906             for (const auto &arg : method->results()) {
1907                 out << "_hidl_args.push_back((void *)&_hidl_out_"
1908                     << arg->name()
1909                     << ");\n";
1910             }
1911             break;
1912         }
1913         default:
1914         {
1915             CHECK(false) << "Unsupported instrumentation event: " << event;
1916         }
1917     }
1918 
1919     out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
1920     out.indent();
1921     out << "callback(" << event_str << ", \"" << superInterface->fqName().package() << "\", \""
1922         << superInterface->fqName().version() << "\", \"" << superInterface->definedName()
1923         << "\", \"" << method->name() << "\", &_hidl_args);\n";
1924     out.unindent();
1925     out << "}\n";
1926     out.unindent();
1927     out << "}\n";
1928     out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1929 }
1930 
1931 }  // namespace android
1932