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 "
311 << chainType->getJavaType(false /* forInitializer */)
312 << "(java.util.Arrays.asList(\n";
313 out.indent(2, [&] {
314 // No need for dimensions when elements are explicitly provided.
315 emitDigestChain(out, "new " + digestType->getJavaType(false /* forInitializer */),
316 chain, [](const auto& e) { return e->javaValue(); });
317 });
318 out << "));\n";
319 } } } /* javaImpl */
320 );
321 return true;
322 }
323
fillGetDescriptorMethod(Method * method) const324 bool Interface::fillGetDescriptorMethod(Method *method) const {
325 if (method->name() != "interfaceDescriptor") {
326 return false;
327 }
328
329 method->fillImplementation(
330 hardware::IBinder::HIDL_GET_DESCRIPTOR_TRANSACTION,
331 { { IMPL_INTERFACE, [this](auto &out) {
332 out << "_hidl_cb("
333 << fullName()
334 << "::descriptor);\n"
335 << "return ::android::hardware::Void();\n";
336 } } }, /* cppImpl */
337 { { IMPL_INTERFACE, [this](auto &out) {
338 out << "return "
339 << fullJavaName()
340 << ".kInterfaceName;\n";
341 } } } /* javaImpl */
342 );
343 return true;
344 }
345
fillGetDebugInfoMethod(Method * method) const346 bool Interface::fillGetDebugInfoMethod(Method *method) const {
347 if (method->name() != "getDebugInfo") {
348 return false;
349 }
350
351 static const std::string sArch =
352 "#if defined(__LP64__)\n"
353 "::android::hidl::base::V1_0::DebugInfo::Architecture::IS_64BIT\n"
354 "#else\n"
355 "::android::hidl::base::V1_0::DebugInfo::Architecture::IS_32BIT\n"
356 "#endif\n";
357
358 method->fillImplementation(
359 hardware::IBinder::HIDL_GET_REF_INFO_TRANSACTION,
360 {
361 {IMPL_INTERFACE,
362 [](auto &out) {
363 // getDebugInfo returns N/A for local objects.
364 out << "::android::hidl::base::V1_0::DebugInfo info = {};\n";
365 out << "info.pid = -1;\n";
366 out << "info.ptr = 0;\n";
367 out << "info.arch = \n" << sArch << ";\n";
368 out << "_hidl_cb(info);\n";
369 out << "return ::android::hardware::Void();\n";
370 }
371 },
372 {IMPL_STUB_IMPL,
373 [](auto &out) {
374 out << "::android::hidl::base::V1_0::DebugInfo info = {};\n";
375 out << "info.pid = ::android::hardware::details::getPidIfSharable();\n";
376 out << "info.ptr = ::android::hardware::details::debuggable()"
377 << "? reinterpret_cast<uint64_t>(this) : 0;\n";
378 out << "info.arch = \n" << sArch << ";\n";
379 out << "_hidl_cb(info);\n";
380 out << "return ::android::hardware::Void();\n";
381 }
382 }
383 }, /* cppImpl */
384 { { IMPL_INTERFACE, [method](auto &out) {
385 const Type &refInfo = method->results().front()->type();
386 out << refInfo.getJavaType(false /* forInitializer */) << " info = new "
387 << refInfo.getJavaType(true /* forInitializer */) << "();\n"
388 << "info.pid = android.os.HidlSupport.getPidIfSharable();\n"
389 << "info.ptr = 0;\n"
390 << "info.arch = android.hidl.base.V1_0.DebugInfo.Architecture.UNKNOWN;\n"
391 << "return info;\n";
392 } } } /* javaImpl */
393 );
394
395 return true;
396 }
397
fillDebugMethod(Method * method) const398 bool Interface::fillDebugMethod(Method *method) const {
399 if (method->name() != "debug") {
400 return false;
401 }
402
403 method->fillImplementation(hardware::IBinder::HIDL_DEBUG_TRANSACTION,
404 {
405 {IMPL_INTERFACE,
406 [](auto& out) {
407 out << "(void)fd;\n"
408 << "(void)options;\n"
409 << "return ::android::hardware::Void();\n";
410 }},
411 }, /* cppImpl */
412 {
413 {IMPL_INTERFACE, [](auto& out) { out << "return;\n"; }},
414 } /* javaImpl */
415 );
416
417 return true;
418 }
419
addUserDefinedMethod(Method * method)420 void Interface::addUserDefinedMethod(Method* method) {
421 CHECK(!method->isHidlReserved());
422 mUserMethods.push_back(method);
423 }
424
getReferences() const425 std::vector<const Reference<Type>*> Interface::getReferences() const {
426 std::vector<const Reference<Type>*> ret;
427
428 if (!isIBase()) {
429 ret.push_back(&mSuperType);
430 }
431
432 for (const auto* method : methods()) {
433 const auto& references = method->getReferences();
434 ret.insert(ret.end(), references.begin(), references.end());
435 }
436
437 return ret;
438 }
439
getStrongReferences() const440 std::vector<const Reference<Type>*> Interface::getStrongReferences() const {
441 // Interface is a special case as a reference:
442 // its definiton must be completed for extension but
443 // not necessary for other references.
444
445 std::vector<const Reference<Type>*> ret;
446 if (!isIBase()) {
447 ret.push_back(&mSuperType);
448 }
449
450 for (const auto* method : methods()) {
451 const auto& references = method->getStrongReferences();
452 ret.insert(ret.end(), references.begin(), references.end());
453 }
454
455 return ret;
456 }
457
resolveInheritance()458 status_t Interface::resolveInheritance() {
459 size_t serial = hardware::IBinder::FIRST_CALL_TRANSACTION;
460 for (const auto* ancestor : superTypeChain()) {
461 serial += ancestor->mUserMethods.size();
462 }
463
464 for (Method* method : mUserMethods) {
465 if (serial > hardware::IBinder::LAST_CALL_TRANSACTION) {
466 std::cerr << "ERROR: More than " << hardware::IBinder::LAST_CALL_TRANSACTION
467 << " methods (including super and reserved) are not allowed at " << location()
468 << std::endl;
469 return UNKNOWN_ERROR;
470 }
471
472 method->setSerialId(serial);
473 serial++;
474 }
475
476 return Scope::resolveInheritance();
477 }
478
validate() const479 status_t Interface::validate() const {
480 CHECK(isIBase() == mSuperType.isEmptyReference());
481
482 if (!isIBase() && !mSuperType->isInterface()) {
483 std::cerr << "ERROR: You can only extend interfaces at " << mSuperType.location()
484 << std::endl;
485 return UNKNOWN_ERROR;
486 }
487
488 status_t err;
489
490 err = validateUniqueNames();
491 if (err != OK) return err;
492
493 return Scope::validate();
494 }
495
getAlignmentAndSize(size_t * align,size_t * size) const496 void Interface::getAlignmentAndSize(size_t* align, size_t* size) const {
497 *align = 8;
498 *size = 8;
499 }
500
validateUniqueNames() const501 status_t Interface::validateUniqueNames() const {
502 std::unordered_map<std::string, const Interface*> registeredMethodNames;
503 for (auto const& tuple : allSuperMethodsFromRoot()) {
504 // No need to check super method uniqueness
505 registeredMethodNames[tuple.method()->name()] = tuple.interface();
506 }
507
508 for (const Method* method : mUserMethods) {
509 auto registered = registeredMethodNames.find(method->name());
510
511 if (registered != registeredMethodNames.end()) {
512 const Interface* definedInType = registered->second;
513
514 if (definedInType == this) {
515 // Defined in this interface
516 std::cerr << "ERROR: Redefinition of method '" << method->name() << "'";
517 } else if (definedInType->isIBase()) {
518 // Defined in IBase
519 std::cerr << "ERROR: Redefinition of reserved method '" << method->name() << "'";
520 } else {
521 // Defined in super not IBase
522 std::cerr << "ERROR: Redefinition of method '" << method->name()
523 << "' defined in interface '" << definedInType->fullName() << "'";
524 }
525 std::cerr << " at " << method->location() << std::endl;
526 return UNKNOWN_ERROR;
527 }
528
529 registeredMethodNames[method->name()] = this;
530 }
531
532 return OK;
533 }
534
validateAnnotations() const535 status_t Interface::validateAnnotations() const {
536 for (const Annotation* annotation : annotations()) {
537 const std::string name = annotation->name();
538
539 if (name == "SensitiveData") {
540 continue;
541 }
542
543 std::cerr << "WARNING: Unrecognized annotation '" << name << "' for " << typeName()
544 << " at " << location() << ". Only @SensitiveData is supported." << std::endl;
545 // ideally would be error, but we don't want to break downstream
546 // return UNKNOWN_ERROR;
547 }
548
549 for (const Method* method : methods()) {
550 for (const Annotation* annotation : method->annotations()) {
551 const std::string name = annotation->name();
552
553 if (name == "entry" || name == "exit" || name == "callflow") {
554 continue;
555 }
556
557 std::cerr << "ERROR: Unrecognized annotation '" << name
558 << "' for method: " << method->name() << " at " << method->location()
559 << ". An annotation should be one of: "
560 << "@entry, @exit, or @callflow." << std::endl;
561 return UNKNOWN_ERROR;
562 }
563 }
564 return OK; // not calling superclass which is more restrictive
565 }
566
addAllReservedMethods(const std::map<std::string,Method * > & allReservedMethods)567 bool Interface::addAllReservedMethods(const std::map<std::string, Method*>& allReservedMethods) {
568 // use a sorted map to insert them in serial ID order.
569 std::map<int32_t, Method *> reservedMethodsById;
570 for (const auto& pair : allReservedMethods) {
571 Method *method = pair.second->copySignature();
572 bool fillSuccess = fillPingMethod(method)
573 || fillDescriptorChainMethod(method)
574 || fillGetDescriptorMethod(method)
575 || fillHashChainMethod(method)
576 || fillSyspropsChangedMethod(method)
577 || fillLinkToDeathMethod(method)
578 || fillUnlinkToDeathMethod(method)
579 || fillSetHALInstrumentationMethod(method)
580 || fillGetDebugInfoMethod(method)
581 || fillDebugMethod(method);
582
583 if (!fillSuccess) {
584 std::cerr << "ERROR: hidl-gen does not recognize a reserved method " << method->name()
585 << std::endl;
586 return false;
587 }
588 if (!reservedMethodsById.emplace(method->getSerialId(), method).second) {
589 std::cerr << "ERROR: hidl-gen uses duplicated serial id for " << method->name()
590 << " and " << reservedMethodsById[method->getSerialId()]->name()
591 << ", serialId = " << method->getSerialId() << std::endl;
592 return false;
593 }
594 }
595 for (const auto &pair : reservedMethodsById) {
596 this->mReservedMethods.push_back(pair.second);
597 }
598 return true;
599 }
600
hasSensitiveDataAnnotation() const601 bool Interface::hasSensitiveDataAnnotation() const {
602 for (const auto& annotation : annotations()) {
603 if (annotation->name() == "SensitiveData") {
604 return true;
605 }
606 }
607
608 return false;
609 }
610
superType() const611 const Interface* Interface::superType() const {
612 if (isIBase()) return nullptr;
613 if (!mSuperType->isInterface()) {
614 // This is actually an error
615 // that would be caught in validate
616 return nullptr;
617 }
618 return static_cast<const Interface*>(mSuperType.get());
619 }
620
typeChain() const621 std::vector<const Interface *> Interface::typeChain() const {
622 std::vector<const Interface *> v;
623 const Interface *iface = this;
624 while (iface != nullptr) {
625 v.push_back(iface);
626 iface = iface->superType();
627 }
628 return v;
629 }
630
superTypeChain() const631 std::vector<const Interface *> Interface::superTypeChain() const {
632 return isIBase() ? std::vector<const Interface*>() : superType()->typeChain();
633 }
634
isElidableType() const635 bool Interface::isElidableType() const {
636 return true;
637 }
638
isInterface() const639 bool Interface::isInterface() const {
640 return true;
641 }
642
userDefinedMethods() const643 const std::vector<Method *> &Interface::userDefinedMethods() const {
644 return mUserMethods;
645 }
646
hidlReservedMethods() const647 const std::vector<Method *> &Interface::hidlReservedMethods() const {
648 return mReservedMethods;
649 }
650
methods() const651 std::vector<Method *> Interface::methods() const {
652 std::vector<Method *> v(mUserMethods);
653 v.insert(v.end(), mReservedMethods.begin(), mReservedMethods.end());
654 return v;
655 }
656
allMethodsFromRoot() const657 std::vector<InterfaceAndMethod> Interface::allMethodsFromRoot() const {
658 std::vector<InterfaceAndMethod> v;
659 std::vector<const Interface *> chain = typeChain();
660 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
661 const Interface *iface = *it;
662 for (Method *userMethod : iface->userDefinedMethods()) {
663 v.push_back(InterfaceAndMethod(iface, userMethod));
664 }
665 }
666 for (Method *reservedMethod : hidlReservedMethods()) {
667 v.push_back(InterfaceAndMethod(
668 *chain.rbegin(), // IBase
669 reservedMethod));
670 }
671 return v;
672 }
673
allSuperMethodsFromRoot() const674 std::vector<InterfaceAndMethod> Interface::allSuperMethodsFromRoot() const {
675 return isIBase() ? std::vector<InterfaceAndMethod>() : superType()->allMethodsFromRoot();
676 }
677
getBaseName() const678 std::string Interface::getBaseName() const {
679 return fqName().getInterfaceBaseName();
680 }
681
getAdapterName() const682 std::string Interface::getAdapterName() const {
683 return fqName().getInterfaceAdapterName();
684 }
685
getProxyName() const686 std::string Interface::getProxyName() const {
687 return fqName().getInterfaceProxyName();
688 }
689
getStubName() const690 std::string Interface::getStubName() const {
691 return fqName().getInterfaceStubName();
692 }
693
getHwName() const694 std::string Interface::getHwName() const {
695 return fqName().getInterfaceHwName();
696 }
697
getPassthroughName() const698 std::string Interface::getPassthroughName() const {
699 return fqName().getInterfacePassthroughName();
700 }
701
getProxyFqName() const702 FQName Interface::getProxyFqName() const {
703 return fqName().getInterfaceProxyFqName();
704 }
705
getStubFqName() const706 FQName Interface::getStubFqName() const {
707 return fqName().getInterfaceStubFqName();
708 }
709
getPassthroughFqName() const710 FQName Interface::getPassthroughFqName() const {
711 return fqName().getInterfacePassthroughFqName();
712 }
713
getCppType(StorageMode mode,bool specifyNamespaces) const714 std::string Interface::getCppType(StorageMode mode,
715 bool specifyNamespaces) const {
716 const std::string base =
717 std::string(specifyNamespaces ? "::android::" : "")
718 + "sp<"
719 + fullName()
720 + ">";
721
722 switch (mode) {
723 case StorageMode_Stack:
724 case StorageMode_Result:
725 return base;
726
727 case StorageMode_Argument:
728 return "const " + base + "&";
729 }
730 }
731
getJavaType(bool) const732 std::string Interface::getJavaType(bool /* forInitializer */) const {
733 return fullJavaName();
734 }
735
getVtsType() const736 std::string Interface::getVtsType() const {
737 if (StringHelper::EndsWith(definedName(), "Callback")) {
738 return "TYPE_HIDL_CALLBACK";
739 } else {
740 return "TYPE_HIDL_INTERFACE";
741 }
742 }
743
emitReaderWriter(Formatter & out,const std::string & name,const std::string & parcelObj,bool parcelObjIsPointer,bool isReader,ErrorMode mode) const744 void Interface::emitReaderWriter(
745 Formatter &out,
746 const std::string &name,
747 const std::string &parcelObj,
748 bool parcelObjIsPointer,
749 bool isReader,
750 ErrorMode mode) const {
751 const std::string parcelObjDeref =
752 parcelObj + (parcelObjIsPointer ? "->" : ".");
753
754 if (isReader) {
755 out << "{\n";
756 out.indent();
757
758 const std::string binderName = "_hidl_binder";
759 out << "::android::sp<::android::hardware::IBinder> "
760 << binderName << ";\n";
761
762 out << "_hidl_err = ";
763 out << parcelObjDeref
764 << "readNullableStrongBinder(&"
765 << binderName
766 << ");\n";
767
768 handleError(out, mode);
769
770 out << name
771 << " = "
772 << "::android::hardware::fromBinder<"
773 << fqName().cppName()
774 << ","
775 << getProxyFqName().cppName()
776 << ","
777 << getStubFqName().cppName()
778 << ">("
779 << binderName
780 << ");\n";
781
782 out.unindent();
783 out << "}\n\n";
784 } else {
785 out << "if (" << name << " == nullptr) {\n";
786 out.indent();
787 out << "_hidl_err = ";
788 out << parcelObjDeref
789 << "writeStrongBinder(nullptr);\n";
790 out.unindent();
791 out << "} else {\n";
792 out.indent();
793 out << "::android::sp<::android::hardware::IBinder> _hidl_binder = "
794 << "::android::hardware::getOrCreateCachedBinder(" << name << ".get());\n";
795 out << "if (_hidl_binder.get() != nullptr) {\n";
796 out.indent([&] {
797 out << "_hidl_err = "
798 << parcelObjDeref
799 << "writeStrongBinder(_hidl_binder);\n";
800 });
801 out << "} else {\n";
802 out.indent([&] {
803 out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
804 });
805 out << "}\n";
806 out.unindent();
807 out << "}\n";
808
809 handleError(out, mode);
810 }
811 }
812
emitHidlDefinition(Formatter & out) const813 void Interface::emitHidlDefinition(Formatter& out) const {
814 if (getDocComment() != nullptr) getDocComment()->emit(out);
815 out << typeName() << " ";
816
817 const Interface* super = superType();
818 if (super != nullptr && !super->isIBase()) {
819 out << "extends " << super->fqName().getRelativeFQName(fqName()) << " ";
820 }
821
822 out << "{";
823
824 out.indent([&] {
825 const std::vector<const NamedType*>& definedTypes = getSortedDefinedTypes();
826 if (definedTypes.size() > 0 || userDefinedMethods().size() > 0) out << "\n";
827
828 out.join(definedTypes.begin(), definedTypes.end(), "\n",
829 [&](auto t) { t->emitHidlDefinition(out); });
830
831 if (definedTypes.size() > 0 && userDefinedMethods().size() > 0) out << "\n";
832
833 out.join(userDefinedMethods().begin(), userDefinedMethods().end(), "\n",
834 [&](auto method) { method->emitHidlDefinition(out); });
835 });
836
837 out << "};\n";
838 }
839
emitPackageTypeDeclarations(Formatter & out) const840 void Interface::emitPackageTypeDeclarations(Formatter& out) const {
841 Scope::emitPackageTypeDeclarations(out);
842
843 out << "static inline std::string toString(" << getCppArgumentType() << " o);\n\n";
844 }
845
emitPackageTypeHeaderDefinitions(Formatter & out) const846 void Interface::emitPackageTypeHeaderDefinitions(Formatter& out) const {
847 Scope::emitPackageTypeHeaderDefinitions(out);
848
849 out << "static inline std::string toString(" << getCppArgumentType() << " o) ";
850
851 out.block([&] {
852 out << "std::string os = \"[class or subclass of \";\n"
853 << "os += " << fullName() << "::descriptor;\n"
854 << "os += \"]\";\n"
855 << "os += o->isRemote() ? \"@remote\" : \"@local\";\n"
856 << "return os;\n";
857 }).endl().endl();
858 }
859
emitTypeDefinitions(Formatter & out,const std::string & prefix) const860 void Interface::emitTypeDefinitions(Formatter& out, const std::string& prefix) const {
861 std::string space = prefix.empty() ? "" : (prefix + "::");
862
863 Scope::emitTypeDefinitions(out, space + definedName());
864 }
865
emitJavaReaderWriter(Formatter & out,const std::string & parcelObj,const std::string & argName,bool isReader) const866 void Interface::emitJavaReaderWriter(
867 Formatter &out,
868 const std::string &parcelObj,
869 const std::string &argName,
870 bool isReader) const {
871 if (isReader) {
872 out << fullJavaName()
873 << ".asInterface("
874 << parcelObj
875 << ".readStrongBinder());\n";
876 } else {
877 out << parcelObj
878 << ".writeStrongBinder("
879 << argName
880 << " == null ? null : "
881 << argName
882 << ".asBinder());\n";
883 }
884 }
885
emitVtsAttributeDeclaration(Formatter & out) const886 void Interface::emitVtsAttributeDeclaration(Formatter& out) const {
887 for (const auto &type : getSubTypes()) {
888 // Skip for TypeDef as it is just an alias of a defined type.
889 if (type->isTypeDef()) {
890 continue;
891 }
892 out << "attribute: {\n";
893 out.indent();
894 type->emitVtsTypeDeclarations(out);
895 out.unindent();
896 out << "}\n\n";
897 }
898 }
899
emitVtsMethodDeclaration(Formatter & out,bool isInherited) const900 void Interface::emitVtsMethodDeclaration(Formatter& out, bool isInherited) const {
901 for (const auto &method : methods()) {
902 if (method->isHidlReserved()) {
903 continue;
904 }
905
906 out << "api: {\n";
907 out.indent();
908 out << "name: \"" << method->name() << "\"\n";
909 out << "is_inherited: " << (isInherited ? "true" : "false") << "\n";
910 // Generate declaration for each return value.
911 for (const auto &result : method->results()) {
912 out << "return_type_hidl: {\n";
913 out.indent();
914 out << "name: \"" << result->name() << "\"\n";
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 out << "name: \"" << arg->name() << "\"\n";
924 arg->type().emitVtsAttributeType(out);
925 out.unindent();
926 out << "}\n";
927 }
928 // Generate declaration for each annotation.
929 for (const auto &annotation : method->annotations()) {
930 out << "callflow: {\n";
931 out.indent();
932 const std::string name = annotation->name();
933 if (name == "entry") {
934 out << "entry: true\n";
935 } else if (name == "exit") {
936 out << "exit: true\n";
937 } else if (name == "callflow") {
938 const AnnotationParam *param =
939 annotation->getParam("next");
940 if (param != nullptr) {
941 for (const auto& value : param->getValues()) {
942 out << "next: " << value << "\n";
943 }
944 }
945 } else {
946 CHECK(false);
947 }
948 out.unindent();
949 out << "}\n";
950 }
951 out.unindent();
952 out << "}\n\n";
953 }
954 }
955
emitVtsAttributeType(Formatter & out) const956 void Interface::emitVtsAttributeType(Formatter& out) const {
957 out << "type: " << getVtsType() << "\n"
958 << "predefined_type: \""
959 << fullName()
960 << "\"\n";
961 }
962
deepIsJavaCompatible(std::unordered_set<const Type * > * visited) const963 bool Interface::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const {
964 if (hasSensitiveDataAnnotation()) {
965 return false;
966 }
967
968 if (superType() != nullptr && !superType()->isJavaCompatible(visited)) {
969 return false;
970 }
971
972 for (const auto* method : methods()) {
973 if (!method->deepIsJavaCompatible(visited)) {
974 return false;
975 }
976 }
977
978 return Scope::deepIsJavaCompatible(visited);
979 }
980
isNeverStrongReference() const981 bool Interface::isNeverStrongReference() const {
982 return true;
983 }
984
985 const FQName gIBaseFqName = FQName("android.hidl.base", "1.0", "IBase");
986 const FQName gIManagerFqName = FQName("android.hidl.manager", "1.0", "IServiceManager");
987
988 } // namespace android
989
990