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
getProxyName() const682 std::string Interface::getProxyName() const {
683 return fqName().getInterfaceProxyName();
684 }
685
getStubName() const686 std::string Interface::getStubName() const {
687 return fqName().getInterfaceStubName();
688 }
689
getHwName() const690 std::string Interface::getHwName() const {
691 return fqName().getInterfaceHwName();
692 }
693
getPassthroughName() const694 std::string Interface::getPassthroughName() const {
695 return fqName().getInterfacePassthroughName();
696 }
697
getProxyFqName() const698 FQName Interface::getProxyFqName() const {
699 return fqName().getInterfaceProxyFqName();
700 }
701
getStubFqName() const702 FQName Interface::getStubFqName() const {
703 return fqName().getInterfaceStubFqName();
704 }
705
getPassthroughFqName() const706 FQName Interface::getPassthroughFqName() const {
707 return fqName().getInterfacePassthroughFqName();
708 }
709
getCppType(StorageMode mode,bool specifyNamespaces) const710 std::string Interface::getCppType(StorageMode mode,
711 bool specifyNamespaces) const {
712 const std::string base =
713 std::string(specifyNamespaces ? "::android::" : "")
714 + "sp<"
715 + fullName()
716 + ">";
717
718 switch (mode) {
719 case StorageMode_Stack:
720 case StorageMode_Result:
721 return base;
722
723 case StorageMode_Argument:
724 return "const " + base + "&";
725 }
726 }
727
getJavaType(bool) const728 std::string Interface::getJavaType(bool /* forInitializer */) const {
729 return fullJavaName();
730 }
731
getVtsType() const732 std::string Interface::getVtsType() const {
733 if (StringHelper::EndsWith(definedName(), "Callback")) {
734 return "TYPE_HIDL_CALLBACK";
735 } else {
736 return "TYPE_HIDL_INTERFACE";
737 }
738 }
739
emitReaderWriter(Formatter & out,const std::string & name,const std::string & parcelObj,bool parcelObjIsPointer,bool isReader,ErrorMode mode) const740 void Interface::emitReaderWriter(
741 Formatter &out,
742 const std::string &name,
743 const std::string &parcelObj,
744 bool parcelObjIsPointer,
745 bool isReader,
746 ErrorMode mode) const {
747 const std::string parcelObjDeref =
748 parcelObj + (parcelObjIsPointer ? "->" : ".");
749
750 if (isReader) {
751 out << "{\n";
752 out.indent();
753
754 const std::string binderName = "_hidl_binder";
755 out << "::android::sp<::android::hardware::IBinder> "
756 << binderName << ";\n";
757
758 out << "_hidl_err = ";
759 out << parcelObjDeref
760 << "readNullableStrongBinder(&"
761 << binderName
762 << ");\n";
763
764 handleError(out, mode);
765
766 out << name
767 << " = "
768 << "::android::hardware::fromBinder<"
769 << fqName().cppName()
770 << ","
771 << getProxyFqName().cppName()
772 << ","
773 << getStubFqName().cppName()
774 << ">("
775 << binderName
776 << ");\n";
777
778 out.unindent();
779 out << "}\n\n";
780 } else {
781 out << "if (" << name << " == nullptr) {\n";
782 out.indent();
783 out << "_hidl_err = ";
784 out << parcelObjDeref
785 << "writeStrongBinder(nullptr);\n";
786 out.unindent();
787 out << "} else {\n";
788 out.indent();
789 out << "::android::sp<::android::hardware::IBinder> _hidl_binder = "
790 << "::android::hardware::getOrCreateCachedBinder(" << name << ".get());\n";
791 out << "if (_hidl_binder.get() != nullptr) {\n";
792 out.indent([&] {
793 out << "_hidl_err = "
794 << parcelObjDeref
795 << "writeStrongBinder(_hidl_binder);\n";
796 });
797 out << "} else {\n";
798 out.indent([&] {
799 out << "_hidl_err = ::android::UNKNOWN_ERROR;\n";
800 });
801 out << "}\n";
802 out.unindent();
803 out << "}\n";
804
805 handleError(out, mode);
806 }
807 }
808
emitHidlDefinition(Formatter & out) const809 void Interface::emitHidlDefinition(Formatter& out) const {
810 if (getDocComment() != nullptr) getDocComment()->emit(out);
811 out << typeName() << " ";
812
813 const Interface* super = superType();
814 if (super != nullptr && !super->isIBase()) {
815 out << "extends " << super->fqName().getRelativeFQName(fqName()) << " ";
816 }
817
818 out << "{";
819
820 out.indent([&] {
821 const std::vector<const NamedType*>& definedTypes = getSortedDefinedTypes();
822 if (definedTypes.size() > 0 || userDefinedMethods().size() > 0) out << "\n";
823
824 out.join(definedTypes.begin(), definedTypes.end(), "\n",
825 [&](auto t) { t->emitHidlDefinition(out); });
826
827 if (definedTypes.size() > 0 && userDefinedMethods().size() > 0) out << "\n";
828
829 out.join(userDefinedMethods().begin(), userDefinedMethods().end(), "\n",
830 [&](auto method) { method->emitHidlDefinition(out); });
831 });
832
833 out << "};\n";
834 }
835
emitPackageTypeDeclarations(Formatter & out) const836 void Interface::emitPackageTypeDeclarations(Formatter& out) const {
837 Scope::emitPackageTypeDeclarations(out);
838
839 out << "static inline std::string toString(" << getCppArgumentType() << " o);\n\n";
840 }
841
emitPackageTypeHeaderDefinitions(Formatter & out) const842 void Interface::emitPackageTypeHeaderDefinitions(Formatter& out) const {
843 Scope::emitPackageTypeHeaderDefinitions(out);
844
845 out << "static inline std::string toString(" << getCppArgumentType() << " o) ";
846
847 out.block([&] {
848 out << "std::string os = \"[class or subclass of \";\n"
849 << "os += " << fullName() << "::descriptor;\n"
850 << "os += \"]\";\n"
851 << "os += o->isRemote() ? \"@remote\" : \"@local\";\n"
852 << "return os;\n";
853 }).endl().endl();
854 }
855
emitTypeDefinitions(Formatter & out,const std::string & prefix) const856 void Interface::emitTypeDefinitions(Formatter& out, const std::string& prefix) const {
857 std::string space = prefix.empty() ? "" : (prefix + "::");
858
859 Scope::emitTypeDefinitions(out, space + definedName());
860 }
861
emitJavaReaderWriter(Formatter & out,const std::string & parcelObj,const std::string & argName,bool isReader) const862 void Interface::emitJavaReaderWriter(
863 Formatter &out,
864 const std::string &parcelObj,
865 const std::string &argName,
866 bool isReader) const {
867 if (isReader) {
868 out << fullJavaName()
869 << ".asInterface("
870 << parcelObj
871 << ".readStrongBinder());\n";
872 } else {
873 out << parcelObj
874 << ".writeStrongBinder("
875 << argName
876 << " == null ? null : "
877 << argName
878 << ".asBinder());\n";
879 }
880 }
881
emitVtsAttributeDeclaration(Formatter & out) const882 void Interface::emitVtsAttributeDeclaration(Formatter& out) const {
883 for (const auto &type : getSubTypes()) {
884 // Skip for TypeDef as it is just an alias of a defined type.
885 if (type->isTypeDef()) {
886 continue;
887 }
888 out << "attribute: {\n";
889 out.indent();
890 type->emitVtsTypeDeclarations(out);
891 out.unindent();
892 out << "}\n\n";
893 }
894 }
895
emitVtsMethodDeclaration(Formatter & out,bool isInherited) const896 void Interface::emitVtsMethodDeclaration(Formatter& out, bool isInherited) const {
897 for (const auto &method : methods()) {
898 if (method->isHidlReserved()) {
899 continue;
900 }
901
902 out << "api: {\n";
903 out.indent();
904 out << "name: \"" << method->name() << "\"\n";
905 out << "is_inherited: " << (isInherited ? "true" : "false") << "\n";
906 // Generate declaration for each return value.
907 for (const auto &result : method->results()) {
908 out << "return_type_hidl: {\n";
909 out.indent();
910 out << "name: \"" << result->name() << "\"\n";
911 result->type().emitVtsAttributeType(out);
912 out.unindent();
913 out << "}\n";
914 }
915 // Generate declaration for each input argument
916 for (const auto &arg : method->args()) {
917 out << "arg: {\n";
918 out.indent();
919 out << "name: \"" << arg->name() << "\"\n";
920 arg->type().emitVtsAttributeType(out);
921 out.unindent();
922 out << "}\n";
923 }
924 // Generate declaration for each annotation.
925 for (const auto &annotation : method->annotations()) {
926 out << "callflow: {\n";
927 out.indent();
928 const std::string name = annotation->name();
929 if (name == "entry") {
930 out << "entry: true\n";
931 } else if (name == "exit") {
932 out << "exit: true\n";
933 } else if (name == "callflow") {
934 const AnnotationParam *param =
935 annotation->getParam("next");
936 if (param != nullptr) {
937 for (const auto& value : param->getValues()) {
938 out << "next: " << value << "\n";
939 }
940 }
941 } else {
942 CHECK(false);
943 }
944 out.unindent();
945 out << "}\n";
946 }
947 out.unindent();
948 out << "}\n\n";
949 }
950 }
951
emitVtsAttributeType(Formatter & out) const952 void Interface::emitVtsAttributeType(Formatter& out) const {
953 out << "type: " << getVtsType() << "\n"
954 << "predefined_type: \""
955 << fullName()
956 << "\"\n";
957 }
958
deepIsJavaCompatible(std::unordered_set<const Type * > * visited) const959 bool Interface::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const {
960 if (hasSensitiveDataAnnotation()) {
961 return false;
962 }
963
964 if (superType() != nullptr && !superType()->isJavaCompatible(visited)) {
965 return false;
966 }
967
968 for (const auto* method : methods()) {
969 if (!method->deepIsJavaCompatible(visited)) {
970 return false;
971 }
972 }
973
974 return Scope::deepIsJavaCompatible(visited);
975 }
976
isNeverStrongReference() const977 bool Interface::isNeverStrongReference() const {
978 return true;
979 }
980
981 const FQName gIBaseFqName = FQName("android.hidl.base", "1.0", "IBase");
982 const FQName gIManagerFqName = FQName("android.hidl.manager", "1.0", "IServiceManager");
983
984 } // namespace android
985
986