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