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