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 <unordered_map>
34
35 #include <android-base/logging.h>
36 #include <hidl-util/Formatter.h>
37 #include <hidl-util/StringHelper.h>
38
39 namespace android {
40
41 #define B_PACK_CHARS(c1, c2, c3, c4) \
42 ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4))
43
44 /* It is very important that these values NEVER change. These values
45 * must remain unchanged over the lifetime of android. This is
46 * because the framework on a device will be updated independently of
47 * the hals on a device. If the hals are compiled with one set of
48 * transaction values, and the framework with another, then the
49 * interface between them will be destroyed, and the device will not
50 * work.
51 */
52 enum {
53 /////////////////// User defined transactions
54 FIRST_CALL_TRANSACTION = 0x00000001,
55 LAST_CALL_TRANSACTION = 0x0effffff,
56 /////////////////// HIDL reserved
57 FIRST_HIDL_TRANSACTION = 0x0f000000,
58 HIDL_PING_TRANSACTION = B_PACK_CHARS(0x0f, 'P', 'N', 'G'),
59 HIDL_DESCRIPTOR_CHAIN_TRANSACTION = B_PACK_CHARS(0x0f, 'C', 'H', 'N'),
60 HIDL_GET_DESCRIPTOR_TRANSACTION = B_PACK_CHARS(0x0f, 'D', 'S', 'C'),
61 HIDL_SYSPROPS_CHANGED_TRANSACTION = B_PACK_CHARS(0x0f, 'S', 'Y', 'S'),
62 HIDL_LINK_TO_DEATH_TRANSACTION = B_PACK_CHARS(0x0f, 'L', 'T', 'D'),
63 HIDL_UNLINK_TO_DEATH_TRANSACTION = B_PACK_CHARS(0x0f, 'U', 'T', 'D'),
64 HIDL_SET_HAL_INSTRUMENTATION_TRANSACTION = B_PACK_CHARS(0x0f, 'I', 'N', 'T'),
65 HIDL_GET_REF_INFO_TRANSACTION = B_PACK_CHARS(0x0f, 'R', 'E', 'F'),
66 HIDL_DEBUG_TRANSACTION = B_PACK_CHARS(0x0f, 'D', 'B', 'G'),
67 HIDL_HASH_CHAIN_TRANSACTION = B_PACK_CHARS(0x0f, 'H', 'S', 'H'),
68 LAST_HIDL_TRANSACTION = 0x0fffffff,
69 };
70
Interface(const char * localName,const FQName & fullName,const Location & location,Scope * parent,const Reference<Type> & superType,const Hash * fileHash)71 Interface::Interface(const char* localName, const FQName& fullName, const Location& location,
72 Scope* parent, const Reference<Type>& superType, const Hash* fileHash)
73 : Scope(localName, fullName, location, parent), mSuperType(superType), mFileHash(fileHash) {}
74
typeName() const75 std::string Interface::typeName() const {
76 return "interface " + localName();
77 }
78
getFileHash() const79 const Hash* Interface::getFileHash() const {
80 return mFileHash;
81 }
82
fillPingMethod(Method * method) const83 bool Interface::fillPingMethod(Method *method) const {
84 if (method->name() != "ping") {
85 return false;
86 }
87
88 method->fillImplementation(
89 HIDL_PING_TRANSACTION,
90 {
91 {IMPL_INTERFACE,
92 [](auto &out) {
93 out << "return ::android::hardware::Void();\n";
94 }
95 },
96 {IMPL_STUB_IMPL,
97 [](auto &out) {
98 out << "return ::android::hardware::Void();\n";
99 }
100 }
101 }, /*cppImpl*/
102 {
103 {IMPL_INTERFACE,
104 [](auto &out) {
105 out << "return;\n";
106 }
107 },
108 } /*javaImpl*/
109 );
110
111 return true;
112 }
113
fillLinkToDeathMethod(Method * method) const114 bool Interface::fillLinkToDeathMethod(Method *method) const {
115 if (method->name() != "linkToDeath") {
116 return false;
117 }
118
119 method->fillImplementation(
120 HIDL_LINK_TO_DEATH_TRANSACTION,
121 {
122 {IMPL_INTERFACE,
123 [](auto &out) {
124 out << "(void)cookie;\n"
125 << "return (recipient != nullptr);\n";
126 }
127 },
128 {IMPL_PROXY,
129 [](auto &out) {
130 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
131 out << "::android::hardware::hidl_binder_death_recipient *binder_recipient"
132 << " = new ::android::hardware::hidl_binder_death_recipient(recipient, cookie, this);\n"
133 << "std::unique_lock<std::mutex> lock(_hidl_mMutex);\n"
134 << "_hidl_mDeathRecipients.push_back(binder_recipient);\n"
135 << "return (remote()->linkToDeath(binder_recipient)"
136 << " == ::android::OK);\n";
137 }
138 },
139 {IMPL_STUB, nullptr}
140 }, /*cppImpl*/
141 {
142 {IMPL_INTERFACE,
143 [](auto &out) {
144 out << "return true;";
145 }
146 },
147 {IMPL_PROXY,
148 [](auto &out) {
149 out << "return mRemote.linkToDeath(recipient, cookie);\n";
150 }
151 },
152 {IMPL_STUB, nullptr}
153 } /*javaImpl*/
154 );
155 return true;
156 }
157
fillUnlinkToDeathMethod(Method * method) const158 bool Interface::fillUnlinkToDeathMethod(Method *method) const {
159 if (method->name() != "unlinkToDeath") {
160 return false;
161 }
162
163 method->fillImplementation(
164 HIDL_UNLINK_TO_DEATH_TRANSACTION,
165 {
166 {IMPL_INTERFACE,
167 [](auto &out) {
168 out << "return (recipient != nullptr);\n";
169 }
170 },
171 {IMPL_PROXY,
172 [](auto &out) {
173 out << "std::unique_lock<std::mutex> lock(_hidl_mMutex);\n"
174 << "for (auto it = _hidl_mDeathRecipients.begin();"
175 << "it != _hidl_mDeathRecipients.end();"
176 << "++it) {\n";
177 out.indent([&] {
178 out.sIf("(*it)->getRecipient() == recipient", [&] {
179 out << "::android::status_t status = remote()->unlinkToDeath(*it);\n"
180 << "_hidl_mDeathRecipients.erase(it);\n"
181 << "return status == ::android::OK;\n";
182 });
183 });
184 out << "}\n";
185 out << "return false;\n";
186 }
187 },
188 {IMPL_STUB, nullptr /* don't generate code */}
189 }, /*cppImpl*/
190 {
191 {IMPL_INTERFACE,
192 [](auto &out) {
193 out << "return true;\n";
194 }
195 },
196 {IMPL_PROXY,
197 [](auto &out) {
198 out << "return mRemote.unlinkToDeath(recipient);\n";
199 }
200 },
201 {IMPL_STUB, nullptr /* don't generate code */}
202 } /*javaImpl*/
203 );
204 return true;
205 }
fillSyspropsChangedMethod(Method * method) const206 bool Interface::fillSyspropsChangedMethod(Method *method) const {
207 if (method->name() != "notifySyspropsChanged") {
208 return false;
209 }
210
211 method->fillImplementation(
212 HIDL_SYSPROPS_CHANGED_TRANSACTION,
213 { { IMPL_INTERFACE, [](auto &out) {
214 out << "::android::report_sysprop_change();\n";
215 out << "return ::android::hardware::Void();";
216 } } }, /*cppImpl */
217 { { IMPL_INTERFACE, [](auto &out) { /* javaImpl */
218 out << "android.os.HwBinder.enableInstrumentation();";
219 } } } /*javaImpl */
220 );
221 return true;
222 }
223
fillSetHALInstrumentationMethod(Method * method) const224 bool Interface::fillSetHALInstrumentationMethod(Method *method) const {
225 if (method->name() != "setHALInstrumentation") {
226 return false;
227 }
228
229 method->fillImplementation(
230 HIDL_SET_HAL_INSTRUMENTATION_TRANSACTION,
231 {
232 {IMPL_INTERFACE,
233 [](auto &out) {
234 // do nothing for base class.
235 out << "return ::android::hardware::Void();\n";
236 }
237 },
238 {IMPL_STUB,
239 [](auto &out) {
240 out << "configureInstrumentation();\n";
241 }
242 },
243 {IMPL_PASSTHROUGH,
244 [](auto &out) {
245 out << "configureInstrumentation();\n";
246 out << "return ::android::hardware::Void();\n";
247 }
248 },
249 }, /*cppImpl */
250 { { IMPL_INTERFACE, [](auto & /*out*/) { /* javaImpl */
251 // Not support for Java Impl for now.
252 } } } /*javaImpl */
253 );
254 return true;
255 }
256
fillDescriptorChainMethod(Method * method) const257 bool Interface::fillDescriptorChainMethod(Method *method) const {
258 if (method->name() != "interfaceChain") {
259 return false;
260 }
261
262 method->fillImplementation(
263 HIDL_DESCRIPTOR_CHAIN_TRANSACTION,
264 { { IMPL_INTERFACE, [this](auto &out) {
265 std::vector<const Interface *> chain = typeChain();
266 out << "_hidl_cb(";
267 out.block([&] {
268 for (const Interface *iface : chain) {
269 out << iface->fullName() << "::descriptor,\n";
270 }
271 });
272 out << ");\n";
273 out << "return ::android::hardware::Void();";
274 } } }, /* cppImpl */
275 { { IMPL_INTERFACE, [this](auto &out) {
276 std::vector<const Interface *> chain = typeChain();
277 out << "return new java.util.ArrayList<String>(java.util.Arrays.asList(\n";
278 out.indent(); out.indent();
279 for (size_t i = 0; i < chain.size(); ++i) {
280 if (i != 0)
281 out << ",\n";
282 out << chain[i]->fullJavaName() << ".kInterfaceName";
283 }
284 out << "));";
285 out.unindent(); out.unindent();
286 } } } /* javaImpl */
287 );
288 return true;
289 }
290
emitDigestChain(Formatter & out,const std::string & prefix,const std::vector<const Interface * > & chain,std::function<std::string (std::unique_ptr<ConstantExpression>)> byteToString) const291 void Interface::emitDigestChain(
292 Formatter& out, const std::string& prefix, const std::vector<const Interface*>& chain,
293 std::function<std::string(std::unique_ptr<ConstantExpression>)> byteToString) const {
294 out.join(chain.begin(), chain.end(), ",\n", [&](const auto& iface) {
295 out << prefix;
296 out << "{";
297 out.join(
298 iface->getFileHash()->raw().begin(), iface->getFileHash()->raw().end(), ",",
299 [&](const auto& e) {
300 // Use ConstantExpression::cppValue / javaValue
301 // because Java used signed byte for uint8_t.
302 out << byteToString(ConstantExpression::ValueOf(ScalarType::Kind::KIND_UINT8, e));
303 });
304 out << "} /* ";
305 out << iface->getFileHash()->hexString();
306 out << " */";
307 });
308 }
309
fillHashChainMethod(Method * method) const310 bool Interface::fillHashChainMethod(Method *method) const {
311 if (method->name() != "getHashChain") {
312 return false;
313 }
314 const VectorType *chainType = static_cast<const VectorType *>(&method->results()[0]->type());
315 const ArrayType *digestType = static_cast<const ArrayType *>(chainType->getElementType());
316
317 method->fillImplementation(
318 HIDL_HASH_CHAIN_TRANSACTION,
319 { { IMPL_INTERFACE, [this, digestType](auto &out) {
320 std::vector<const Interface *> chain = typeChain();
321 out << "_hidl_cb(";
322 out.block([&] {
323 emitDigestChain(out, "(" + digestType->getInternalDataCppType() + ")", chain,
324 [](const auto& e) { return e->cppValue(); });
325 });
326 out << ");\n";
327 out << "return ::android::hardware::Void();\n";
328 } } }, /* cppImpl */
329 { { IMPL_INTERFACE, [this, digestType, chainType](auto &out) {
330 std::vector<const Interface *> chain = typeChain();
331 out << "return new "
332 << chainType->getJavaType(false /* forInitializer */)
333 << "(java.util.Arrays.asList(\n";
334 out.indent(2, [&] {
335 // No need for dimensions when elements are explicitly provided.
336 emitDigestChain(out, "new " + digestType->getJavaType(false /* forInitializer */),
337 chain, [](const auto& e) { return e->javaValue(); });
338 });
339 out << "));\n";
340 } } } /* javaImpl */
341 );
342 return true;
343 }
344
fillGetDescriptorMethod(Method * method) const345 bool Interface::fillGetDescriptorMethod(Method *method) const {
346 if (method->name() != "interfaceDescriptor") {
347 return false;
348 }
349
350 method->fillImplementation(
351 HIDL_GET_DESCRIPTOR_TRANSACTION,
352 { { IMPL_INTERFACE, [this](auto &out) {
353 out << "_hidl_cb("
354 << fullName()
355 << "::descriptor);\n"
356 << "return ::android::hardware::Void();";
357 } } }, /* cppImpl */
358 { { IMPL_INTERFACE, [this](auto &out) {
359 out << "return "
360 << fullJavaName()
361 << ".kInterfaceName;\n";
362 } } } /* javaImpl */
363 );
364 return true;
365 }
366
fillGetDebugInfoMethod(Method * method) const367 bool Interface::fillGetDebugInfoMethod(Method *method) const {
368 if (method->name() != "getDebugInfo") {
369 return false;
370 }
371
372 static const std::string sArch =
373 "#if defined(__LP64__)\n"
374 "::android::hidl::base::V1_0::DebugInfo::Architecture::IS_64BIT\n"
375 "#else\n"
376 "::android::hidl::base::V1_0::DebugInfo::Architecture::IS_32BIT\n"
377 "#endif\n";
378
379 method->fillImplementation(
380 HIDL_GET_REF_INFO_TRANSACTION,
381 {
382 {IMPL_INTERFACE,
383 [](auto &out) {
384 // getDebugInfo returns N/A for local objects.
385 out << "::android::hidl::base::V1_0::DebugInfo info = {};\n";
386 out << "info.pid = -1;\n";
387 out << "info.ptr = 0;\n";
388 out << "info.arch = \n" << sArch << ";\n";
389 out << "_hidl_cb(info);\n";
390 out << "return ::android::hardware::Void();\n";
391 }
392 },
393 {IMPL_STUB_IMPL,
394 [](auto &out) {
395 out << "::android::hidl::base::V1_0::DebugInfo info = {};\n";
396 out << "info.pid = ::android::hardware::details::getPidIfSharable();\n";
397 out << "info.ptr = ::android::hardware::details::debuggable()"
398 << "? reinterpret_cast<uint64_t>(this) : 0;\n";
399 out << "info.arch = \n" << sArch << ";\n";
400 out << "_hidl_cb(info);\n";
401 out << "return ::android::hardware::Void();\n";
402 }
403 }
404 }, /* cppImpl */
405 { { IMPL_INTERFACE, [method](auto &out) {
406 const Type &refInfo = method->results().front()->type();
407 out << refInfo.getJavaType(false /* forInitializer */) << " info = new "
408 << refInfo.getJavaType(true /* forInitializer */) << "();\n"
409 << "info.pid = android.os.HidlSupport.getPidIfSharable();\n"
410 << "info.ptr = 0;\n"
411 << "info.arch = android.hidl.base.V1_0.DebugInfo.Architecture.UNKNOWN;\n"
412 << "return info;";
413 } } } /* javaImpl */
414 );
415
416 return true;
417 }
418
fillDebugMethod(Method * method) const419 bool Interface::fillDebugMethod(Method *method) const {
420 if (method->name() != "debug") {
421 return false;
422 }
423
424 method->fillImplementation(
425 HIDL_DEBUG_TRANSACTION,
426 {
427 {IMPL_INTERFACE,
428 [](auto &out) {
429 out << "(void)fd;\n"
430 << "(void)options;\n"
431 << "return ::android::hardware::Void();";
432 }
433 },
434 }, /* cppImpl */
435 {
436 /* unused, as the debug method is hidden from Java */
437 } /* javaImpl */
438 );
439
440 return true;
441 }
442
443 static std::map<std::string, Method *> gAllReservedMethods;
444
addMethod(Method * method)445 bool Interface::addMethod(Method *method) {
446 if (isIBase()) {
447 if (!gAllReservedMethods.emplace(method->name(), method).second) {
448 std::cerr << "ERROR: hidl-gen encountered duplicated reserved method " << method->name()
449 << std::endl;
450 return false;
451 }
452 // will add it in addAllReservedMethods
453 return true;
454 }
455
456 CHECK(!method->isHidlReserved());
457 mUserMethods.push_back(method);
458
459 return true;
460 }
461
getReferences() const462 std::vector<const Reference<Type>*> Interface::getReferences() const {
463 std::vector<const Reference<Type>*> ret;
464
465 if (!isIBase()) {
466 ret.push_back(&mSuperType);
467 }
468
469 for (const auto* method : methods()) {
470 const auto& references = method->getReferences();
471 ret.insert(ret.end(), references.begin(), references.end());
472 }
473
474 return ret;
475 }
476
getConstantExpressions() const477 std::vector<const ConstantExpression*> Interface::getConstantExpressions() const {
478 std::vector<const ConstantExpression*> ret;
479 for (const auto* method : methods()) {
480 const auto& retMethod = method->getConstantExpressions();
481 ret.insert(ret.end(), retMethod.begin(), retMethod.end());
482 }
483 return ret;
484 }
485
getStrongReferences() const486 std::vector<const Reference<Type>*> Interface::getStrongReferences() const {
487 // Interface is a special case as a reference:
488 // its definiton must be completed for extension but
489 // not necessary for other references.
490
491 std::vector<const Reference<Type>*> ret;
492 if (!isIBase()) {
493 ret.push_back(&mSuperType);
494 }
495
496 for (const auto* method : methods()) {
497 const auto& references = method->getStrongReferences();
498 ret.insert(ret.end(), references.begin(), references.end());
499 }
500
501 return ret;
502 }
503
resolveInheritance()504 status_t Interface::resolveInheritance() {
505 size_t serial = FIRST_CALL_TRANSACTION;
506 for (const auto* ancestor : superTypeChain()) {
507 serial += ancestor->mUserMethods.size();
508 }
509
510 for (Method* method : mUserMethods) {
511 if (serial > LAST_CALL_TRANSACTION) {
512 std::cerr << "ERROR: More than " << LAST_CALL_TRANSACTION
513 << " methods (including super and reserved) are not allowed at " << location()
514 << std::endl;
515 return UNKNOWN_ERROR;
516 }
517
518 method->setSerialId(serial);
519 serial++;
520 }
521
522 return Scope::resolveInheritance();
523 }
524
validate() const525 status_t Interface::validate() const {
526 CHECK(isIBase() == mSuperType.isEmptyReference());
527
528 if (!isIBase() && !mSuperType->isInterface()) {
529 std::cerr << "ERROR: You can only extend interfaces at " << mSuperType.location()
530 << std::endl;
531 return UNKNOWN_ERROR;
532 }
533
534 status_t err;
535
536 err = validateUniqueNames();
537 if (err != OK) return err;
538
539 err = validateAnnotations();
540 if (err != OK) return err;
541
542 return Scope::validate();
543 }
544
getAlignmentAndSize(size_t * align,size_t * size) const545 void Interface::getAlignmentAndSize(size_t* align, size_t* size) const {
546 *align = 8;
547 *size = 8;
548 }
549
validateUniqueNames() const550 status_t Interface::validateUniqueNames() const {
551 std::unordered_map<std::string, const Interface*> registeredMethodNames;
552 for (auto const& tuple : allSuperMethodsFromRoot()) {
553 // No need to check super method uniqueness
554 registeredMethodNames[tuple.method()->name()] = tuple.interface();
555 }
556
557 for (const Method* method : mUserMethods) {
558 auto registered = registeredMethodNames.find(method->name());
559
560 if (registered != registeredMethodNames.end()) {
561 const Interface* definedInType = registered->second;
562
563 if (definedInType == this) {
564 // Defined in this interface
565 std::cerr << "ERROR: Redefinition of method '" << method->name() << "'";
566 } else if (definedInType->isIBase()) {
567 // Defined in IBase
568 std::cerr << "ERROR: Redefinition of reserved method '" << method->name() << "'";
569 } else {
570 // Defined in super not IBase
571 std::cerr << "ERROR: Redefinition of method '" << method->name()
572 << "' defined in interface '" << definedInType->fullName() << "'";
573 }
574 std::cerr << " at " << method->location() << std::endl;
575 return UNKNOWN_ERROR;
576 }
577
578 registeredMethodNames[method->name()] = this;
579 }
580
581 return OK;
582 }
583
validateAnnotations() const584 status_t Interface::validateAnnotations() const {
585 for (const Method* method : methods()) {
586 for (const Annotation* annotation : method->annotations()) {
587 const std::string name = annotation->name();
588
589 if (name == "entry" || name == "exit" || name == "callflow") {
590 continue;
591 }
592
593 std::cerr << "ERROR: Unrecognized annotation '" << name
594 << "' for method: " << method->name() << ". An annotation should be one of: "
595 << "entry, exit, callflow." << std::endl;
596 return UNKNOWN_ERROR;
597 }
598 }
599 return OK;
600 }
601
addAllReservedMethods()602 bool Interface::addAllReservedMethods() {
603 // use a sorted map to insert them in serial ID order.
604 std::map<int32_t, Method *> reservedMethodsById;
605 for (const auto &pair : gAllReservedMethods) {
606 Method *method = pair.second->copySignature();
607 bool fillSuccess = fillPingMethod(method)
608 || fillDescriptorChainMethod(method)
609 || fillGetDescriptorMethod(method)
610 || fillHashChainMethod(method)
611 || fillSyspropsChangedMethod(method)
612 || fillLinkToDeathMethod(method)
613 || fillUnlinkToDeathMethod(method)
614 || fillSetHALInstrumentationMethod(method)
615 || fillGetDebugInfoMethod(method)
616 || fillDebugMethod(method);
617
618 if (!fillSuccess) {
619 std::cerr << "ERROR: hidl-gen does not recognize a reserved method " << method->name()
620 << std::endl;
621 return false;
622 }
623 if (!reservedMethodsById.emplace(method->getSerialId(), method).second) {
624 std::cerr << "ERROR: hidl-gen uses duplicated serial id for " << method->name()
625 << " and " << reservedMethodsById[method->getSerialId()]->name()
626 << ", serialId = " << method->getSerialId() << std::endl;
627 return false;
628 }
629 }
630 for (const auto &pair : reservedMethodsById) {
631 this->mReservedMethods.push_back(pair.second);
632 }
633 return true;
634 }
635
superType() const636 const Interface* Interface::superType() const {
637 if (isIBase()) return nullptr;
638 if (!mSuperType->isInterface()) {
639 // This is actually an error
640 // that would be caught in validate
641 return nullptr;
642 }
643 return static_cast<const Interface*>(mSuperType.get());
644 }
645
typeChain() const646 std::vector<const Interface *> Interface::typeChain() const {
647 std::vector<const Interface *> v;
648 const Interface *iface = this;
649 while (iface != nullptr) {
650 v.push_back(iface);
651 iface = iface->superType();
652 }
653 return v;
654 }
655
superTypeChain() const656 std::vector<const Interface *> Interface::superTypeChain() const {
657 return isIBase() ? std::vector<const Interface*>() : superType()->typeChain();
658 }
659
isElidableType() const660 bool Interface::isElidableType() const {
661 return true;
662 }
663
isInterface() const664 bool Interface::isInterface() const {
665 return true;
666 }
667
isBinder() const668 bool Interface::isBinder() const {
669 return true;
670 }
671
userDefinedMethods() const672 const std::vector<Method *> &Interface::userDefinedMethods() const {
673 return mUserMethods;
674 }
675
hidlReservedMethods() const676 const std::vector<Method *> &Interface::hidlReservedMethods() const {
677 return mReservedMethods;
678 }
679
methods() const680 std::vector<Method *> Interface::methods() const {
681 std::vector<Method *> v(mUserMethods);
682 v.insert(v.end(), mReservedMethods.begin(), mReservedMethods.end());
683 return v;
684 }
685
allMethodsFromRoot() const686 std::vector<InterfaceAndMethod> Interface::allMethodsFromRoot() const {
687 std::vector<InterfaceAndMethod> v;
688 std::vector<const Interface *> chain = typeChain();
689 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
690 const Interface *iface = *it;
691 for (Method *userMethod : iface->userDefinedMethods()) {
692 v.push_back(InterfaceAndMethod(iface, userMethod));
693 }
694 }
695 for (Method *reservedMethod : hidlReservedMethods()) {
696 v.push_back(InterfaceAndMethod(
697 *chain.rbegin(), // IBase
698 reservedMethod));
699 }
700 return v;
701 }
702
allSuperMethodsFromRoot() const703 std::vector<InterfaceAndMethod> Interface::allSuperMethodsFromRoot() const {
704 return isIBase() ? std::vector<InterfaceAndMethod>() : superType()->allMethodsFromRoot();
705 }
706
getBaseName() const707 std::string Interface::getBaseName() const {
708 return fqName().getInterfaceBaseName();
709 }
710
getAdapterName() const711 std::string Interface::getAdapterName() const {
712 return fqName().getInterfaceAdapterName();
713 }
714
getProxyName() const715 std::string Interface::getProxyName() const {
716 return fqName().getInterfaceProxyName();
717 }
718
getStubName() const719 std::string Interface::getStubName() const {
720 return fqName().getInterfaceStubName();
721 }
722
getHwName() const723 std::string Interface::getHwName() const {
724 return fqName().getInterfaceHwName();
725 }
726
getPassthroughName() const727 std::string Interface::getPassthroughName() const {
728 return fqName().getInterfacePassthroughName();
729 }
730
getProxyFqName() const731 FQName Interface::getProxyFqName() const {
732 return fqName().getInterfaceProxyFqName();
733 }
734
getStubFqName() const735 FQName Interface::getStubFqName() const {
736 return fqName().getInterfaceStubFqName();
737 }
738
getPassthroughFqName() const739 FQName Interface::getPassthroughFqName() const {
740 return fqName().getInterfacePassthroughFqName();
741 }
742
getCppType(StorageMode mode,bool specifyNamespaces) const743 std::string Interface::getCppType(StorageMode mode,
744 bool specifyNamespaces) const {
745 const std::string base =
746 std::string(specifyNamespaces ? "::android::" : "")
747 + "sp<"
748 + fullName()
749 + ">";
750
751 switch (mode) {
752 case StorageMode_Stack:
753 case StorageMode_Result:
754 return base;
755
756 case StorageMode_Argument:
757 return "const " + base + "&";
758 }
759 }
760
getJavaType(bool) const761 std::string Interface::getJavaType(bool /* forInitializer */) const {
762 return fullJavaName();
763 }
764
getVtsType() const765 std::string Interface::getVtsType() const {
766 if (StringHelper::EndsWith(localName(), "Callback")) {
767 return "TYPE_HIDL_CALLBACK";
768 } else {
769 return "TYPE_HIDL_INTERFACE";
770 }
771 }
772
emitReaderWriter(Formatter & out,const std::string & name,const std::string & parcelObj,bool parcelObjIsPointer,bool isReader,ErrorMode mode) const773 void Interface::emitReaderWriter(
774 Formatter &out,
775 const std::string &name,
776 const std::string &parcelObj,
777 bool parcelObjIsPointer,
778 bool isReader,
779 ErrorMode mode) const {
780 const std::string parcelObjDeref =
781 parcelObj + (parcelObjIsPointer ? "->" : ".");
782
783 if (isReader) {
784 out << "{\n";
785 out.indent();
786
787 const std::string binderName = "_hidl_binder";
788 out << "::android::sp<::android::hardware::IBinder> "
789 << binderName << ";\n";
790
791 out << "_hidl_err = ";
792 out << parcelObjDeref
793 << "readNullableStrongBinder(&"
794 << binderName
795 << ");\n";
796
797 handleError(out, mode);
798
799 out << name
800 << " = "
801 << "::android::hardware::fromBinder<"
802 << fqName().cppName()
803 << ","
804 << getProxyFqName().cppName()
805 << ","
806 << getStubFqName().cppName()
807 << ">("
808 << binderName
809 << ");\n";
810
811 out.unindent();
812 out << "}\n\n";
813 } else {
814 out << "if (" << name << " == nullptr) {\n";
815 out.indent();
816 out << "_hidl_err = ";
817 out << parcelObjDeref
818 << "writeStrongBinder(nullptr);\n";
819 out.unindent();
820 out << "} else {\n";
821 out.indent();
822 out << "::android::sp<::android::hardware::IBinder> _hidl_binder = "
823 << "::android::hardware::toBinder<\n";
824 out.indent(2, [&] {
825 out << fqName().cppName()
826 << ">("
827 << name
828 << ");\n";
829 });
830 out << "if (_hidl_binder.get() != nullptr) {\n";
831 out.indent([&] {
832 out << "_hidl_err = "
833 << parcelObjDeref
834 << "writeStrongBinder(_hidl_binder);\n";
835 });
836 out << "} else {\n";
837 out.indent([&] {
838 out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
839 });
840 out << "}\n";
841 out.unindent();
842 out << "}\n";
843
844 handleError(out, mode);
845 }
846 }
847
emitPackageTypeDeclarations(Formatter & out) const848 void Interface::emitPackageTypeDeclarations(Formatter& out) const {
849 Scope::emitPackageTypeDeclarations(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 + localName());
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) const902 void Interface::emitVtsMethodDeclaration(Formatter& out) 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 // Generate declaration for each return value.
912 for (const auto &result : method->results()) {
913 out << "return_type_hidl: {\n";
914 out.indent();
915 result->type().emitVtsAttributeType(out);
916 out.unindent();
917 out << "}\n";
918 }
919 // Generate declaration for each input argument
920 for (const auto &arg : method->args()) {
921 out << "arg: {\n";
922 out.indent();
923 arg->type().emitVtsAttributeType(out);
924 out.unindent();
925 out << "}\n";
926 }
927 // Generate declaration for each annotation.
928 for (const auto &annotation : method->annotations()) {
929 out << "callflow: {\n";
930 out.indent();
931 const std::string name = annotation->name();
932 if (name == "entry") {
933 out << "entry: true\n";
934 } else if (name == "exit") {
935 out << "exit: true\n";
936 } else if (name == "callflow") {
937 const AnnotationParam *param =
938 annotation->getParam("next");
939 if (param != nullptr) {
940 for (const auto& value : param->getValues()) {
941 out << "next: " << value << "\n";
942 }
943 }
944 } else {
945 CHECK(false);
946 }
947 out.unindent();
948 out << "}\n";
949 }
950 out.unindent();
951 out << "}\n\n";
952 }
953 }
954
emitVtsAttributeType(Formatter & out) const955 void Interface::emitVtsAttributeType(Formatter& out) const {
956 out << "type: " << getVtsType() << "\n"
957 << "predefined_type: \""
958 << fullName()
959 << "\"\n";
960 }
961
hasOnewayMethods() const962 bool Interface::hasOnewayMethods() const {
963 for (auto const &method : methods()) {
964 if (method->isOneway()) {
965 return true;
966 }
967 }
968
969 const Interface* superClass = superType();
970
971 if (superClass != nullptr) {
972 return superClass->hasOnewayMethods();
973 }
974
975 return false;
976 }
977
deepIsJavaCompatible(std::unordered_set<const Type * > * visited) const978 bool Interface::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const {
979 if (superType() != nullptr && !superType()->isJavaCompatible(visited)) {
980 return false;
981 }
982
983 for (const auto* method : methods()) {
984 if (!method->deepIsJavaCompatible(visited)) {
985 return false;
986 }
987 }
988
989 return Scope::isJavaCompatible(visited);
990 }
991
isNeverStrongReference() const992 bool Interface::isNeverStrongReference() const {
993 return true;
994 }
995
996 } // namespace android
997
998