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