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 "Interface.h"
18
19 #include "Annotation.h"
20 #include "ArrayType.h"
21 #include "ConstantExpression.h"
22 #include "DeathRecipientType.h"
23 #include "Method.h"
24 #include "ScalarType.h"
25 #include "StringType.h"
26 #include "VectorType.h"
27
28 #include <unistd.h>
29
30 #include <iostream>
31 #include <memory>
32 #include <sstream>
33 #include <string>
34 #include <unordered_map>
35
36 #include <android-base/logging.h>
37 #include <hidl-util/Formatter.h>
38 #include <hidl-util/StringHelper.h>
39 #include <hwbinder/IBinder.h>
40
41 namespace android {
42
43 const std::unique_ptr<ConstantExpression> Interface::FLAG_ONE_WAY =
44 std::make_unique<LiteralConstantExpression>(ScalarType::KIND_UINT32, hardware::IBinder::FLAG_ONEWAY, "oneway");
45
Interface(const std::string & localName,const FQName & fullName,const Location & location,Scope * parent,const Reference<Type> & superType,const Hash * fileHash)46 Interface::Interface(const std::string& localName, const FQName& fullName, const Location& location,
47 Scope* parent, const Reference<Type>& superType, const Hash* fileHash)
48 : Scope(localName, fullName, location, parent), mSuperType(superType), mFileHash(fileHash) {}
49
typeName() const50 std::string Interface::typeName() const {
51 return "interface " + definedName();
52 }
53
getFileHash() const54 const Hash* Interface::getFileHash() const {
55 return mFileHash;
56 }
57
fillPingMethod(Method * method) const58 bool Interface::fillPingMethod(Method *method) const {
59 if (method->name() != "ping") {
60 return false;
61 }
62
63 method->fillImplementation(
64 hardware::IBinder::HIDL_PING_TRANSACTION,
65 {
66 {IMPL_INTERFACE,
67 [](auto &out) {
68 out << "return ::android::hardware::Void();\n";
69 }
70 },
71 {IMPL_STUB_IMPL,
72 [](auto &out) {
73 out << "return ::android::hardware::Void();\n";
74 }
75 }
76 }, /*cppImpl*/
77 {
78 {IMPL_INTERFACE,
79 [](auto &out) {
80 out << "return;\n";
81 }
82 },
83 } /*javaImpl*/
84 );
85
86 return true;
87 }
88
fillLinkToDeathMethod(Method * method) const89 bool Interface::fillLinkToDeathMethod(Method *method) const {
90 if (method->name() != "linkToDeath") {
91 return false;
92 }
93
94 method->fillImplementation(
95 hardware::IBinder::HIDL_LINK_TO_DEATH_TRANSACTION,
96 {
97 {IMPL_INTERFACE,
98 [](auto &out) {
99 out << "(void)cookie;\n"
100 << "return (recipient != nullptr);\n";
101 }
102 },
103 {IMPL_PROXY,
104 [](auto &out) {
105 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
106 out << "::android::hardware::hidl_binder_death_recipient *binder_recipient"
107 << " = new ::android::hardware::hidl_binder_death_recipient(recipient, cookie, this);\n"
108 << "std::unique_lock<std::mutex> lock(_hidl_mMutex);\n"
109 << "_hidl_mDeathRecipients.push_back(binder_recipient);\n"
110 << "return (remote()->linkToDeath(binder_recipient)"
111 << " == ::android::OK);\n";
112 }
113 },
114 {IMPL_STUB, nullptr}
115 }, /*cppImpl*/
116 {
117 {IMPL_INTERFACE,
118 [](auto &out) {
119 out << "return true;\n";
120 }
121 },
122 {IMPL_PROXY,
123 [](auto &out) {
124 out << "return mRemote.linkToDeath(recipient, cookie);\n";
125 }
126 },
127 {IMPL_STUB, nullptr}
128 } /*javaImpl*/
129 );
130 return true;
131 }
132
fillUnlinkToDeathMethod(Method * method) const133 bool Interface::fillUnlinkToDeathMethod(Method *method) const {
134 if (method->name() != "unlinkToDeath") {
135 return false;
136 }
137
138 method->fillImplementation(
139 hardware::IBinder::HIDL_UNLINK_TO_DEATH_TRANSACTION,
140 {
141 {IMPL_INTERFACE,
142 [](auto &out) {
143 out << "return (recipient != nullptr);\n";
144 }
145 },
146 {IMPL_PROXY,
147 [](auto &out) {
148 out << "std::unique_lock<std::mutex> lock(_hidl_mMutex);\n"
149 << "for (auto it = _hidl_mDeathRecipients.rbegin();"
150 << "it != _hidl_mDeathRecipients.rend();"
151 << "++it) {\n";
152 out.indent([&] {
153 out.sIf("(*it)->getRecipient() == recipient", [&] {
154 out << "::android::status_t status = remote()->unlinkToDeath(*it);\n"
155 << "_hidl_mDeathRecipients.erase(it.base()-1);\n"
156 << "return status == ::android::OK;\n";
157 });
158 }).endl();
159 out << "}\n";
160 out << "return false;\n";
161 }
162 },
163 {IMPL_STUB, nullptr /* don't generate code */}
164 }, /*cppImpl*/
165 {
166 {IMPL_INTERFACE,
167 [](auto &out) {
168 out << "return true;\n";
169 }
170 },
171 {IMPL_PROXY,
172 [](auto &out) {
173 out << "return mRemote.unlinkToDeath(recipient);\n";
174 }
175 },
176 {IMPL_STUB, nullptr /* don't generate code */}
177 } /*javaImpl*/
178 );
179 return true;
180 }
fillSyspropsChangedMethod(Method * method) const181 bool Interface::fillSyspropsChangedMethod(Method *method) const {
182 if (method->name() != "notifySyspropsChanged") {
183 return false;
184 }
185
186 method->fillImplementation(
187 hardware::IBinder::HIDL_SYSPROPS_CHANGED_TRANSACTION,
188 { { IMPL_INTERFACE, [](auto &out) {
189 out << "::android::report_sysprop_change();\n";
190 out << "return ::android::hardware::Void();\n";
191 } } }, /*cppImpl */
192 { { IMPL_INTERFACE, [](auto &out) { /* javaImpl */
193 out << "android.os.HwBinder.enableInstrumentation();\n";
194 } } } /*javaImpl */
195 );
196 return true;
197 }
198
fillSetHALInstrumentationMethod(Method * method) const199 bool Interface::fillSetHALInstrumentationMethod(Method *method) const {
200 if (method->name() != "setHALInstrumentation") {
201 return false;
202 }
203
204 method->fillImplementation(
205 hardware::IBinder::HIDL_SET_HAL_INSTRUMENTATION_TRANSACTION,
206 {
207 {IMPL_INTERFACE,
208 [](auto &out) {
209 // do nothing for base class.
210 out << "return ::android::hardware::Void();\n";
211 }
212 },
213 {IMPL_STUB,
214 [](auto &out) {
215 out << "configureInstrumentation();\n";
216 }
217 },
218 {IMPL_PASSTHROUGH,
219 [](auto &out) {
220 out << "configureInstrumentation();\n";
221 out << "return ::android::hardware::Void();\n";
222 }
223 },
224 }, /*cppImpl */
225 { { IMPL_INTERFACE, [](auto & /*out*/) { /* javaImpl */
226 // Not support for Java Impl for now.
227 } } } /*javaImpl */
228 );
229 return true;
230 }
231
fillDescriptorChainMethod(Method * method) const232 bool Interface::fillDescriptorChainMethod(Method *method) const {
233 if (method->name() != "interfaceChain") {
234 return false;
235 }
236
237 method->fillImplementation(
238 hardware::IBinder::HIDL_DESCRIPTOR_CHAIN_TRANSACTION,
239 { { IMPL_INTERFACE, [this](auto &out) {
240 std::vector<const Interface *> chain = typeChain();
241 out << "_hidl_cb(";
242 out.block([&] {
243 for (const Interface *iface : chain) {
244 out << iface->fullName() << "::descriptor,\n";
245 }
246 });
247 out << ");\n";
248 out << "return ::android::hardware::Void();\n";
249 } } }, /* cppImpl */
250 { { IMPL_INTERFACE, [this](auto &out) {
251 std::vector<const Interface *> chain = typeChain();
252 out << "return new java.util.ArrayList<String>(java.util.Arrays.asList(\n";
253 out.indent(); out.indent();
254 for (size_t i = 0; i < chain.size(); ++i) {
255 if (i != 0)
256 out << ",\n";
257 out << chain[i]->fullJavaName() << ".kInterfaceName";
258 }
259 out << "));\n";
260 out.unindent(); out.unindent();
261 } } } /* javaImpl */
262 );
263 return true;
264 }
265
emitDigestChain(Formatter & out,const std::string & prefix,const std::vector<const Interface * > & chain,std::function<std::string (std::unique_ptr<ConstantExpression>)> byteToString) const266 void Interface::emitDigestChain(
267 Formatter& out, const std::string& prefix, const std::vector<const Interface*>& chain,
268 std::function<std::string(std::unique_ptr<ConstantExpression>)> byteToString) const {
269 out.join(chain.begin(), chain.end(), ",\n", [&](const auto& iface) {
270 out << prefix;
271 out << "{";
272 out.join(
273 iface->getFileHash()->raw().begin(), iface->getFileHash()->raw().end(), ",",
274 [&](const auto& e) {
275 // Use ConstantExpression::cppValue / javaValue
276 // because Java used signed byte for uint8_t.
277 out << byteToString(ConstantExpression::ValueOf(ScalarType::Kind::KIND_UINT8, e));
278 });
279 out << "} /* ";
280 out << iface->getFileHash()->hexString();
281 out << " */";
282 });
283 }
284
fillHashChainMethod(Method * method) const285 bool Interface::fillHashChainMethod(Method *method) const {
286 if (method->name() != "getHashChain") {
287 return false;
288 }
289 const VectorType *chainType = static_cast<const VectorType *>(&method->results()[0]->type());
290 const ArrayType *digestType = static_cast<const ArrayType *>(chainType->getElementType());
291
292 method->fillImplementation(
293 hardware::IBinder::HIDL_HASH_CHAIN_TRANSACTION,
294 { { IMPL_INTERFACE, [this, digestType](auto &out) {
295 std::vector<const Interface *> chain = typeChain();
296 out << "_hidl_cb(";
297 out.block([&] {
298 emitDigestChain(out, "(" + digestType->getInternalDataCppType() + ")", chain,
299 [](const auto& e) { return e->cppValue(); });
300 });
301 out << ");\n";
302 out << "return ::android::hardware::Void();\n";
303 } } }, /* cppImpl */
304 { { IMPL_INTERFACE, [this, digestType, chainType](auto &out) {
305 std::vector<const Interface *> chain = typeChain();
306 out << "return new "
307 << chainType->getJavaType(false /* forInitializer */)
308 << "(java.util.Arrays.asList(\n";
309 out.indent(2, [&] {
310 // No need for dimensions when elements are explicitly provided.
311 emitDigestChain(out, "new " + digestType->getJavaType(false /* forInitializer */),
312 chain, [](const auto& e) { return e->javaValue(); });
313 });
314 out << "));\n";
315 } } } /* javaImpl */
316 );
317 return true;
318 }
319
fillGetDescriptorMethod(Method * method) const320 bool Interface::fillGetDescriptorMethod(Method *method) const {
321 if (method->name() != "interfaceDescriptor") {
322 return false;
323 }
324
325 method->fillImplementation(
326 hardware::IBinder::HIDL_GET_DESCRIPTOR_TRANSACTION,
327 { { IMPL_INTERFACE, [this](auto &out) {
328 out << "_hidl_cb("
329 << fullName()
330 << "::descriptor);\n"
331 << "return ::android::hardware::Void();\n";
332 } } }, /* cppImpl */
333 { { IMPL_INTERFACE, [this](auto &out) {
334 out << "return "
335 << fullJavaName()
336 << ".kInterfaceName;\n";
337 } } } /* javaImpl */
338 );
339 return true;
340 }
341
fillGetDebugInfoMethod(Method * method) const342 bool Interface::fillGetDebugInfoMethod(Method *method) const {
343 if (method->name() != "getDebugInfo") {
344 return false;
345 }
346
347 static const std::string sArch =
348 "#if defined(__LP64__)\n"
349 "::android::hidl::base::V1_0::DebugInfo::Architecture::IS_64BIT\n"
350 "#else\n"
351 "::android::hidl::base::V1_0::DebugInfo::Architecture::IS_32BIT\n"
352 "#endif\n";
353
354 method->fillImplementation(
355 hardware::IBinder::HIDL_GET_REF_INFO_TRANSACTION,
356 {
357 {IMPL_INTERFACE,
358 [](auto &out) {
359 // getDebugInfo returns N/A for local objects.
360 out << "::android::hidl::base::V1_0::DebugInfo info = {};\n";
361 out << "info.pid = -1;\n";
362 out << "info.ptr = 0;\n";
363 out << "info.arch = \n" << sArch << ";\n";
364 out << "_hidl_cb(info);\n";
365 out << "return ::android::hardware::Void();\n";
366 }
367 },
368 {IMPL_STUB_IMPL,
369 [](auto &out) {
370 out << "::android::hidl::base::V1_0::DebugInfo info = {};\n";
371 out << "info.pid = ::android::hardware::details::getPidIfSharable();\n";
372 out << "info.ptr = ::android::hardware::details::debuggable()"
373 << "? reinterpret_cast<uint64_t>(this) : 0;\n";
374 out << "info.arch = \n" << sArch << ";\n";
375 out << "_hidl_cb(info);\n";
376 out << "return ::android::hardware::Void();\n";
377 }
378 }
379 }, /* cppImpl */
380 { { IMPL_INTERFACE, [method](auto &out) {
381 const Type &refInfo = method->results().front()->type();
382 out << refInfo.getJavaType(false /* forInitializer */) << " info = new "
383 << refInfo.getJavaType(true /* forInitializer */) << "();\n"
384 << "info.pid = android.os.HidlSupport.getPidIfSharable();\n"
385 << "info.ptr = 0;\n"
386 << "info.arch = android.hidl.base.V1_0.DebugInfo.Architecture.UNKNOWN;\n"
387 << "return info;\n";
388 } } } /* javaImpl */
389 );
390
391 return true;
392 }
393
fillDebugMethod(Method * method) const394 bool Interface::fillDebugMethod(Method *method) const {
395 if (method->name() != "debug") {
396 return false;
397 }
398
399 method->fillImplementation(hardware::IBinder::HIDL_DEBUG_TRANSACTION,
400 {
401 {IMPL_INTERFACE,
402 [](auto& out) {
403 out << "(void)fd;\n"
404 << "(void)options;\n"
405 << "return ::android::hardware::Void();\n";
406 }},
407 }, /* cppImpl */
408 {
409 {IMPL_INTERFACE, [](auto& out) { out << "return;\n"; }},
410 } /* javaImpl */
411 );
412
413 return true;
414 }
415
addUserDefinedMethod(Method * method)416 void Interface::addUserDefinedMethod(Method* method) {
417 CHECK(!method->isHidlReserved());
418 mUserMethods.push_back(method);
419 }
420
getReferences() const421 std::vector<const Reference<Type>*> Interface::getReferences() const {
422 std::vector<const Reference<Type>*> ret;
423
424 if (!isIBase()) {
425 ret.push_back(&mSuperType);
426 }
427
428 for (const auto* method : methods()) {
429 const auto& references = method->getReferences();
430 ret.insert(ret.end(), references.begin(), references.end());
431 }
432
433 return ret;
434 }
435
getStrongReferences() const436 std::vector<const Reference<Type>*> Interface::getStrongReferences() const {
437 // Interface is a special case as a reference:
438 // its definiton must be completed for extension but
439 // not necessary for other references.
440
441 std::vector<const Reference<Type>*> ret;
442 if (!isIBase()) {
443 ret.push_back(&mSuperType);
444 }
445
446 for (const auto* method : methods()) {
447 const auto& references = method->getStrongReferences();
448 ret.insert(ret.end(), references.begin(), references.end());
449 }
450
451 return ret;
452 }
453
resolveInheritance()454 status_t Interface::resolveInheritance() {
455 size_t serial = hardware::IBinder::FIRST_CALL_TRANSACTION;
456 for (const auto* ancestor : superTypeChain()) {
457 serial += ancestor->mUserMethods.size();
458 }
459
460 for (Method* method : mUserMethods) {
461 if (serial > hardware::IBinder::LAST_CALL_TRANSACTION) {
462 std::cerr << "ERROR: More than " << hardware::IBinder::LAST_CALL_TRANSACTION
463 << " methods (including super and reserved) are not allowed at " << location()
464 << std::endl;
465 return UNKNOWN_ERROR;
466 }
467
468 method->setSerialId(serial);
469 serial++;
470 }
471
472 return Scope::resolveInheritance();
473 }
474
validate() const475 status_t Interface::validate() const {
476 CHECK(isIBase() == mSuperType.isEmptyReference());
477
478 if (!isIBase() && !mSuperType->isInterface()) {
479 std::cerr << "ERROR: You can only extend interfaces at " << mSuperType.location()
480 << std::endl;
481 return UNKNOWN_ERROR;
482 }
483
484 status_t err;
485
486 err = validateUniqueNames();
487 if (err != OK) return err;
488
489 err = validateAnnotations();
490 if (err != OK) return err;
491
492 return Scope::validate();
493 }
494
getAlignmentAndSize(size_t * align,size_t * size) const495 void Interface::getAlignmentAndSize(size_t* align, size_t* size) const {
496 *align = 8;
497 *size = 8;
498 }
499
validateUniqueNames() const500 status_t Interface::validateUniqueNames() const {
501 std::unordered_map<std::string, const Interface*> registeredMethodNames;
502 for (auto const& tuple : allSuperMethodsFromRoot()) {
503 // No need to check super method uniqueness
504 registeredMethodNames[tuple.method()->name()] = tuple.interface();
505 }
506
507 for (const Method* method : mUserMethods) {
508 auto registered = registeredMethodNames.find(method->name());
509
510 if (registered != registeredMethodNames.end()) {
511 const Interface* definedInType = registered->second;
512
513 if (definedInType == this) {
514 // Defined in this interface
515 std::cerr << "ERROR: Redefinition of method '" << method->name() << "'";
516 } else if (definedInType->isIBase()) {
517 // Defined in IBase
518 std::cerr << "ERROR: Redefinition of reserved method '" << method->name() << "'";
519 } else {
520 // Defined in super not IBase
521 std::cerr << "ERROR: Redefinition of method '" << method->name()
522 << "' defined in interface '" << definedInType->fullName() << "'";
523 }
524 std::cerr << " at " << method->location() << std::endl;
525 return UNKNOWN_ERROR;
526 }
527
528 registeredMethodNames[method->name()] = this;
529 }
530
531 return OK;
532 }
533
validateAnnotations() const534 status_t Interface::validateAnnotations() const {
535 for (const Method* method : methods()) {
536 for (const Annotation* annotation : method->annotations()) {
537 const std::string name = annotation->name();
538
539 if (name == "entry" || name == "exit" || name == "callflow") {
540 continue;
541 }
542
543 std::cerr << "ERROR: Unrecognized annotation '" << name
544 << "' for method: " << method->name() << ". An annotation should be one of: "
545 << "entry, exit, callflow." << std::endl;
546 return UNKNOWN_ERROR;
547 }
548 }
549 return OK;
550 }
551
addAllReservedMethods(const std::map<std::string,Method * > & allReservedMethods)552 bool Interface::addAllReservedMethods(const std::map<std::string, Method*>& allReservedMethods) {
553 // use a sorted map to insert them in serial ID order.
554 std::map<int32_t, Method *> reservedMethodsById;
555 for (const auto& pair : allReservedMethods) {
556 Method *method = pair.second->copySignature();
557 bool fillSuccess = fillPingMethod(method)
558 || fillDescriptorChainMethod(method)
559 || fillGetDescriptorMethod(method)
560 || fillHashChainMethod(method)
561 || fillSyspropsChangedMethod(method)
562 || fillLinkToDeathMethod(method)
563 || fillUnlinkToDeathMethod(method)
564 || fillSetHALInstrumentationMethod(method)
565 || fillGetDebugInfoMethod(method)
566 || fillDebugMethod(method);
567
568 if (!fillSuccess) {
569 std::cerr << "ERROR: hidl-gen does not recognize a reserved method " << method->name()
570 << std::endl;
571 return false;
572 }
573 if (!reservedMethodsById.emplace(method->getSerialId(), method).second) {
574 std::cerr << "ERROR: hidl-gen uses duplicated serial id for " << method->name()
575 << " and " << reservedMethodsById[method->getSerialId()]->name()
576 << ", serialId = " << method->getSerialId() << std::endl;
577 return false;
578 }
579 }
580 for (const auto &pair : reservedMethodsById) {
581 this->mReservedMethods.push_back(pair.second);
582 }
583 return true;
584 }
585
superType() const586 const Interface* Interface::superType() const {
587 if (isIBase()) return nullptr;
588 if (!mSuperType->isInterface()) {
589 // This is actually an error
590 // that would be caught in validate
591 return nullptr;
592 }
593 return static_cast<const Interface*>(mSuperType.get());
594 }
595
typeChain() const596 std::vector<const Interface *> Interface::typeChain() const {
597 std::vector<const Interface *> v;
598 const Interface *iface = this;
599 while (iface != nullptr) {
600 v.push_back(iface);
601 iface = iface->superType();
602 }
603 return v;
604 }
605
superTypeChain() const606 std::vector<const Interface *> Interface::superTypeChain() const {
607 return isIBase() ? std::vector<const Interface*>() : superType()->typeChain();
608 }
609
isElidableType() const610 bool Interface::isElidableType() const {
611 return true;
612 }
613
isInterface() const614 bool Interface::isInterface() const {
615 return true;
616 }
617
userDefinedMethods() const618 const std::vector<Method *> &Interface::userDefinedMethods() const {
619 return mUserMethods;
620 }
621
hidlReservedMethods() const622 const std::vector<Method *> &Interface::hidlReservedMethods() const {
623 return mReservedMethods;
624 }
625
methods() const626 std::vector<Method *> Interface::methods() const {
627 std::vector<Method *> v(mUserMethods);
628 v.insert(v.end(), mReservedMethods.begin(), mReservedMethods.end());
629 return v;
630 }
631
allMethodsFromRoot() const632 std::vector<InterfaceAndMethod> Interface::allMethodsFromRoot() const {
633 std::vector<InterfaceAndMethod> v;
634 std::vector<const Interface *> chain = typeChain();
635 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
636 const Interface *iface = *it;
637 for (Method *userMethod : iface->userDefinedMethods()) {
638 v.push_back(InterfaceAndMethod(iface, userMethod));
639 }
640 }
641 for (Method *reservedMethod : hidlReservedMethods()) {
642 v.push_back(InterfaceAndMethod(
643 *chain.rbegin(), // IBase
644 reservedMethod));
645 }
646 return v;
647 }
648
allSuperMethodsFromRoot() const649 std::vector<InterfaceAndMethod> Interface::allSuperMethodsFromRoot() const {
650 return isIBase() ? std::vector<InterfaceAndMethod>() : superType()->allMethodsFromRoot();
651 }
652
getBaseName() const653 std::string Interface::getBaseName() const {
654 return fqName().getInterfaceBaseName();
655 }
656
getAdapterName() const657 std::string Interface::getAdapterName() const {
658 return fqName().getInterfaceAdapterName();
659 }
660
getProxyName() const661 std::string Interface::getProxyName() const {
662 return fqName().getInterfaceProxyName();
663 }
664
getStubName() const665 std::string Interface::getStubName() const {
666 return fqName().getInterfaceStubName();
667 }
668
getHwName() const669 std::string Interface::getHwName() const {
670 return fqName().getInterfaceHwName();
671 }
672
getPassthroughName() const673 std::string Interface::getPassthroughName() const {
674 return fqName().getInterfacePassthroughName();
675 }
676
getProxyFqName() const677 FQName Interface::getProxyFqName() const {
678 return fqName().getInterfaceProxyFqName();
679 }
680
getStubFqName() const681 FQName Interface::getStubFqName() const {
682 return fqName().getInterfaceStubFqName();
683 }
684
getPassthroughFqName() const685 FQName Interface::getPassthroughFqName() const {
686 return fqName().getInterfacePassthroughFqName();
687 }
688
getCppType(StorageMode mode,bool specifyNamespaces) const689 std::string Interface::getCppType(StorageMode mode,
690 bool specifyNamespaces) const {
691 const std::string base =
692 std::string(specifyNamespaces ? "::android::" : "")
693 + "sp<"
694 + fullName()
695 + ">";
696
697 switch (mode) {
698 case StorageMode_Stack:
699 case StorageMode_Result:
700 return base;
701
702 case StorageMode_Argument:
703 return "const " + base + "&";
704 }
705 }
706
getJavaType(bool) const707 std::string Interface::getJavaType(bool /* forInitializer */) const {
708 return fullJavaName();
709 }
710
getVtsType() const711 std::string Interface::getVtsType() const {
712 if (StringHelper::EndsWith(definedName(), "Callback")) {
713 return "TYPE_HIDL_CALLBACK";
714 } else {
715 return "TYPE_HIDL_INTERFACE";
716 }
717 }
718
emitReaderWriter(Formatter & out,const std::string & name,const std::string & parcelObj,bool parcelObjIsPointer,bool isReader,ErrorMode mode) const719 void Interface::emitReaderWriter(
720 Formatter &out,
721 const std::string &name,
722 const std::string &parcelObj,
723 bool parcelObjIsPointer,
724 bool isReader,
725 ErrorMode mode) const {
726 const std::string parcelObjDeref =
727 parcelObj + (parcelObjIsPointer ? "->" : ".");
728
729 if (isReader) {
730 out << "{\n";
731 out.indent();
732
733 const std::string binderName = "_hidl_binder";
734 out << "::android::sp<::android::hardware::IBinder> "
735 << binderName << ";\n";
736
737 out << "_hidl_err = ";
738 out << parcelObjDeref
739 << "readNullableStrongBinder(&"
740 << binderName
741 << ");\n";
742
743 handleError(out, mode);
744
745 out << name
746 << " = "
747 << "::android::hardware::fromBinder<"
748 << fqName().cppName()
749 << ","
750 << getProxyFqName().cppName()
751 << ","
752 << getStubFqName().cppName()
753 << ">("
754 << binderName
755 << ");\n";
756
757 out.unindent();
758 out << "}\n\n";
759 } else {
760 out << "if (" << name << " == nullptr) {\n";
761 out.indent();
762 out << "_hidl_err = ";
763 out << parcelObjDeref
764 << "writeStrongBinder(nullptr);\n";
765 out.unindent();
766 out << "} else {\n";
767 out.indent();
768 out << "::android::sp<::android::hardware::IBinder> _hidl_binder = "
769 << "::android::hardware::getOrCreateCachedBinder(" << name << ".get());\n";
770 out << "if (_hidl_binder.get() != nullptr) {\n";
771 out.indent([&] {
772 out << "_hidl_err = "
773 << parcelObjDeref
774 << "writeStrongBinder(_hidl_binder);\n";
775 });
776 out << "} else {\n";
777 out.indent([&] {
778 out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
779 });
780 out << "}\n";
781 out.unindent();
782 out << "}\n";
783
784 handleError(out, mode);
785 }
786 }
787
emitHidlDefinition(Formatter & out) const788 void Interface::emitHidlDefinition(Formatter& out) const {
789 if (getDocComment() != nullptr) getDocComment()->emit(out);
790 out << typeName() << " ";
791
792 const Interface* super = superType();
793 if (super != nullptr && !super->isIBase()) {
794 out << "extends " << super->fqName().getRelativeFQName(fqName()) << " ";
795 }
796
797 out << "{";
798
799 out.indent([&] {
800 const std::vector<const NamedType*>& definedTypes = getSortedDefinedTypes();
801 if (definedTypes.size() > 0 || userDefinedMethods().size() > 0) out << "\n";
802
803 out.join(definedTypes.begin(), definedTypes.end(), "\n",
804 [&](auto t) { t->emitHidlDefinition(out); });
805
806 if (definedTypes.size() > 0 && userDefinedMethods().size() > 0) out << "\n";
807
808 out.join(userDefinedMethods().begin(), userDefinedMethods().end(), "\n",
809 [&](auto method) { method->emitHidlDefinition(out); });
810 });
811
812 out << "};\n";
813 }
814
emitPackageTypeDeclarations(Formatter & out) const815 void Interface::emitPackageTypeDeclarations(Formatter& out) const {
816 Scope::emitPackageTypeDeclarations(out);
817
818 out << "static inline std::string toString(" << getCppArgumentType() << " o);\n\n";
819 }
820
emitPackageTypeHeaderDefinitions(Formatter & out) const821 void Interface::emitPackageTypeHeaderDefinitions(Formatter& out) const {
822 Scope::emitPackageTypeHeaderDefinitions(out);
823
824 out << "static inline std::string toString(" << getCppArgumentType() << " o) ";
825
826 out.block([&] {
827 out << "std::string os = \"[class or subclass of \";\n"
828 << "os += " << fullName() << "::descriptor;\n"
829 << "os += \"]\";\n"
830 << "os += o->isRemote() ? \"@remote\" : \"@local\";\n"
831 << "return os;\n";
832 }).endl().endl();
833 }
834
emitTypeDefinitions(Formatter & out,const std::string & prefix) const835 void Interface::emitTypeDefinitions(Formatter& out, const std::string& prefix) const {
836 std::string space = prefix.empty() ? "" : (prefix + "::");
837
838 Scope::emitTypeDefinitions(out, space + definedName());
839 }
840
emitJavaReaderWriter(Formatter & out,const std::string & parcelObj,const std::string & argName,bool isReader) const841 void Interface::emitJavaReaderWriter(
842 Formatter &out,
843 const std::string &parcelObj,
844 const std::string &argName,
845 bool isReader) const {
846 if (isReader) {
847 out << fullJavaName()
848 << ".asInterface("
849 << parcelObj
850 << ".readStrongBinder());\n";
851 } else {
852 out << parcelObj
853 << ".writeStrongBinder("
854 << argName
855 << " == null ? null : "
856 << argName
857 << ".asBinder());\n";
858 }
859 }
860
emitVtsAttributeDeclaration(Formatter & out) const861 void Interface::emitVtsAttributeDeclaration(Formatter& out) const {
862 for (const auto &type : getSubTypes()) {
863 // Skip for TypeDef as it is just an alias of a defined type.
864 if (type->isTypeDef()) {
865 continue;
866 }
867 out << "attribute: {\n";
868 out.indent();
869 type->emitVtsTypeDeclarations(out);
870 out.unindent();
871 out << "}\n\n";
872 }
873 }
874
emitVtsMethodDeclaration(Formatter & out,bool isInherited) const875 void Interface::emitVtsMethodDeclaration(Formatter& out, bool isInherited) const {
876 for (const auto &method : methods()) {
877 if (method->isHidlReserved()) {
878 continue;
879 }
880
881 out << "api: {\n";
882 out.indent();
883 out << "name: \"" << method->name() << "\"\n";
884 out << "is_inherited: " << (isInherited ? "true" : "false") << "\n";
885 // Generate declaration for each return value.
886 for (const auto &result : method->results()) {
887 out << "return_type_hidl: {\n";
888 out.indent();
889 out << "name: \"" << result->name() << "\"\n";
890 result->type().emitVtsAttributeType(out);
891 out.unindent();
892 out << "}\n";
893 }
894 // Generate declaration for each input argument
895 for (const auto &arg : method->args()) {
896 out << "arg: {\n";
897 out.indent();
898 out << "name: \"" << arg->name() << "\"\n";
899 arg->type().emitVtsAttributeType(out);
900 out.unindent();
901 out << "}\n";
902 }
903 // Generate declaration for each annotation.
904 for (const auto &annotation : method->annotations()) {
905 out << "callflow: {\n";
906 out.indent();
907 const std::string name = annotation->name();
908 if (name == "entry") {
909 out << "entry: true\n";
910 } else if (name == "exit") {
911 out << "exit: true\n";
912 } else if (name == "callflow") {
913 const AnnotationParam *param =
914 annotation->getParam("next");
915 if (param != nullptr) {
916 for (const auto& value : param->getValues()) {
917 out << "next: " << value << "\n";
918 }
919 }
920 } else {
921 CHECK(false);
922 }
923 out.unindent();
924 out << "}\n";
925 }
926 out.unindent();
927 out << "}\n\n";
928 }
929 }
930
emitVtsAttributeType(Formatter & out) const931 void Interface::emitVtsAttributeType(Formatter& out) const {
932 out << "type: " << getVtsType() << "\n"
933 << "predefined_type: \""
934 << fullName()
935 << "\"\n";
936 }
937
deepIsJavaCompatible(std::unordered_set<const Type * > * visited) const938 bool Interface::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const {
939 if (superType() != nullptr && !superType()->isJavaCompatible(visited)) {
940 return false;
941 }
942
943 for (const auto* method : methods()) {
944 if (!method->deepIsJavaCompatible(visited)) {
945 return false;
946 }
947 }
948
949 return Scope::deepIsJavaCompatible(visited);
950 }
951
isNeverStrongReference() const952 bool Interface::isNeverStrongReference() const {
953 return true;
954 }
955
956 const FQName gIBaseFqName = FQName("android.hidl.base", "1.0", "IBase");
957 const FQName gIManagerFqName = FQName("android.hidl.manager", "1.0", "IServiceManager");
958
959 } // namespace android
960
961