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
1075 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
1076 out << klassName;
1077 out << "::descriptor);\n";
1078 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1079
1080 bool hasInterfaceArgument = false;
1081
1082 for (const auto &arg : method->args()) {
1083 if (arg->type().isInterface()) {
1084 hasInterfaceArgument = true;
1085 }
1086 emitCppReaderWriter(
1087 out,
1088 "_hidl_data",
1089 false /* parcelObjIsPointer */,
1090 arg,
1091 false /* reader */,
1092 Type::ErrorMode_Goto,
1093 false /* addPrefixToName */);
1094 }
1095
1096 if (hasInterfaceArgument) {
1097 // Start binder threadpool to handle incoming transactions
1098 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1099 }
1100 out << "_hidl_transact_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact("
1101 << method->getSerialId()
1102 << " /* "
1103 << method->name()
1104 << " */, _hidl_data, &_hidl_reply";
1105
1106 if (method->isOneway()) {
1107 out << ", " << Interface::FLAG_ONE_WAY->cppValue();
1108 } else {
1109 out << ", 0";
1110 }
1111
1112 if (hasCallback) {
1113 out << ", [&] (::android::hardware::Parcel& _hidl_reply) {\n";
1114 out.indent();
1115 declareCppReaderLocals(
1116 out, method->results(), true /* forResults */);
1117 out.endl();
1118 } else {
1119 out << ");\n";
1120 out << "if (_hidl_transact_err != ::android::OK) \n";
1121 out.block([&] {
1122 out << "_hidl_err = _hidl_transact_err;\n";
1123 out << "goto _hidl_error;\n";
1124 }).endl().endl();
1125 }
1126
1127 if (!method->isOneway()) {
1128 Type::ErrorMode errorMode = hasCallback ? Type::ErrorMode_ReturnNothing : Type::ErrorMode_Goto;
1129
1130 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
1131 Type::handleError(out, errorMode);
1132
1133 if (hasCallback) {
1134 out << "if (!_hidl_status.isOk()) { return; }\n\n";
1135 } else {
1136 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1137 }
1138
1139 for (const auto &arg : method->results()) {
1140 emitCppReaderWriter(
1141 out,
1142 "_hidl_reply",
1143 false /* parcelObjIsPointer */,
1144 arg,
1145 true /* reader */,
1146 errorMode,
1147 true /* addPrefixToName */);
1148 }
1149
1150 if (returnsValue && elidedReturn == nullptr) {
1151 out << "_hidl_cb(";
1152
1153 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
1154 if (arg->type().resultNeedsDeref()) {
1155 out << "*";
1156 }
1157 out << "_hidl_out_" << arg->name();
1158 });
1159
1160 out << ");\n\n";
1161 }
1162 }
1163
1164 generateCppInstrumentationCall(
1165 out,
1166 InstrumentationEvent::CLIENT_API_EXIT,
1167 method,
1168 superInterface);
1169
1170 if (hasCallback) {
1171 out.unindent();
1172 out << "});\n";
1173 out << "if (_hidl_transact_err != ::android::OK) ";
1174 out.block([&] {
1175 out << "_hidl_err = _hidl_transact_err;\n";
1176 out << "goto _hidl_error;\n";
1177 }).endl().endl();
1178 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n";
1179 }
1180
1181 if (elidedReturn != nullptr) {
1182 out << "return ::android::hardware::Return<";
1183 out << elidedReturn->type().getCppResultType()
1184 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1185 } else {
1186 out << "return ::android::hardware::Return<void>();\n\n";
1187 }
1188
1189 out.unindent();
1190 out << "_hidl_error:\n";
1191 out.indent();
1192 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1193 out << "return ::android::hardware::Return<";
1194 if (elidedReturn != nullptr) {
1195 out << method->results().at(0)->type().getCppResultType();
1196 } else {
1197 out << "void";
1198 }
1199 out << ">(_hidl_status);\n";
1200
1201 out.unindent();
1202 out << "}\n\n";
1203 }
1204
generateProxySource(Formatter & out,const FQName & fqName) const1205 void AST::generateProxySource(Formatter& out, const FQName& fqName) const {
1206 const std::string klassName = fqName.getInterfaceProxyName();
1207
1208 out << klassName
1209 << "::"
1210 << klassName
1211 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
1212
1213 out.indent();
1214 out.indent();
1215
1216 out << ": BpInterface"
1217 << "<"
1218 << fqName.getInterfaceName()
1219 << ">(_hidl_impl),\n"
1220 << " ::android::hardware::details::HidlInstrumentor(\""
1221 << mPackage.string()
1222 << "\", \""
1223 << fqName.getInterfaceName()
1224 << "\") {\n";
1225
1226 out.unindent();
1227 out.unindent();
1228 out << "}\n\n";
1229
1230 out << "void " << klassName << "::onLastStrongRef(const void* id) ";
1231 out.block([&] {
1232 out.block([&] {
1233 // if unlinkToDeath is not used, remove strong cycle between
1234 // this and hidl_binder_death_recipient
1235 out << "std::unique_lock<std::mutex> lock(_hidl_mMutex);\n";
1236 out << "_hidl_mDeathRecipients.clear();\n";
1237 }).endl().endl();
1238
1239 out << "BpInterface<" << fqName.getInterfaceName() << ">::onLastStrongRef(id);\n";
1240 }).endl();
1241
1242 generateMethods(out,
1243 [&](const Method* method, const Interface* superInterface) {
1244 generateStaticProxyMethodSource(out, klassName, method, superInterface);
1245 },
1246 false /* include parents */);
1247
1248 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1249 generateProxyMethodSource(out, klassName, method, superInterface);
1250 });
1251 }
1252
generateStubSource(Formatter & out,const Interface * iface) const1253 void AST::generateStubSource(Formatter& out, const Interface* iface) const {
1254 const std::string interfaceName = iface->definedName();
1255 const std::string klassName = iface->getStubName();
1256
1257 out << klassName
1258 << "::"
1259 << klassName
1260 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
1261
1262 out.indent();
1263 out.indent();
1264
1265 if (iface->isIBase()) {
1266 out << ": ::android::hardware::details::HidlInstrumentor(\"";
1267 } else {
1268 out << ": "
1269 << gIBaseFqName.getInterfaceStubFqName().cppName()
1270 << "(_hidl_impl, \"";
1271 }
1272
1273 out << mPackage.string()
1274 << "\", \""
1275 << interfaceName
1276 << "\") { \n";
1277 out.indent();
1278 out << "_hidl_mImpl = _hidl_impl;\n";
1279 out << "auto prio = ::android::hardware::getMinSchedulerPolicy(_hidl_impl);\n";
1280 out << "mSchedPolicy = prio.sched_policy;\n";
1281 out << "mSchedPriority = prio.prio;\n";
1282 out << "setRequestingSid(::android::hardware::getRequestingSid(_hidl_impl));\n";
1283 out.unindent();
1284
1285 out.unindent();
1286 out.unindent();
1287 out << "}\n\n";
1288
1289 if (iface->isIBase()) {
1290 // BnHwBase has a constructor to initialize the HidlInstrumentor
1291 // class properly.
1292 out << klassName
1293 << "::"
1294 << klassName
1295 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1296 << " const std::string &HidlInstrumentor_package,"
1297 << " const std::string &HidlInstrumentor_interface)\n";
1298
1299 out.indent();
1300 out.indent();
1301
1302 out << ": ::android::hardware::details::HidlInstrumentor("
1303 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
1304 out.indent();
1305 out << "_hidl_mImpl = _hidl_impl;\n";
1306 out.unindent();
1307
1308 out.unindent();
1309 out.unindent();
1310 out << "}\n\n";
1311 }
1312
1313 out << klassName << "::~" << klassName << "() ";
1314 out.block([&]() {
1315 out << "::android::hardware::details::gBnMap->eraseIfEqual(_hidl_mImpl.get(), this);\n";
1316 })
1317 .endl()
1318 .endl();
1319
1320 if (isIBase()) {
1321 out << "bool " << klassName << "::checkSubclass(const void* subclassID) const ";
1322 out.block([&] { out << "return subclassID == " << interfaceName << "::descriptor;\n"; });
1323 }
1324
1325 generateMethods(out,
1326 [&](const Method* method, const Interface* superInterface) {
1327 return generateStaticStubMethodSource(out, iface->fqName(), method, superInterface);
1328 },
1329 false /* include parents */);
1330
1331 generateMethods(out, [&](const Method* method, const Interface*) {
1332 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1333 return;
1334 }
1335 method->generateCppSignature(out, iface->getStubName());
1336 out << " ";
1337 out.block([&] {
1338 method->cppImpl(IMPL_STUB_IMPL, out);
1339 }).endl();
1340 });
1341
1342 out << "::android::status_t " << klassName << "::onTransact(\n";
1343
1344 out.indent();
1345 out.indent();
1346
1347 out << "uint32_t _hidl_code,\n"
1348 << "const ::android::hardware::Parcel &_hidl_data,\n"
1349 << "::android::hardware::Parcel *_hidl_reply,\n"
1350 << "uint32_t _hidl_flags,\n"
1351 << "TransactCallback _hidl_cb) {\n";
1352
1353 out.unindent();
1354
1355 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
1356 out << "switch (_hidl_code) {\n";
1357 out.indent();
1358
1359 for (const auto &tuple : iface->allMethodsFromRoot()) {
1360 const Method *method = tuple.method();
1361 const Interface *superInterface = tuple.interface();
1362
1363 if (!isIBase() && method->isHidlReserved()) {
1364 continue;
1365 }
1366 out << "case "
1367 << method->getSerialId()
1368 << " /* "
1369 << method->name()
1370 << " */:\n{\n";
1371
1372 out.indent();
1373
1374 generateStubSourceForMethod(out, method, superInterface);
1375
1376 out.unindent();
1377 out << "}\n\n";
1378 }
1379
1380 out << "default:\n{\n";
1381 out.indent();
1382
1383 if (iface->isIBase()) {
1384 out << "(void)_hidl_flags;\n";
1385 out << "return ::android::UNKNOWN_TRANSACTION;\n";
1386 } else {
1387 out << "return ";
1388 out << gIBaseFqName.getInterfaceStubFqName().cppName();
1389 out << "::onTransact(\n";
1390
1391 out.indent();
1392 out.indent();
1393
1394 out << "_hidl_code, _hidl_data, _hidl_reply, "
1395 << "_hidl_flags, _hidl_cb);\n";
1396
1397 out.unindent();
1398 out.unindent();
1399 }
1400
1401 out.unindent();
1402 out << "}\n";
1403
1404 out.unindent();
1405 out << "}\n\n";
1406
1407 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1408 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1409 out.indent(2, [&] {
1410 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1411 out << "_hidl_reply);\n";
1412 });
1413 });
1414
1415 out << "return _hidl_err;\n";
1416
1417 out.unindent();
1418 out << "}\n\n";
1419 }
1420
generateStubSourceForMethod(Formatter & out,const Method * method,const Interface * superInterface) const1421 void AST::generateStubSourceForMethod(Formatter& out, const Method* method,
1422 const Interface* superInterface) const {
1423 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1424 method->cppImpl(IMPL_STUB, out);
1425 out << "break;\n";
1426 return;
1427 }
1428
1429 out << "_hidl_err = "
1430 << superInterface->fqName().cppNamespace()
1431 << "::"
1432 << superInterface->getStubName()
1433 << "::_hidl_"
1434 << method->name()
1435 << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
1436 out << "break;\n";
1437 }
1438
generateStaticStubMethodSource(Formatter & out,const FQName & fqName,const Method * method,const Interface * superInterface) const1439 void AST::generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
1440 const Method* method, const Interface* superInterface) const {
1441 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1442 return;
1443 }
1444
1445 const std::string& klassName = fqName.getInterfaceStubName();
1446
1447 out << "::android::status_t " << klassName << "::_hidl_" << method->name() << "(\n";
1448
1449 out.indent();
1450 out.indent();
1451
1452 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
1453 << "const ::android::hardware::Parcel &_hidl_data,\n"
1454 << "::android::hardware::Parcel *_hidl_reply,\n"
1455 << "TransactCallback _hidl_cb) {\n";
1456
1457 out.unindent();
1458
1459 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1460 out << "bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();\n";
1461 out << "const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();\n";
1462 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1463
1464 out << "::android::status_t _hidl_err = ::android::OK;\n";
1465
1466 out << "if (!_hidl_data.enforceInterface("
1467 << klassName
1468 << "::Pure::descriptor)) {\n";
1469
1470 out.indent();
1471 out << "_hidl_err = ::android::BAD_TYPE;\n";
1472 out << "return _hidl_err;\n";
1473 out.unindent();
1474 out << "}\n\n";
1475
1476 declareCppReaderLocals(out, method->args(), false /* forResults */);
1477
1478 for (const auto &arg : method->args()) {
1479 emitCppReaderWriter(
1480 out,
1481 "_hidl_data",
1482 false /* parcelObjIsPointer */,
1483 arg,
1484 true /* reader */,
1485 Type::ErrorMode_Return,
1486 false /* addPrefixToName */);
1487 }
1488
1489 generateCppInstrumentationCall(
1490 out,
1491 InstrumentationEvent::SERVER_API_ENTRY,
1492 method,
1493 superInterface);
1494
1495 const bool returnsValue = !method->results().empty();
1496 const NamedReference<Type>* elidedReturn = method->canElideCallback();
1497
1498 std::string callee;
1499
1500 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL)) {
1501 callee = "_hidl_this";
1502 } else {
1503 callee = "static_cast<" + fqName.getInterfaceName() + "*>(_hidl_this->getImpl().get())";
1504 }
1505
1506 if (elidedReturn != nullptr) {
1507 out << elidedReturn->type().getCppResultType()
1508 << " _hidl_out_"
1509 << elidedReturn->name()
1510 << " = "
1511 << callee << "->" << method->name()
1512 << "(";
1513
1514 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
1515 if (arg->type().resultNeedsDeref()) {
1516 out << "*";
1517 }
1518 out << arg->name();
1519 });
1520
1521 out << ");\n\n";
1522
1523 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1524 << "_hidl_reply);\n\n";
1525
1526 elidedReturn->type().emitReaderWriter(
1527 out,
1528 "_hidl_out_" + elidedReturn->name(),
1529 "_hidl_reply",
1530 true, /* parcelObjIsPointer */
1531 false, /* isReader */
1532 Type::ErrorMode_Goto);
1533
1534 out.unindent();
1535 out << "_hidl_error:\n";
1536 out.indent();
1537
1538 generateCppInstrumentationCall(
1539 out,
1540 InstrumentationEvent::SERVER_API_EXIT,
1541 method,
1542 superInterface);
1543
1544 out << "if (_hidl_err != ::android::OK) { return _hidl_err; }\n";
1545 out << "_hidl_cb(*_hidl_reply);\n";
1546 } else {
1547 if (returnsValue) {
1548 out << "bool _hidl_callbackCalled = false;\n\n";
1549 }
1550
1551 out << "::android::hardware::Return<void> _hidl_ret = " << callee << "->" << method->name()
1552 << "(";
1553
1554 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
1555 if (arg->type().resultNeedsDeref()) {
1556 out << "*";
1557 }
1558
1559 out << arg->name();
1560 });
1561
1562 if (returnsValue) {
1563 if (!method->args().empty()) {
1564 out << ", ";
1565 }
1566
1567 out << "[&](";
1568
1569 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
1570 out << "const auto &_hidl_out_" << arg->name();
1571 });
1572
1573 out << ") {\n";
1574 out.indent();
1575 out << "if (_hidl_callbackCalled) {\n";
1576 out.indent();
1577 out << "LOG_ALWAYS_FATAL(\""
1578 << method->name()
1579 << ": _hidl_cb called a second time, but must be called once.\");\n";
1580 out.unindent();
1581 out << "}\n";
1582 out << "_hidl_callbackCalled = true;\n\n";
1583
1584 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1585 << "_hidl_reply);\n\n";
1586
1587 for (const auto &arg : method->results()) {
1588 emitCppReaderWriter(
1589 out,
1590 "_hidl_reply",
1591 true /* parcelObjIsPointer */,
1592 arg,
1593 false /* reader */,
1594 Type::ErrorMode_Goto,
1595 true /* addPrefixToName */);
1596 }
1597
1598 if (!method->results().empty()) {
1599 out.unindent();
1600 out << "_hidl_error:\n";
1601 out.indent();
1602 }
1603
1604 generateCppInstrumentationCall(
1605 out,
1606 InstrumentationEvent::SERVER_API_EXIT,
1607 method,
1608 superInterface);
1609
1610 out << "if (_hidl_err != ::android::OK) { return; }\n";
1611 out << "_hidl_cb(*_hidl_reply);\n";
1612
1613 out.unindent();
1614 out << "});\n\n";
1615 } else {
1616 out << ");\n\n";
1617 out << "(void) _hidl_cb;\n\n";
1618 generateCppInstrumentationCall(
1619 out,
1620 InstrumentationEvent::SERVER_API_EXIT,
1621 method,
1622 superInterface);
1623 }
1624
1625 out << "_hidl_ret.assertOk();\n";
1626
1627 if (returnsValue) {
1628 out << "if (!_hidl_callbackCalled) {\n";
1629 out.indent();
1630 out << "LOG_ALWAYS_FATAL(\""
1631 << method->name()
1632 << ": _hidl_cb not called, but must be called once.\");\n";
1633 out.unindent();
1634 out << "}\n\n";
1635 } else {
1636 out << "::android::hardware::writeToParcel("
1637 << "::android::hardware::Status::ok(), "
1638 << "_hidl_reply);\n\n";
1639 }
1640 }
1641
1642 out << "return _hidl_err;\n";
1643 out.unindent();
1644 out << "}\n\n";
1645 }
1646
generatePassthroughHeader(Formatter & out) const1647 void AST::generatePassthroughHeader(Formatter& out) const {
1648 if (!AST::isInterface()) {
1649 // types.hal does not get a stub header.
1650 return;
1651 }
1652
1653 const Interface* iface = mRootScope.getInterface();
1654 CHECK(iface != nullptr);
1655
1656 const std::string klassName = iface->getPassthroughName();
1657
1658 const std::string guard = makeHeaderGuard(klassName);
1659
1660 out << "#ifndef " << guard << "\n";
1661 out << "#define " << guard << "\n\n";
1662
1663 out << "#include <android-base/macros.h>\n";
1664 out << "#include <cutils/trace.h>\n";
1665 out << "#include <future>\n";
1666
1667 generateCppPackageInclude(out, mPackage, iface->definedName());
1668 out << "\n";
1669
1670 out << "#include <hidl/HidlPassthroughSupport.h>\n";
1671 out << "#include <hidl/TaskRunner.h>\n";
1672
1673 enterLeaveNamespace(out, true /* enter */);
1674 out << "\n";
1675
1676 out << "struct " << klassName << " : " << iface->definedName()
1677 << ", ::android::hardware::details::HidlInstrumentor {\n";
1678
1679 out.indent();
1680 out << "explicit " << klassName << "(const ::android::sp<" << iface->definedName()
1681 << "> impl);\n";
1682
1683 out.endl();
1684 generateTemplatizationLink(out);
1685 generateCppTag(out, "::android::hardware::details::bs_tag");
1686
1687 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1688 generatePassthroughMethod(out, method, superInterface);
1689 });
1690
1691 out.unindent();
1692 out << "private:\n";
1693 out.indent();
1694 out << "const ::android::sp<" << iface->definedName() << "> mImpl;\n";
1695
1696 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
1697
1698 out << "\n";
1699
1700 out << "::android::hardware::Return<void> addOnewayTask("
1701 "std::function<void(void)>);\n\n";
1702
1703 out.unindent();
1704
1705 out << "};\n\n";
1706
1707 enterLeaveNamespace(out, false /* enter */);
1708
1709 out << "\n#endif // " << guard << "\n";
1710 }
1711
generateInterfaceSource(Formatter & out) const1712 void AST::generateInterfaceSource(Formatter& out) const {
1713 const Interface* iface = mRootScope.getInterface();
1714
1715 // generate castFrom functions
1716 std::string childTypeResult = iface->getCppResultType();
1717
1718 generateMethods(out, [&](const Method* method, const Interface*) {
1719 bool reserved = method->isHidlReserved();
1720
1721 if (!reserved) {
1722 out << "// no default implementation for: ";
1723 }
1724 method->generateCppSignature(out, iface->definedName());
1725 if (reserved) {
1726 out.block([&]() {
1727 method->cppImpl(IMPL_INTERFACE, out);
1728 }).endl();
1729 }
1730
1731 out << "\n";
1732
1733 return;
1734 });
1735
1736 for (const Interface *superType : iface->typeChain()) {
1737 out << "::android::hardware::Return<" << childTypeResult << "> " << iface->definedName()
1738 << "::castFrom(" << superType->getCppArgumentType() << " parent, bool "
1739 << (iface == superType ? "/* emitError */" : "emitError") << ") {\n";
1740 out.indent();
1741 if (iface == superType) {
1742 out << "return parent;\n";
1743 } else {
1744 out << "return ::android::hardware::details::castInterface<";
1745 out << iface->definedName() << ", " << superType->fqName().cppName() << ", "
1746 << iface->getProxyName() << ">(\n";
1747 out.indent();
1748 out.indent();
1749 out << "parent, \""
1750 << iface->fqName().string()
1751 << "\", emitError);\n";
1752 out.unindent();
1753 out.unindent();
1754 }
1755 out.unindent();
1756 out << "}\n\n";
1757 }
1758 }
1759
generatePassthroughSource(Formatter & out) const1760 void AST::generatePassthroughSource(Formatter& out) const {
1761 const Interface* iface = mRootScope.getInterface();
1762
1763 const std::string klassName = iface->getPassthroughName();
1764
1765 out << klassName << "::" << klassName << "(const ::android::sp<" << iface->fullName()
1766 << "> impl) : ::android::hardware::details::HidlInstrumentor(\"" << mPackage.string()
1767 << "\", \"" << iface->definedName() << "\"), mImpl(impl) {\n";
1768
1769 out.indent([&] { out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n"; });
1770
1771 out << "}\n\n";
1772
1773 out << "::android::hardware::Return<void> " << klassName
1774 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1775 out.indent();
1776 out << "if (!mOnewayQueue.push(fun)) {\n";
1777 out.indent();
1778 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1779 out.indent();
1780 out.indent();
1781 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
1782 << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
1783 out.unindent();
1784 out.unindent();
1785 out.unindent();
1786 out << "}\n";
1787
1788 out << "return ::android::hardware::Status();\n";
1789
1790 out.unindent();
1791 out << "}\n\n";
1792 }
1793
generateCppAtraceCall(Formatter & out,InstrumentationEvent event,const Method * method) const1794 void AST::generateCppAtraceCall(Formatter &out,
1795 InstrumentationEvent event,
1796 const Method *method) const {
1797 const Interface* iface = mRootScope.getInterface();
1798 std::string baseString = "HIDL::" + iface->definedName() + "::" + method->name();
1799 switch (event) {
1800 case SERVER_API_ENTRY:
1801 {
1802 out << "atrace_begin(ATRACE_TAG_HAL, \""
1803 << baseString + "::server\");\n";
1804 break;
1805 }
1806 case PASSTHROUGH_ENTRY:
1807 {
1808 out << "atrace_begin(ATRACE_TAG_HAL, \""
1809 << baseString + "::passthrough\");\n";
1810 break;
1811 }
1812 case SERVER_API_EXIT:
1813 case PASSTHROUGH_EXIT:
1814 {
1815 out << "atrace_end(ATRACE_TAG_HAL);\n";
1816 break;
1817 }
1818 // client uses scope because of gotos
1819 // this isn't done for server because the profiled code isn't alone in its scope
1820 // this isn't done for passthrough becuase the profiled boundary isn't even in the same code
1821 case CLIENT_API_ENTRY: {
1822 out << "::android::ScopedTrace PASTE(___tracer, __LINE__) (ATRACE_TAG_HAL, \""
1823 << baseString + "::client\");\n";
1824 break;
1825 }
1826 case CLIENT_API_EXIT:
1827 break;
1828 default:
1829 {
1830 CHECK(false) << "Unsupported instrumentation event: " << event;
1831 }
1832 }
1833 }
1834
generateCppInstrumentationCall(Formatter & out,InstrumentationEvent event,const Method * method,const Interface * superInterface) const1835 void AST::generateCppInstrumentationCall(
1836 Formatter &out,
1837 InstrumentationEvent event,
1838 const Method *method,
1839 const Interface* superInterface) const {
1840 generateCppAtraceCall(out, event, method);
1841
1842 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1843 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1844 out.indent();
1845 out << "std::vector<void *> _hidl_args;\n";
1846 std::string event_str = "";
1847 switch (event) {
1848 case SERVER_API_ENTRY:
1849 {
1850 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1851 for (const auto &arg : method->args()) {
1852 out << "_hidl_args.push_back((void *)"
1853 << (arg->type().resultNeedsDeref() ? "" : "&")
1854 << arg->name()
1855 << ");\n";
1856 }
1857 break;
1858 }
1859 case SERVER_API_EXIT:
1860 {
1861 event_str = "InstrumentationEvent::SERVER_API_EXIT";
1862 for (const auto &arg : method->results()) {
1863 out << "_hidl_args.push_back((void *)&_hidl_out_"
1864 << arg->name()
1865 << ");\n";
1866 }
1867 break;
1868 }
1869 case CLIENT_API_ENTRY:
1870 {
1871 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1872 for (const auto &arg : method->args()) {
1873 out << "_hidl_args.push_back((void *)&"
1874 << arg->name()
1875 << ");\n";
1876 }
1877 break;
1878 }
1879 case CLIENT_API_EXIT:
1880 {
1881 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1882 for (const auto &arg : method->results()) {
1883 out << "_hidl_args.push_back((void *)"
1884 << (arg->type().resultNeedsDeref() ? "" : "&")
1885 << "_hidl_out_"
1886 << arg->name()
1887 << ");\n";
1888 }
1889 break;
1890 }
1891 case PASSTHROUGH_ENTRY:
1892 {
1893 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1894 for (const auto &arg : method->args()) {
1895 out << "_hidl_args.push_back((void *)&"
1896 << arg->name()
1897 << ");\n";
1898 }
1899 break;
1900 }
1901 case PASSTHROUGH_EXIT:
1902 {
1903 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
1904 for (const auto &arg : method->results()) {
1905 out << "_hidl_args.push_back((void *)&_hidl_out_"
1906 << arg->name()
1907 << ");\n";
1908 }
1909 break;
1910 }
1911 default:
1912 {
1913 CHECK(false) << "Unsupported instrumentation event: " << event;
1914 }
1915 }
1916
1917 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
1918 out.indent();
1919 out << "callback(" << event_str << ", \"" << superInterface->fqName().package() << "\", \""
1920 << superInterface->fqName().version() << "\", \"" << superInterface->definedName()
1921 << "\", \"" << method->name() << "\", &_hidl_args);\n";
1922 out.unindent();
1923 out << "}\n";
1924 out.unindent();
1925 out << "}\n";
1926 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1927 }
1928
1929 } // namespace android
1930