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