blob: 6af96d329473244dc1483b25ddf88a44dae11a2d [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 Huber9ed827c2016-08-22 12:31:13 -070011Interface::Interface(
12 const char *localName, Interface *super, AnnotationVector *annotations)
13 : Scope(localName),
14 mSuperType(super),
Andreas Huberea081b32016-08-17 15:57:47 -070015 mAnnotationsByName(annotations),
16 mIsJavaCompatibleInProgress(false) {
Andreas Huberc9410c72016-07-28 12:18:40 -070017}
18
19void Interface::addMethod(Method *method) {
20 mMethods.push_back(method);
21}
22
Andreas Huber6cb08cf2016-08-03 15:44:51 -070023const Interface *Interface::superType() const {
Andreas Huberc9410c72016-07-28 12:18:40 -070024 return mSuperType;
25}
26
Andreas Hubera2723d22016-07-29 15:36:07 -070027bool Interface::isInterface() const {
28 return true;
29}
30
Andreas Huber295ad302016-08-16 11:35:00 -070031bool Interface::isBinder() const {
32 return true;
33}
34
Andreas Huber881227d2016-08-02 14:20:21 -070035const std::vector<Method *> &Interface::methods() const {
36 return mMethods;
37}
38
Zhuoyao Zhang5158db42016-08-10 10:25:20 -070039const AnnotationVector &Interface::annotations() const {
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -070040 return *mAnnotationsByName;
41}
42
Andreas Huber881227d2016-08-02 14:20:21 -070043std::string Interface::getCppType(StorageMode mode, std::string *extra) const {
44 extra->clear();
Andreas Huber31629bc2016-08-03 09:06:40 -070045 const std::string base = "::android::sp<" + fullName() + ">";
Andreas Huber881227d2016-08-02 14:20:21 -070046
47 switch (mode) {
48 case StorageMode_Stack:
49 case StorageMode_Result:
50 return base;
51
52 case StorageMode_Argument:
53 return "const " + base + "&";
54 }
55}
56
Andreas Huber2831d512016-08-15 09:33:47 -070057std::string Interface::getJavaType() const {
58 return fullJavaName();
59}
60
Andreas Huber881227d2016-08-02 14:20:21 -070061void Interface::emitReaderWriter(
62 Formatter &out,
63 const std::string &name,
64 const std::string &parcelObj,
65 bool parcelObjIsPointer,
66 bool isReader,
67 ErrorMode mode) const {
68 const std::string parcelObjDeref =
69 parcelObj + (parcelObjIsPointer ? "->" : ".");
70
71 if (isReader) {
Andreas Hubere7ff2282016-08-16 13:50:03 -070072 out << "{\n";
73 out.indent();
74
Iliyan Malchev549e2592016-08-10 08:59:12 -070075 const std::string binderName = "_hidl_" + name + "_binder";
Andreas Huber881227d2016-08-02 14:20:21 -070076
Andreas Huber8a82ff72016-08-04 10:29:39 -070077 out << "::android::sp<::android::hardware::IBinder> "
Andreas Huber881227d2016-08-02 14:20:21 -070078 << binderName << ";\n";
79
Iliyan Malchev549e2592016-08-10 08:59:12 -070080 out << "_hidl_err = ";
Andreas Huber881227d2016-08-02 14:20:21 -070081 out << parcelObjDeref
82 << "readNullableStrongBinder(&"
83 << binderName
84 << ");\n";
85
86 handleError(out, mode);
87
88 out << name
89 << " = "
Andreas Huber0e00de42016-08-03 09:56:02 -070090 << fullName()
Andreas Huber881227d2016-08-02 14:20:21 -070091 << "::asInterface("
92 << binderName
93 << ");\n";
Andreas Hubere7ff2282016-08-16 13:50:03 -070094
95 out.unindent();
96 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -070097 } else {
Iliyan Malchev549e2592016-08-10 08:59:12 -070098 out << "_hidl_err = ";
Andreas Huber881227d2016-08-02 14:20:21 -070099 out << parcelObjDeref
100 << "writeStrongBinder("
Andreas Huber0e00de42016-08-03 09:56:02 -0700101 << fullName()
Andreas Huber881227d2016-08-02 14:20:21 -0700102 << "::asBinder("
103 << name
104 << "));\n";
105
106 handleError(out, mode);
107 }
108}
109
Andreas Huber2831d512016-08-15 09:33:47 -0700110void Interface::emitJavaReaderWriter(
111 Formatter &out,
112 const std::string &parcelObj,
113 const std::string &argName,
114 bool isReader) const {
115 if (isReader) {
116 out << fullJavaName()
117 << ".asInterface("
118 << parcelObj
119 << ".readStrongBinder());\n";
120 } else {
121 out << parcelObj
122 << ".writeStrongBinder("
123 << argName
124 << " == null ? null : "
125 << argName
126 << ".asBinder());\n";
127 }
128}
129
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700130status_t Interface::emitVtsAttributeDeclaration(Formatter &out) const {
131 for (const auto &type : getSubTypes()) {
132 out << "attribute: {\n";
133 out.indent();
134 status_t status = type->emitVtsTypeDeclarations(out);
135 if (status != OK) {
136 return status;
137 }
138 out.unindent();
139 out << "}\n\n";
140 }
141 return OK;
142}
143
144status_t Interface::emitVtsMethodDeclaration(Formatter &out) const {
145 for (const auto &method : mMethods) {
146 out << "api: {\n";
147 out.indent();
148 out << "name: \"" << method->name() << "\"\n";
149 // Generate declaration for each return value.
150 for (const auto &result : method->results()) {
151 out << "return_type_hidl: {\n";
152 out.indent();
153 status_t status = result->type().emitVtsAttributeType(out);
154 if (status != OK) {
155 return status;
156 }
157 out.unindent();
158 out << "}\n";
159 }
160 // Generate declaration for each input argument
161 for (const auto &arg : method->args()) {
162 out << "arg: {\n";
163 out.indent();
164 status_t status = arg->type().emitVtsAttributeType(out);
165 if (status != OK) {
166 return status;
167 }
168 out.unindent();
169 out << "}\n";
170 }
171 // Generate declaration for each annotation.
172 const AnnotationVector & annotations = method->annotations();
173 for (size_t i = 0; i < annotations.size(); i++) {
174 out << "callflow: {\n";
175 out.indent();
176 std::string name = annotations.keyAt(i);
177 if (name == "entry") {
178 out << "entry: true\n";
179 } else if (name == "exit") {
180 out << "exit: true\n";
181 } else if (name == "callflow") {
182 Annotation* annotation = annotations.valueAt(i);
183 std::vector<std::string> * values = annotation->params()
184 .valueFor("next");
185 for (auto value : *values) {
186 out << "next: " << value << "\n";
187 }
188 } else {
189 std::cerr << "Invalid annotation '"
190 << name << "' for method: " << method->name()
191 << ". Should be one of: entry, exit, callflow. \n";
192 return UNKNOWN_ERROR;
193 }
194 out.unindent();
195 out << "}\n";
196 }
197 out.unindent();
198 out << "}\n\n";
199 }
200 return OK;
201}
202
203status_t Interface::emitVtsAttributeType(Formatter &out) const {
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700204 out << "type: TYPE_HIDL_CALLBACK\n"
205 << "predefined_type: \""
206 << localName()
207 << "\"\n";
208 return OK;
209}
210
Andreas Huber70a59e12016-08-16 12:57:01 -0700211bool Interface::isJavaCompatible() const {
Andreas Huberea081b32016-08-17 15:57:47 -0700212 if (mIsJavaCompatibleInProgress) {
213 // We're currently trying to determine if this Interface is
214 // java-compatible and something is referencing this interface through
215 // one of its methods. Assume we'll ultimately succeed, if we were wrong
216 // the original invocation of Interface::isJavaCompatible() will then
217 // return the correct "false" result.
218 return true;
219 }
220
221 mIsJavaCompatibleInProgress = true;
222
Andreas Huber70a59e12016-08-16 12:57:01 -0700223 if (!Scope::isJavaCompatible()) {
Andreas Huberea081b32016-08-17 15:57:47 -0700224 mIsJavaCompatibleInProgress = false;
Andreas Huber70a59e12016-08-16 12:57:01 -0700225 return false;
226 }
227
228 for (const auto &method : mMethods) {
229 if (!method->isJavaCompatible()) {
Andreas Huberea081b32016-08-17 15:57:47 -0700230 mIsJavaCompatibleInProgress = false;
Andreas Huber70a59e12016-08-16 12:57:01 -0700231 return false;
232 }
233 }
234
Andreas Huberea081b32016-08-17 15:57:47 -0700235 mIsJavaCompatibleInProgress = false;
236
Andreas Huber70a59e12016-08-16 12:57:01 -0700237 return true;
238}
239
Andreas Huberc9410c72016-07-28 12:18:40 -0700240} // namespace android
241