blob: c36e75f97c2d860f820a3a110039a5ce52d7fb3e [file] [log] [blame]
Andreas Huberc9410c72016-07-28 12:18:40 -07001#include "Interface.h"
2
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -07003#include "Annotation.h"
Andreas Huberc9410c72016-07-28 12:18:40 -07004#include "Formatter.h"
5#include "Method.h"
6
Zhuoyao Zhang864c7712016-08-16 15:35:28 -07007#include <iostream>
8
Andreas Huberc9410c72016-07-28 12:18:40 -07009namespace android {
10
Andreas Huberea081b32016-08-17 15:57:47 -070011Interface::Interface(Interface *super, AnnotationVector *annotations)
12 : mSuperType(super),
13 mAnnotationsByName(annotations),
14 mIsJavaCompatibleInProgress(false) {
Andreas Huberc9410c72016-07-28 12:18:40 -070015}
16
17void Interface::addMethod(Method *method) {
18 mMethods.push_back(method);
19}
20
Andreas Huber6cb08cf2016-08-03 15:44:51 -070021const Interface *Interface::superType() const {
Andreas Huberc9410c72016-07-28 12:18:40 -070022 return mSuperType;
23}
24
Andreas Hubera2723d22016-07-29 15:36:07 -070025bool Interface::isInterface() const {
26 return true;
27}
28
Andreas Huber295ad302016-08-16 11:35:00 -070029bool Interface::isBinder() const {
30 return true;
31}
32
Andreas Huber881227d2016-08-02 14:20:21 -070033const std::vector<Method *> &Interface::methods() const {
34 return mMethods;
35}
36
Zhuoyao Zhang5158db42016-08-10 10:25:20 -070037const AnnotationVector &Interface::annotations() const {
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -070038 return *mAnnotationsByName;
39}
40
Andreas Huber881227d2016-08-02 14:20:21 -070041std::string Interface::getCppType(StorageMode mode, std::string *extra) const {
42 extra->clear();
Andreas Huber31629bc2016-08-03 09:06:40 -070043 const std::string base = "::android::sp<" + fullName() + ">";
Andreas Huber881227d2016-08-02 14:20:21 -070044
45 switch (mode) {
46 case StorageMode_Stack:
47 case StorageMode_Result:
48 return base;
49
50 case StorageMode_Argument:
51 return "const " + base + "&";
52 }
53}
54
Andreas Huber2831d512016-08-15 09:33:47 -070055std::string Interface::getJavaType() const {
56 return fullJavaName();
57}
58
Andreas Huber881227d2016-08-02 14:20:21 -070059void Interface::emitReaderWriter(
60 Formatter &out,
61 const std::string &name,
62 const std::string &parcelObj,
63 bool parcelObjIsPointer,
64 bool isReader,
65 ErrorMode mode) const {
66 const std::string parcelObjDeref =
67 parcelObj + (parcelObjIsPointer ? "->" : ".");
68
69 if (isReader) {
Andreas Hubere7ff2282016-08-16 13:50:03 -070070 out << "{\n";
71 out.indent();
72
Iliyan Malchev549e2592016-08-10 08:59:12 -070073 const std::string binderName = "_hidl_" + name + "_binder";
Andreas Huber881227d2016-08-02 14:20:21 -070074
Andreas Huber8a82ff72016-08-04 10:29:39 -070075 out << "::android::sp<::android::hardware::IBinder> "
Andreas Huber881227d2016-08-02 14:20:21 -070076 << binderName << ";\n";
77
Iliyan Malchev549e2592016-08-10 08:59:12 -070078 out << "_hidl_err = ";
Andreas Huber881227d2016-08-02 14:20:21 -070079 out << parcelObjDeref
80 << "readNullableStrongBinder(&"
81 << binderName
82 << ");\n";
83
84 handleError(out, mode);
85
86 out << name
87 << " = "
Andreas Huber0e00de42016-08-03 09:56:02 -070088 << fullName()
Andreas Huber881227d2016-08-02 14:20:21 -070089 << "::asInterface("
90 << binderName
91 << ");\n";
Andreas Hubere7ff2282016-08-16 13:50:03 -070092
93 out.unindent();
94 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -070095 } else {
Iliyan Malchev549e2592016-08-10 08:59:12 -070096 out << "_hidl_err = ";
Andreas Huber881227d2016-08-02 14:20:21 -070097 out << parcelObjDeref
98 << "writeStrongBinder("
Andreas Huber0e00de42016-08-03 09:56:02 -070099 << fullName()
Andreas Huber881227d2016-08-02 14:20:21 -0700100 << "::asBinder("
101 << name
102 << "));\n";
103
104 handleError(out, mode);
105 }
106}
107
Andreas Huber2831d512016-08-15 09:33:47 -0700108void Interface::emitJavaReaderWriter(
109 Formatter &out,
110 const std::string &parcelObj,
111 const std::string &argName,
112 bool isReader) const {
113 if (isReader) {
114 out << fullJavaName()
115 << ".asInterface("
116 << parcelObj
117 << ".readStrongBinder());\n";
118 } else {
119 out << parcelObj
120 << ".writeStrongBinder("
121 << argName
122 << " == null ? null : "
123 << argName
124 << ".asBinder());\n";
125 }
126}
127
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700128status_t Interface::emitVtsAttributeDeclaration(Formatter &out) const {
129 for (const auto &type : getSubTypes()) {
130 out << "attribute: {\n";
131 out.indent();
132 status_t status = type->emitVtsTypeDeclarations(out);
133 if (status != OK) {
134 return status;
135 }
136 out.unindent();
137 out << "}\n\n";
138 }
139 return OK;
140}
141
142status_t Interface::emitVtsMethodDeclaration(Formatter &out) const {
143 for (const auto &method : mMethods) {
144 out << "api: {\n";
145 out.indent();
146 out << "name: \"" << method->name() << "\"\n";
147 // Generate declaration for each return value.
148 for (const auto &result : method->results()) {
149 out << "return_type_hidl: {\n";
150 out.indent();
151 status_t status = result->type().emitVtsAttributeType(out);
152 if (status != OK) {
153 return status;
154 }
155 out.unindent();
156 out << "}\n";
157 }
158 // Generate declaration for each input argument
159 for (const auto &arg : method->args()) {
160 out << "arg: {\n";
161 out.indent();
162 status_t status = arg->type().emitVtsAttributeType(out);
163 if (status != OK) {
164 return status;
165 }
166 out.unindent();
167 out << "}\n";
168 }
169 // Generate declaration for each annotation.
170 const AnnotationVector & annotations = method->annotations();
171 for (size_t i = 0; i < annotations.size(); i++) {
172 out << "callflow: {\n";
173 out.indent();
174 std::string name = annotations.keyAt(i);
175 if (name == "entry") {
176 out << "entry: true\n";
177 } else if (name == "exit") {
178 out << "exit: true\n";
179 } else if (name == "callflow") {
180 Annotation* annotation = annotations.valueAt(i);
181 std::vector<std::string> * values = annotation->params()
182 .valueFor("next");
183 for (auto value : *values) {
184 out << "next: " << value << "\n";
185 }
186 } else {
187 std::cerr << "Invalid annotation '"
188 << name << "' for method: " << method->name()
189 << ". Should be one of: entry, exit, callflow. \n";
190 return UNKNOWN_ERROR;
191 }
192 out.unindent();
193 out << "}\n";
194 }
195 out.unindent();
196 out << "}\n\n";
197 }
198 return OK;
199}
200
201status_t Interface::emitVtsAttributeType(Formatter &out) const {
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700202 out << "type: TYPE_HIDL_CALLBACK\n"
203 << "predefined_type: \""
204 << localName()
205 << "\"\n";
206 return OK;
207}
208
Andreas Huber70a59e12016-08-16 12:57:01 -0700209bool Interface::isJavaCompatible() const {
Andreas Huberea081b32016-08-17 15:57:47 -0700210 if (mIsJavaCompatibleInProgress) {
211 // We're currently trying to determine if this Interface is
212 // java-compatible and something is referencing this interface through
213 // one of its methods. Assume we'll ultimately succeed, if we were wrong
214 // the original invocation of Interface::isJavaCompatible() will then
215 // return the correct "false" result.
216 return true;
217 }
218
219 mIsJavaCompatibleInProgress = true;
220
Andreas Huber70a59e12016-08-16 12:57:01 -0700221 if (!Scope::isJavaCompatible()) {
Andreas Huberea081b32016-08-17 15:57:47 -0700222 mIsJavaCompatibleInProgress = false;
Andreas Huber70a59e12016-08-16 12:57:01 -0700223 return false;
224 }
225
226 for (const auto &method : mMethods) {
227 if (!method->isJavaCompatible()) {
Andreas Huberea081b32016-08-17 15:57:47 -0700228 mIsJavaCompatibleInProgress = false;
Andreas Huber70a59e12016-08-16 12:57:01 -0700229 return false;
230 }
231 }
232
Andreas Huberea081b32016-08-17 15:57:47 -0700233 mIsJavaCompatibleInProgress = false;
234
Andreas Huber70a59e12016-08-16 12:57:01 -0700235 return true;
236}
237
Andreas Huberc9410c72016-07-28 12:18:40 -0700238} // namespace android
239