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