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