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 << "¬ification);\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 << "¬ification) ";
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