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