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