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 generateMethods(out,
694 [&](const Method* method, const Interface*) {
695 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
696 return;
697 }
698
699 out << "static ::android::status_t _hidl_" << method->name() << "(\n";
700
701 out.indent(2,
702 [&] {
703 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
704 << "const ::android::hardware::Parcel &_hidl_data,\n"
705 << "::android::hardware::Parcel *_hidl_reply,\n"
706 << "TransactCallback _hidl_cb);\n";
707 })
708 .endl()
709 .endl();
710 },
711 false /* include parents */);
712
713 out.unindent();
714 out << "private:\n";
715 out.indent();
716
717 generateMethods(out, [&](const Method* method, const Interface* iface) {
718 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
719 return;
720 }
721 const bool returnsValue = !method->results().empty();
722 const NamedReference<Type>* elidedReturn = method->canElideCallback();
723
724 if (elidedReturn == nullptr && returnsValue) {
725 out << "using " << method->name() << "_cb = "
726 << iface->fqName().cppName()
727 << "::" << method->name() << "_cb;\n";
728 }
729 method->generateCppSignature(out);
730 out << ";\n";
731 });
732
733 out << "::android::sp<" << iface->definedName() << "> _hidl_mImpl;\n";
734 out.unindent();
735 out << "};\n\n";
736
737 enterLeaveNamespace(out, false /* enter */);
738
739 out << "\n#endif // " << guard << "\n";
740 }
741
generateProxyHeader(Formatter & out) const742 void AST::generateProxyHeader(Formatter& out) const {
743 if (!AST::isInterface()) {
744 // types.hal does not get a proxy header.
745 return;
746 }
747
748 const Interface* iface = mRootScope.getInterface();
749 const std::string proxyName = iface->getProxyName();
750 const std::string guard = makeHeaderGuard(proxyName);
751
752 out << "#ifndef " << guard << "\n";
753 out << "#define " << guard << "\n\n";
754
755 out << "#include <hidl/HidlTransportSupport.h>\n\n";
756
757 generateCppPackageInclude(out, mPackage, iface->getHwName());
758 out << "\n";
759
760 enterLeaveNamespace(out, true /* enter */);
761 out << "\n";
762
763 out << "struct " << proxyName << " : public ::android::hardware::BpInterface<"
764 << iface->definedName() << ">, public ::android::hardware::details::HidlInstrumentor {\n";
765
766 out.indent();
767
768 out << "explicit "
769 << proxyName
770 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
771 << "\n\n";
772
773 generateTemplatizationLink(out);
774 DocComment("Type tag for use in template logic that indicates this is a 'proxy' class.",
775 HIDL_LOCATION_HERE)
776 .emit(out);
777 generateCppTag(out, "::android::hardware::details::bphw_tag");
778
779 out << "virtual bool isRemote() const override { return true; }\n\n";
780
781 out << "void onLastStrongRef(const void* id) override;\n\n";
782
783 generateMethods(
784 out,
785 [&](const Method* method, const Interface*) {
786 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
787 return;
788 }
789
790 out << "static ";
791 method->generateCppReturnType(out);
792 out << " _hidl_" << method->name() << "("
793 << "::android::hardware::IInterface* _hidl_this, "
794 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
795
796 if (!method->hasEmptyCppArgSignature()) {
797 out << ", ";
798 }
799 method->emitCppArgSignature(out);
800 out << ");\n";
801 },
802 false /* include parents */);
803
804 generateMethods(out, [&](const Method* method, const Interface*) {
805 method->generateCppSignature(out);
806 out << " override;\n";
807 });
808
809 out.unindent();
810 out << "private:\n";
811 out.indent();
812 out << "std::mutex _hidl_mMutex;\n"
813 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
814 << " _hidl_mDeathRecipients;\n";
815 out.unindent();
816 out << "};\n\n";
817
818 enterLeaveNamespace(out, false /* enter */);
819
820 out << "\n#endif // " << guard << "\n";
821 }
822
generateCppSource(Formatter & out) const823 void AST::generateCppSource(Formatter& out) const {
824 std::string baseName = getBaseName();
825 const Interface *iface = getInterface();
826
827 const std::string klassName = baseName + (baseName == "types" ? "" : "All");
828
829 out << "#define LOG_TAG \""
830 << mPackage.string() << "::" << baseName
831 << "\"\n\n";
832
833 out << "#include <log/log.h>\n";
834 out << "#include <cutils/trace.h>\n";
835 out << "#include <hidl/HidlTransportSupport.h>\n\n";
836 out << "#include <hidl/Static.h>\n";
837 out << "#include <hwbinder/ProcessState.h>\n";
838 out << "#include <utils/Trace.h>\n";
839 if (iface) {
840 // This is a no-op for IServiceManager itself.
841 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
842
843 generateCppPackageInclude(out, mPackage, iface->getProxyName());
844 generateCppPackageInclude(out, mPackage, iface->getStubName());
845 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
846
847 for (const Interface *superType : iface->superTypeChain()) {
848 generateCppPackageInclude(out,
849 superType->fqName(),
850 superType->fqName().getInterfaceProxyName());
851 }
852
853 out << "#include <hidl/ServiceManagement.h>\n";
854 } else {
855 generateCppPackageInclude(out, mPackage, "types");
856 generateCppPackageInclude(out, mPackage, "hwtypes");
857 }
858
859 out << "\n";
860
861 enterLeaveNamespace(out, true /* enter */);
862 out << "\n";
863
864 generateTypeSource(out, iface ? iface->definedName() : "");
865
866 if (iface) {
867 const Interface* iface = mRootScope.getInterface();
868
869 // need to be put here, generateStubSource is using this.
870 out << "const char* " << iface->definedName() << "::descriptor(\""
871 << iface->fqName().string() << "\");\n\n";
872 out << "__attribute__((constructor)) ";
873 out << "static void static_constructor() {\n";
874 out.indent([&] {
875 out << "::android::hardware::details::getBnConstructorMap().set("
876 << iface->definedName() << "::descriptor,\n";
877 out.indent(2, [&] {
878 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
879 out.indent([&] {
880 out << "return new " << iface->getStubName() << "(static_cast<"
881 << iface->definedName() << " *>(iIntf));\n";
882 });
883 out << "});\n";
884 });
885 out << "::android::hardware::details::getBsConstructorMap().set("
886 << iface->definedName() << "::descriptor,\n";
887 out.indent(2, [&] {
888 out << "[](void *iIntf) -> ::android::sp<"
889 << gIBaseFqName.cppName()
890 << "> {\n";
891 out.indent([&] {
892 out << "return new " << iface->getPassthroughName() << "(static_cast<"
893 << iface->definedName() << " *>(iIntf));\n";
894 });
895 out << "});\n";
896 });
897 });
898 out << "}\n\n";
899 out << "__attribute__((destructor))";
900 out << "static void static_destructor() {\n";
901 out.indent([&] {
902 out << "::android::hardware::details::getBnConstructorMap().erase("
903 << iface->definedName() << "::descriptor);\n";
904 out << "::android::hardware::details::getBsConstructorMap().erase("
905 << iface->definedName() << "::descriptor);\n";
906 });
907 out << "}\n\n";
908
909 generateInterfaceSource(out);
910 generateProxySource(out, iface->fqName());
911 generateStubSource(out, iface);
912 generatePassthroughSource(out);
913
914 if (isIBase()) {
915 out << "// skipped getService, registerAsService, registerForNotifications\n";
916 } else {
917 std::string package = iface->fqName().package()
918 + iface->fqName().atVersion();
919
920 implementServiceManagerInteractions(out, iface->fqName(), package);
921 }
922 }
923
924 HidlTypeAssertion::EmitAll(out);
925 out << "\n";
926
927 enterLeaveNamespace(out, false /* enter */);
928 }
929
generateTypeSource(Formatter & out,const std::string & ifaceName) const930 void AST::generateTypeSource(Formatter& out, const std::string& ifaceName) const {
931 mRootScope.emitTypeDefinitions(out, ifaceName);
932 }
933
declareCppReaderLocals(Formatter & out,const std::vector<NamedReference<Type> * > & args,bool forResults) const934 void AST::declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& args,
935 bool forResults) const {
936 if (args.empty()) {
937 return;
938 }
939
940 for (const auto &arg : args) {
941 const Type &type = arg->type();
942
943 out << type.getCppResultType()
944 << " "
945 << (forResults ? "_hidl_out_" : "") + arg->name()
946 << ";\n";
947 }
948
949 out << "\n";
950 }
951
emitCppReaderWriter(Formatter & out,const std::string & parcelObj,bool parcelObjIsPointer,const NamedReference<Type> * arg,bool isReader,Type::ErrorMode mode,bool addPrefixToName) const952 void AST::emitCppReaderWriter(Formatter& out, const std::string& parcelObj, bool parcelObjIsPointer,
953 const NamedReference<Type>* arg, bool isReader, Type::ErrorMode mode,
954 bool addPrefixToName) const {
955 const Type &type = arg->type();
956
957 type.emitReaderWriter(
958 out,
959 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
960 parcelObj,
961 parcelObjIsPointer,
962 isReader,
963 mode);
964 }
965
generateProxyMethodSource(Formatter & out,const std::string & klassName,const Method * method,const Interface * superInterface) const966 void AST::generateProxyMethodSource(Formatter& out, const std::string& klassName,
967 const Method* method, const Interface* superInterface) const {
968 method->generateCppSignature(out,
969 klassName,
970 true /* specify namespaces */);
971
972 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
973 out.block([&] {
974 method->cppImpl(IMPL_PROXY, out);
975 }).endl().endl();
976 return;
977 }
978
979 out.block([&] {
980 const bool returnsValue = !method->results().empty();
981 const NamedReference<Type>* elidedReturn = method->canElideCallback();
982
983 method->generateCppReturnType(out);
984
985 out << " _hidl_out = "
986 << superInterface->fqName().cppNamespace()
987 << "::"
988 << superInterface->getProxyName()
989 << "::_hidl_"
990 << method->name()
991 << "(this, this";
992
993 if (!method->hasEmptyCppArgSignature()) {
994 out << ", ";
995 }
996
997 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
998 out << arg->name();
999 });
1000
1001 if (returnsValue && elidedReturn == nullptr) {
1002 if (!method->args().empty()) {
1003 out << ", ";
1004 }
1005 out << "_hidl_cb";
1006 }
1007
1008 out << ");\n\n";
1009
1010 out << "return _hidl_out;\n";
1011 }).endl().endl();
1012 }
1013
generateStaticProxyMethodSource(Formatter & out,const std::string & klassName,const Method * method,const Interface * superInterface) const1014 void AST::generateStaticProxyMethodSource(Formatter& out, const std::string& klassName,
1015 const Method* method, const Interface* superInterface) const {
1016 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1017 return;
1018 }
1019
1020 method->generateCppReturnType(out);
1021
1022 out << klassName
1023 << "::_hidl_"
1024 << method->name()
1025 << "("
1026 << "::android::hardware::IInterface *_hidl_this, "
1027 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
1028
1029 if (!method->hasEmptyCppArgSignature()) {
1030 out << ", ";
1031 }
1032
1033 method->emitCppArgSignature(out);
1034 out << ") {\n";
1035
1036 out.indent();
1037
1038 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1039 out << "bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();\n";
1040 out << "const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();\n";
1041 out << "#else\n";
1042 out << "(void) _hidl_this_instrumentor;\n";
1043 out << "#endif // __ANDROID_DEBUGGABLE__\n";
1044
1045 const bool returnsValue = !method->results().empty();
1046 const NamedReference<Type>* elidedReturn = method->canElideCallback();
1047 const bool hasCallback = returnsValue && elidedReturn == nullptr;
1048
1049 generateCppInstrumentationCall(
1050 out,
1051 InstrumentationEvent::CLIENT_API_ENTRY,
1052 method,
1053 superInterface);
1054
1055 out << "::android::hardware::Parcel _hidl_data;\n";
1056 out << "::android::hardware::Parcel _hidl_reply;\n";
1057 out << "::android::status_t _hidl_err;\n";
1058 out << "::android::status_t _hidl_transact_err;\n";
1059 out << "::android::hardware::Status _hidl_status;\n\n";
1060
1061 if (!hasCallback) {
1062 declareCppReaderLocals(
1063 out, method->results(), true /* forResults */);
1064 }
1065
1066 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
1067 out << klassName;
1068 out << "::descriptor);\n";
1069 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1070
1071 bool hasInterfaceArgument = false;
1072
1073 for (const auto &arg : method->args()) {
1074 if (arg->type().isInterface()) {
1075 hasInterfaceArgument = true;
1076 }
1077 emitCppReaderWriter(
1078 out,
1079 "_hidl_data",
1080 false /* parcelObjIsPointer */,
1081 arg,
1082 false /* reader */,
1083 Type::ErrorMode_Goto,
1084 false /* addPrefixToName */);
1085 }
1086
1087 if (hasInterfaceArgument) {
1088 // Start binder threadpool to handle incoming transactions
1089 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1090 }
1091 out << "_hidl_transact_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact("
1092 << method->getSerialId()
1093 << " /* "
1094 << method->name()
1095 << " */, _hidl_data, &_hidl_reply";
1096
1097 if (method->isOneway()) {
1098 out << ", " << Interface::FLAG_ONE_WAY->cppValue();
1099 } else {
1100 out << ", 0";
1101 }
1102
1103 if (hasCallback) {
1104 out << ", [&] (::android::hardware::Parcel& _hidl_reply) {\n";
1105 out.indent();
1106 declareCppReaderLocals(
1107 out, method->results(), true /* forResults */);
1108 out.endl();
1109 } else {
1110 out << ");\n";
1111 out << "if (_hidl_transact_err != ::android::OK) \n";
1112 out.block([&] {
1113 out << "_hidl_err = _hidl_transact_err;\n";
1114 out << "goto _hidl_error;\n";
1115 }).endl().endl();
1116 }
1117
1118 if (!method->isOneway()) {
1119 Type::ErrorMode errorMode = hasCallback ? Type::ErrorMode_ReturnNothing : Type::ErrorMode_Goto;
1120
1121 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
1122 Type::handleError(out, errorMode);
1123
1124 if (hasCallback) {
1125 out << "if (!_hidl_status.isOk()) { return; }\n\n";
1126 } else {
1127 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1128 }
1129
1130 for (const auto &arg : method->results()) {
1131 emitCppReaderWriter(
1132 out,
1133 "_hidl_reply",
1134 false /* parcelObjIsPointer */,
1135 arg,
1136 true /* reader */,
1137 errorMode,
1138 true /* addPrefixToName */);
1139 }
1140
1141 if (returnsValue && elidedReturn == nullptr) {
1142 out << "_hidl_cb(";
1143
1144 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
1145 if (arg->type().resultNeedsDeref()) {
1146 out << "*";
1147 }
1148 out << "_hidl_out_" << arg->name();
1149 });
1150
1151 out << ");\n\n";
1152 }
1153 }
1154
1155 generateCppInstrumentationCall(
1156 out,
1157 InstrumentationEvent::CLIENT_API_EXIT,
1158 method,
1159 superInterface);
1160
1161 if (hasCallback) {
1162 out.unindent();
1163 out << "});\n";
1164 out << "if (_hidl_transact_err != ::android::OK) ";
1165 out.block([&] {
1166 out << "_hidl_err = _hidl_transact_err;\n";
1167 out << "goto _hidl_error;\n";
1168 }).endl().endl();
1169 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n";
1170 }
1171
1172 if (elidedReturn != nullptr) {
1173 out << "return ::android::hardware::Return<";
1174 out << elidedReturn->type().getCppResultType()
1175 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1176 } else {
1177 out << "return ::android::hardware::Return<void>();\n\n";
1178 }
1179
1180 out.unindent();
1181 out << "_hidl_error:\n";
1182 out.indent();
1183 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1184 out << "return ::android::hardware::Return<";
1185 if (elidedReturn != nullptr) {
1186 out << method->results().at(0)->type().getCppResultType();
1187 } else {
1188 out << "void";
1189 }
1190 out << ">(_hidl_status);\n";
1191
1192 out.unindent();
1193 out << "}\n\n";
1194 }
1195
generateProxySource(Formatter & out,const FQName & fqName) const1196 void AST::generateProxySource(Formatter& out, const FQName& fqName) const {
1197 const std::string klassName = fqName.getInterfaceProxyName();
1198
1199 out << klassName
1200 << "::"
1201 << klassName
1202 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
1203
1204 out.indent();
1205 out.indent();
1206
1207 out << ": BpInterface"
1208 << "<"
1209 << fqName.getInterfaceName()
1210 << ">(_hidl_impl),\n"
1211 << " ::android::hardware::details::HidlInstrumentor(\""
1212 << mPackage.string()
1213 << "\", \""
1214 << fqName.getInterfaceName()
1215 << "\") {\n";
1216
1217 out.unindent();
1218 out.unindent();
1219 out << "}\n\n";
1220
1221 out << "void " << klassName << "::onLastStrongRef(const void* id) ";
1222 out.block([&] {
1223 out.block([&] {
1224 // if unlinkToDeath is not used, remove strong cycle between
1225 // this and hidl_binder_death_recipient
1226 out << "std::unique_lock<std::mutex> lock(_hidl_mMutex);\n";
1227 out << "_hidl_mDeathRecipients.clear();\n";
1228 }).endl().endl();
1229
1230 out << "BpInterface<" << fqName.getInterfaceName() << ">::onLastStrongRef(id);\n";
1231 }).endl();
1232
1233 generateMethods(out,
1234 [&](const Method* method, const Interface* superInterface) {
1235 generateStaticProxyMethodSource(out, klassName, method, superInterface);
1236 },
1237 false /* include parents */);
1238
1239 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1240 generateProxyMethodSource(out, klassName, method, superInterface);
1241 });
1242 }
1243
generateStubSource(Formatter & out,const Interface * iface) const1244 void AST::generateStubSource(Formatter& out, const Interface* iface) const {
1245 const std::string interfaceName = iface->definedName();
1246 const std::string klassName = iface->getStubName();
1247
1248 out << klassName
1249 << "::"
1250 << klassName
1251 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
1252
1253 out.indent();
1254 out.indent();
1255
1256 if (iface->isIBase()) {
1257 out << ": ::android::hardware::details::HidlInstrumentor(\"";
1258 } else {
1259 out << ": "
1260 << gIBaseFqName.getInterfaceStubFqName().cppName()
1261 << "(_hidl_impl, \"";
1262 }
1263
1264 out << mPackage.string()
1265 << "\", \""
1266 << interfaceName
1267 << "\") { \n";
1268 out.indent();
1269 out << "_hidl_mImpl = _hidl_impl;\n";
1270 out << "auto prio = ::android::hardware::getMinSchedulerPolicy(_hidl_impl);\n";
1271 out << "mSchedPolicy = prio.sched_policy;\n";
1272 out << "mSchedPriority = prio.prio;\n";
1273 out << "setRequestingSid(::android::hardware::getRequestingSid(_hidl_impl));\n";
1274 out.unindent();
1275
1276 out.unindent();
1277 out.unindent();
1278 out << "}\n\n";
1279
1280 if (iface->isIBase()) {
1281 // BnHwBase has a constructor to initialize the HidlInstrumentor
1282 // class properly.
1283 out << klassName
1284 << "::"
1285 << klassName
1286 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1287 << " const std::string &HidlInstrumentor_package,"
1288 << " const std::string &HidlInstrumentor_interface)\n";
1289
1290 out.indent();
1291 out.indent();
1292
1293 out << ": ::android::hardware::details::HidlInstrumentor("
1294 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
1295 out.indent();
1296 out << "_hidl_mImpl = _hidl_impl;\n";
1297 out.unindent();
1298
1299 out.unindent();
1300 out.unindent();
1301 out << "}\n\n";
1302 }
1303
1304 out << klassName << "::~" << klassName << "() ";
1305 out.block([&]() {
1306 out << "::android::hardware::details::gBnMap->eraseIfEqual(_hidl_mImpl.get(), this);\n";
1307 })
1308 .endl()
1309 .endl();
1310
1311 generateMethods(out,
1312 [&](const Method* method, const Interface* superInterface) {
1313 return generateStaticStubMethodSource(out, iface->fqName(), method, superInterface);
1314 },
1315 false /* include parents */);
1316
1317 generateMethods(out, [&](const Method* method, const Interface*) {
1318 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1319 return;
1320 }
1321 method->generateCppSignature(out, iface->getStubName());
1322 out << " ";
1323 out.block([&] {
1324 method->cppImpl(IMPL_STUB_IMPL, out);
1325 }).endl();
1326 });
1327
1328 out << "::android::status_t " << klassName << "::onTransact(\n";
1329
1330 out.indent();
1331 out.indent();
1332
1333 out << "uint32_t _hidl_code,\n"
1334 << "const ::android::hardware::Parcel &_hidl_data,\n"
1335 << "::android::hardware::Parcel *_hidl_reply,\n"
1336 << "uint32_t _hidl_flags,\n"
1337 << "TransactCallback _hidl_cb) {\n";
1338
1339 out.unindent();
1340
1341 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
1342 out << "switch (_hidl_code) {\n";
1343 out.indent();
1344
1345 for (const auto &tuple : iface->allMethodsFromRoot()) {
1346 const Method *method = tuple.method();
1347 const Interface *superInterface = tuple.interface();
1348
1349 if (!isIBase() && method->isHidlReserved()) {
1350 continue;
1351 }
1352 out << "case "
1353 << method->getSerialId()
1354 << " /* "
1355 << method->name()
1356 << " */:\n{\n";
1357
1358 out.indent();
1359
1360 generateStubSourceForMethod(out, method, superInterface);
1361
1362 out.unindent();
1363 out << "}\n\n";
1364 }
1365
1366 out << "default:\n{\n";
1367 out.indent();
1368
1369 if (iface->isIBase()) {
1370 out << "(void)_hidl_flags;\n";
1371 out << "return ::android::UNKNOWN_TRANSACTION;\n";
1372 } else {
1373 out << "return ";
1374 out << gIBaseFqName.getInterfaceStubFqName().cppName();
1375 out << "::onTransact(\n";
1376
1377 out.indent();
1378 out.indent();
1379
1380 out << "_hidl_code, _hidl_data, _hidl_reply, "
1381 << "_hidl_flags, _hidl_cb);\n";
1382
1383 out.unindent();
1384 out.unindent();
1385 }
1386
1387 out.unindent();
1388 out << "}\n";
1389
1390 out.unindent();
1391 out << "}\n\n";
1392
1393 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1394 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1395 out.indent(2, [&] {
1396 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1397 out << "_hidl_reply);\n";
1398 });
1399 });
1400
1401 out << "return _hidl_err;\n";
1402
1403 out.unindent();
1404 out << "}\n\n";
1405 }
1406
generateStubSourceForMethod(Formatter & out,const Method * method,const Interface * superInterface) const1407 void AST::generateStubSourceForMethod(Formatter& out, const Method* method,
1408 const Interface* superInterface) const {
1409 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1410 method->cppImpl(IMPL_STUB, out);
1411 out << "break;\n";
1412 return;
1413 }
1414
1415 out << "_hidl_err = "
1416 << superInterface->fqName().cppNamespace()
1417 << "::"
1418 << superInterface->getStubName()
1419 << "::_hidl_"
1420 << method->name()
1421 << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
1422 out << "break;\n";
1423 }
1424
generateStaticStubMethodSource(Formatter & out,const FQName & fqName,const Method * method,const Interface * superInterface) const1425 void AST::generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
1426 const Method* method, const Interface* superInterface) const {
1427 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1428 return;
1429 }
1430
1431 const std::string& klassName = fqName.getInterfaceStubName();
1432
1433 out << "::android::status_t " << klassName << "::_hidl_" << method->name() << "(\n";
1434
1435 out.indent();
1436 out.indent();
1437
1438 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
1439 << "const ::android::hardware::Parcel &_hidl_data,\n"
1440 << "::android::hardware::Parcel *_hidl_reply,\n"
1441 << "TransactCallback _hidl_cb) {\n";
1442
1443 out.unindent();
1444
1445 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1446 out << "bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();\n";
1447 out << "const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();\n";
1448 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1449
1450 out << "::android::status_t _hidl_err = ::android::OK;\n";
1451
1452 out << "if (!_hidl_data.enforceInterface("
1453 << klassName
1454 << "::Pure::descriptor)) {\n";
1455
1456 out.indent();
1457 out << "_hidl_err = ::android::BAD_TYPE;\n";
1458 out << "return _hidl_err;\n";
1459 out.unindent();
1460 out << "}\n\n";
1461
1462 declareCppReaderLocals(out, method->args(), false /* forResults */);
1463
1464 for (const auto &arg : method->args()) {
1465 emitCppReaderWriter(
1466 out,
1467 "_hidl_data",
1468 false /* parcelObjIsPointer */,
1469 arg,
1470 true /* reader */,
1471 Type::ErrorMode_Return,
1472 false /* addPrefixToName */);
1473 }
1474
1475 generateCppInstrumentationCall(
1476 out,
1477 InstrumentationEvent::SERVER_API_ENTRY,
1478 method,
1479 superInterface);
1480
1481 const bool returnsValue = !method->results().empty();
1482 const NamedReference<Type>* elidedReturn = method->canElideCallback();
1483
1484 std::string callee;
1485
1486 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL)) {
1487 callee = "_hidl_this";
1488 } else {
1489 callee = "static_cast<" + fqName.getInterfaceName() + "*>(_hidl_this->getImpl().get())";
1490 }
1491
1492 if (elidedReturn != nullptr) {
1493 out << elidedReturn->type().getCppResultType()
1494 << " _hidl_out_"
1495 << elidedReturn->name()
1496 << " = "
1497 << callee << "->" << method->name()
1498 << "(";
1499
1500 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
1501 if (arg->type().resultNeedsDeref()) {
1502 out << "*";
1503 }
1504 out << arg->name();
1505 });
1506
1507 out << ");\n\n";
1508
1509 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1510 << "_hidl_reply);\n\n";
1511
1512 elidedReturn->type().emitReaderWriter(
1513 out,
1514 "_hidl_out_" + elidedReturn->name(),
1515 "_hidl_reply",
1516 true, /* parcelObjIsPointer */
1517 false, /* isReader */
1518 Type::ErrorMode_Goto);
1519
1520 out.unindent();
1521 out << "_hidl_error:\n";
1522 out.indent();
1523
1524 generateCppInstrumentationCall(
1525 out,
1526 InstrumentationEvent::SERVER_API_EXIT,
1527 method,
1528 superInterface);
1529
1530 out << "if (_hidl_err != ::android::OK) { return _hidl_err; }\n";
1531 out << "_hidl_cb(*_hidl_reply);\n";
1532 } else {
1533 if (returnsValue) {
1534 out << "bool _hidl_callbackCalled = false;\n\n";
1535 }
1536
1537 out << "::android::hardware::Return<void> _hidl_ret = " << callee << "->" << method->name()
1538 << "(";
1539
1540 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
1541 if (arg->type().resultNeedsDeref()) {
1542 out << "*";
1543 }
1544
1545 out << arg->name();
1546 });
1547
1548 if (returnsValue) {
1549 if (!method->args().empty()) {
1550 out << ", ";
1551 }
1552
1553 out << "[&](";
1554
1555 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
1556 out << "const auto &_hidl_out_" << arg->name();
1557 });
1558
1559 out << ") {\n";
1560 out.indent();
1561 out << "if (_hidl_callbackCalled) {\n";
1562 out.indent();
1563 out << "LOG_ALWAYS_FATAL(\""
1564 << method->name()
1565 << ": _hidl_cb called a second time, but must be called once.\");\n";
1566 out.unindent();
1567 out << "}\n";
1568 out << "_hidl_callbackCalled = true;\n\n";
1569
1570 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1571 << "_hidl_reply);\n\n";
1572
1573 for (const auto &arg : method->results()) {
1574 emitCppReaderWriter(
1575 out,
1576 "_hidl_reply",
1577 true /* parcelObjIsPointer */,
1578 arg,
1579 false /* reader */,
1580 Type::ErrorMode_Goto,
1581 true /* addPrefixToName */);
1582 }
1583
1584 if (!method->results().empty()) {
1585 out.unindent();
1586 out << "_hidl_error:\n";
1587 out.indent();
1588 }
1589
1590 generateCppInstrumentationCall(
1591 out,
1592 InstrumentationEvent::SERVER_API_EXIT,
1593 method,
1594 superInterface);
1595
1596 out << "if (_hidl_err != ::android::OK) { return; }\n";
1597 out << "_hidl_cb(*_hidl_reply);\n";
1598
1599 out.unindent();
1600 out << "});\n\n";
1601 } else {
1602 out << ");\n\n";
1603 out << "(void) _hidl_cb;\n\n";
1604 generateCppInstrumentationCall(
1605 out,
1606 InstrumentationEvent::SERVER_API_EXIT,
1607 method,
1608 superInterface);
1609 }
1610
1611 out << "_hidl_ret.assertOk();\n";
1612
1613 if (returnsValue) {
1614 out << "if (!_hidl_callbackCalled) {\n";
1615 out.indent();
1616 out << "LOG_ALWAYS_FATAL(\""
1617 << method->name()
1618 << ": _hidl_cb not called, but must be called once.\");\n";
1619 out.unindent();
1620 out << "}\n\n";
1621 } else {
1622 out << "::android::hardware::writeToParcel("
1623 << "::android::hardware::Status::ok(), "
1624 << "_hidl_reply);\n\n";
1625 }
1626 }
1627
1628 out << "return _hidl_err;\n";
1629 out.unindent();
1630 out << "}\n\n";
1631 }
1632
generatePassthroughHeader(Formatter & out) const1633 void AST::generatePassthroughHeader(Formatter& out) const {
1634 if (!AST::isInterface()) {
1635 // types.hal does not get a stub header.
1636 return;
1637 }
1638
1639 const Interface* iface = mRootScope.getInterface();
1640 CHECK(iface != nullptr);
1641
1642 const std::string klassName = iface->getPassthroughName();
1643
1644 const std::string guard = makeHeaderGuard(klassName);
1645
1646 out << "#ifndef " << guard << "\n";
1647 out << "#define " << guard << "\n\n";
1648
1649 out << "#include <android-base/macros.h>\n";
1650 out << "#include <cutils/trace.h>\n";
1651 out << "#include <future>\n";
1652
1653 generateCppPackageInclude(out, mPackage, iface->definedName());
1654 out << "\n";
1655
1656 out << "#include <hidl/HidlPassthroughSupport.h>\n";
1657 out << "#include <hidl/TaskRunner.h>\n";
1658
1659 enterLeaveNamespace(out, true /* enter */);
1660 out << "\n";
1661
1662 out << "struct " << klassName << " : " << iface->definedName()
1663 << ", ::android::hardware::details::HidlInstrumentor {\n";
1664
1665 out.indent();
1666 out << "explicit " << klassName << "(const ::android::sp<" << iface->definedName()
1667 << "> impl);\n";
1668
1669 out.endl();
1670 generateTemplatizationLink(out);
1671 generateCppTag(out, "::android::hardware::details::bs_tag");
1672
1673 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1674 generatePassthroughMethod(out, method, superInterface);
1675 });
1676
1677 out.unindent();
1678 out << "private:\n";
1679 out.indent();
1680 out << "const ::android::sp<" << iface->definedName() << "> mImpl;\n";
1681
1682 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
1683
1684 out << "\n";
1685
1686 out << "::android::hardware::Return<void> addOnewayTask("
1687 "std::function<void(void)>);\n\n";
1688
1689 out.unindent();
1690
1691 out << "};\n\n";
1692
1693 enterLeaveNamespace(out, false /* enter */);
1694
1695 out << "\n#endif // " << guard << "\n";
1696 }
1697
generateInterfaceSource(Formatter & out) const1698 void AST::generateInterfaceSource(Formatter& out) const {
1699 const Interface* iface = mRootScope.getInterface();
1700
1701 // generate castFrom functions
1702 std::string childTypeResult = iface->getCppResultType();
1703
1704 generateMethods(out, [&](const Method* method, const Interface*) {
1705 bool reserved = method->isHidlReserved();
1706
1707 if (!reserved) {
1708 out << "// no default implementation for: ";
1709 }
1710 method->generateCppSignature(out, iface->definedName());
1711 if (reserved) {
1712 out.block([&]() {
1713 method->cppImpl(IMPL_INTERFACE, out);
1714 }).endl();
1715 }
1716
1717 out << "\n";
1718
1719 return;
1720 });
1721
1722 for (const Interface *superType : iface->typeChain()) {
1723 out << "::android::hardware::Return<" << childTypeResult << "> " << iface->definedName()
1724 << "::castFrom(" << superType->getCppArgumentType() << " parent, bool "
1725 << (iface == superType ? "/* emitError */" : "emitError") << ") {\n";
1726 out.indent();
1727 if (iface == superType) {
1728 out << "return parent;\n";
1729 } else {
1730 out << "return ::android::hardware::details::castInterface<";
1731 out << iface->definedName() << ", " << superType->fqName().cppName() << ", "
1732 << iface->getProxyName() << ">(\n";
1733 out.indent();
1734 out.indent();
1735 out << "parent, \""
1736 << iface->fqName().string()
1737 << "\", emitError);\n";
1738 out.unindent();
1739 out.unindent();
1740 }
1741 out.unindent();
1742 out << "}\n\n";
1743 }
1744 }
1745
generatePassthroughSource(Formatter & out) const1746 void AST::generatePassthroughSource(Formatter& out) const {
1747 const Interface* iface = mRootScope.getInterface();
1748
1749 const std::string klassName = iface->getPassthroughName();
1750
1751 out << klassName << "::" << klassName << "(const ::android::sp<" << iface->fullName()
1752 << "> impl) : ::android::hardware::details::HidlInstrumentor(\"" << mPackage.string()
1753 << "\", \"" << iface->definedName() << "\"), mImpl(impl) {\n";
1754
1755 out.indent([&] { out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n"; });
1756
1757 out << "}\n\n";
1758
1759 out << "::android::hardware::Return<void> " << klassName
1760 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1761 out.indent();
1762 out << "if (!mOnewayQueue.push(fun)) {\n";
1763 out.indent();
1764 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1765 out.indent();
1766 out.indent();
1767 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
1768 << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
1769 out.unindent();
1770 out.unindent();
1771 out.unindent();
1772 out << "}\n";
1773
1774 out << "return ::android::hardware::Status();\n";
1775
1776 out.unindent();
1777 out << "}\n\n";
1778 }
1779
generateCppAtraceCall(Formatter & out,InstrumentationEvent event,const Method * method) const1780 void AST::generateCppAtraceCall(Formatter &out,
1781 InstrumentationEvent event,
1782 const Method *method) const {
1783 const Interface* iface = mRootScope.getInterface();
1784 std::string baseString = "HIDL::" + iface->definedName() + "::" + method->name();
1785 switch (event) {
1786 case SERVER_API_ENTRY:
1787 {
1788 out << "atrace_begin(ATRACE_TAG_HAL, \""
1789 << baseString + "::server\");\n";
1790 break;
1791 }
1792 case PASSTHROUGH_ENTRY:
1793 {
1794 out << "atrace_begin(ATRACE_TAG_HAL, \""
1795 << baseString + "::passthrough\");\n";
1796 break;
1797 }
1798 case SERVER_API_EXIT:
1799 case PASSTHROUGH_EXIT:
1800 {
1801 out << "atrace_end(ATRACE_TAG_HAL);\n";
1802 break;
1803 }
1804 // client uses scope because of gotos
1805 // this isn't done for server because the profiled code isn't alone in its scope
1806 // this isn't done for passthrough becuase the profiled boundary isn't even in the same code
1807 case CLIENT_API_ENTRY: {
1808 out << "::android::ScopedTrace PASTE(___tracer, __LINE__) (ATRACE_TAG_HAL, \""
1809 << baseString + "::client\");\n";
1810 break;
1811 }
1812 case CLIENT_API_EXIT:
1813 break;
1814 default:
1815 {
1816 CHECK(false) << "Unsupported instrumentation event: " << event;
1817 }
1818 }
1819 }
1820
generateCppInstrumentationCall(Formatter & out,InstrumentationEvent event,const Method * method,const Interface * superInterface) const1821 void AST::generateCppInstrumentationCall(
1822 Formatter &out,
1823 InstrumentationEvent event,
1824 const Method *method,
1825 const Interface* superInterface) const {
1826 generateCppAtraceCall(out, event, method);
1827
1828 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1829 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1830 out.indent();
1831 out << "std::vector<void *> _hidl_args;\n";
1832 std::string event_str = "";
1833 switch (event) {
1834 case SERVER_API_ENTRY:
1835 {
1836 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1837 for (const auto &arg : method->args()) {
1838 out << "_hidl_args.push_back((void *)"
1839 << (arg->type().resultNeedsDeref() ? "" : "&")
1840 << arg->name()
1841 << ");\n";
1842 }
1843 break;
1844 }
1845 case SERVER_API_EXIT:
1846 {
1847 event_str = "InstrumentationEvent::SERVER_API_EXIT";
1848 for (const auto &arg : method->results()) {
1849 out << "_hidl_args.push_back((void *)&_hidl_out_"
1850 << arg->name()
1851 << ");\n";
1852 }
1853 break;
1854 }
1855 case CLIENT_API_ENTRY:
1856 {
1857 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1858 for (const auto &arg : method->args()) {
1859 out << "_hidl_args.push_back((void *)&"
1860 << arg->name()
1861 << ");\n";
1862 }
1863 break;
1864 }
1865 case CLIENT_API_EXIT:
1866 {
1867 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1868 for (const auto &arg : method->results()) {
1869 out << "_hidl_args.push_back((void *)"
1870 << (arg->type().resultNeedsDeref() ? "" : "&")
1871 << "_hidl_out_"
1872 << arg->name()
1873 << ");\n";
1874 }
1875 break;
1876 }
1877 case PASSTHROUGH_ENTRY:
1878 {
1879 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1880 for (const auto &arg : method->args()) {
1881 out << "_hidl_args.push_back((void *)&"
1882 << arg->name()
1883 << ");\n";
1884 }
1885 break;
1886 }
1887 case PASSTHROUGH_EXIT:
1888 {
1889 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
1890 for (const auto &arg : method->results()) {
1891 out << "_hidl_args.push_back((void *)&_hidl_out_"
1892 << arg->name()
1893 << ");\n";
1894 }
1895 break;
1896 }
1897 default:
1898 {
1899 CHECK(false) << "Unsupported instrumentation event: " << event;
1900 }
1901 }
1902
1903 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
1904 out.indent();
1905 out << "callback(" << event_str << ", \"" << superInterface->fqName().package() << "\", \""
1906 << superInterface->fqName().version() << "\", \"" << superInterface->definedName()
1907 << "\", \"" << method->name() << "\", &_hidl_args);\n";
1908 out.unindent();
1909 out << "}\n";
1910 out.unindent();
1911 out << "}\n";
1912 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1913 }
1914
1915 } // namespace android
1916