blob: 66abf8bd79b7adcef7d4d9d2d4a6abc767881892 [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
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
Andreas Huberc9410c72016-07-28 12:18:40 -070017#include "Interface.h"
18
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -070019#include "Annotation.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070020#include "Method.h"
21
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070022#include <hidl-util/Formatter.h>
Zhuoyao Zhang864c7712016-08-16 15:35:28 -070023#include <iostream>
24
Andreas Huberc9410c72016-07-28 12:18:40 -070025namespace android {
26
Andreas Huber9ed827c2016-08-22 12:31:13 -070027Interface::Interface(
Steven Morelandd537ab02016-09-12 10:32:01 -070028 const char *localName, Interface *super,
29 std::vector<Annotation *> *annotations)
Andreas Huber9ed827c2016-08-22 12:31:13 -070030 : Scope(localName),
31 mSuperType(super),
Steven Morelandd537ab02016-09-12 10:32:01 -070032 mAnnotations(annotations),
Andreas Huberea081b32016-08-17 15:57:47 -070033 mIsJavaCompatibleInProgress(false) {
Andreas Huberc9410c72016-07-28 12:18:40 -070034}
35
36void Interface::addMethod(Method *method) {
37 mMethods.push_back(method);
38}
39
Andreas Huber6cb08cf2016-08-03 15:44:51 -070040const Interface *Interface::superType() const {
Andreas Huberc9410c72016-07-28 12:18:40 -070041 return mSuperType;
42}
43
Andreas Hubera2723d22016-07-29 15:36:07 -070044bool Interface::isInterface() const {
45 return true;
46}
47
Andreas Huber295ad302016-08-16 11:35:00 -070048bool Interface::isBinder() const {
49 return true;
50}
51
Andreas Huber881227d2016-08-02 14:20:21 -070052const std::vector<Method *> &Interface::methods() const {
53 return mMethods;
54}
55
Steven Morelandd537ab02016-09-12 10:32:01 -070056const std::vector<Annotation *> &Interface::annotations() const {
57 return *mAnnotations;
Zhuoyao Zhangba7e6e92016-08-10 12:19:02 -070058}
59
Steven Moreland40786312016-08-16 10:29:40 -070060std::string Interface::getBaseName() const {
61 // cut off the leading 'I'.
62 return localName().substr(1);
63}
64
Steven Moreland979e0992016-09-07 09:18:08 -070065std::string Interface::getCppType(StorageMode mode,
66 std::string *extra,
67 bool specifyNamespaces) const {
Andreas Huber881227d2016-08-02 14:20:21 -070068 extra->clear();
Steven Moreland979e0992016-09-07 09:18:08 -070069 const std::string base =
70 std::string(specifyNamespaces ? "::android::" : "")
71 + "sp<"
72 + (specifyNamespaces ? fullName() : partialCppName())
73 + ">";
Andreas Huber881227d2016-08-02 14:20:21 -070074
75 switch (mode) {
76 case StorageMode_Stack:
77 case StorageMode_Result:
78 return base;
79
80 case StorageMode_Argument:
81 return "const " + base + "&";
82 }
83}
84
Andreas Huber2831d512016-08-15 09:33:47 -070085std::string Interface::getJavaType() const {
86 return fullJavaName();
87}
88
Andreas Huber881227d2016-08-02 14:20:21 -070089void Interface::emitReaderWriter(
90 Formatter &out,
91 const std::string &name,
92 const std::string &parcelObj,
93 bool parcelObjIsPointer,
94 bool isReader,
95 ErrorMode mode) const {
96 const std::string parcelObjDeref =
97 parcelObj + (parcelObjIsPointer ? "->" : ".");
98
99 if (isReader) {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700100 out << "{\n";
101 out.indent();
102
Iliyan Malchev549e2592016-08-10 08:59:12 -0700103 const std::string binderName = "_hidl_" + name + "_binder";
Andreas Huber881227d2016-08-02 14:20:21 -0700104
Andreas Huber8a82ff72016-08-04 10:29:39 -0700105 out << "::android::sp<::android::hardware::IBinder> "
Andreas Huber881227d2016-08-02 14:20:21 -0700106 << binderName << ";\n";
107
Iliyan Malchev549e2592016-08-10 08:59:12 -0700108 out << "_hidl_err = ";
Andreas Huber881227d2016-08-02 14:20:21 -0700109 out << parcelObjDeref
110 << "readNullableStrongBinder(&"
111 << binderName
112 << ");\n";
113
114 handleError(out, mode);
115
116 out << name
117 << " = "
Steven Moreland40786312016-08-16 10:29:40 -0700118 << fqName().cppNamespace()
119 << "::IHw"
120 << getBaseName()
Andreas Huber881227d2016-08-02 14:20:21 -0700121 << "::asInterface("
122 << binderName
123 << ");\n";
Andreas Hubere7ff2282016-08-16 13:50:03 -0700124
125 out.unindent();
126 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700127 } else {
Steven Moreland40786312016-08-16 10:29:40 -0700128
129 out << "if (" << name << "->isRemote()) {\n";
130 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700131 out << "_hidl_err = ";
Andreas Huber881227d2016-08-02 14:20:21 -0700132 out << parcelObjDeref
133 << "writeStrongBinder("
Steven Moreland40786312016-08-16 10:29:40 -0700134 << fqName().cppNamespace()
135 << "::IHw"
136 << getBaseName()
137 << "::asBinder(static_cast<"
138 << fqName().cppNamespace()
139 << "::IHw"
140 << getBaseName()
141 << "*>("
142 << name << ".get()"
143 << ")));\n";
144 out.unindent();
145 out << "} else {\n";
146 out.indent();
147 out << "_hidl_err = ";
148 out << parcelObjDeref
149 << "writeStrongBinder("
150 << "new " << fqName().cppNamespace()
151 << "::Bn" << getBaseName() << " "
152 << "(" << name <<"));\n";
153 out.unindent();
154 out << "}\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700155 handleError(out, mode);
156 }
157}
158
Andreas Huber2831d512016-08-15 09:33:47 -0700159void Interface::emitJavaReaderWriter(
160 Formatter &out,
161 const std::string &parcelObj,
162 const std::string &argName,
163 bool isReader) const {
164 if (isReader) {
165 out << fullJavaName()
166 << ".asInterface("
167 << parcelObj
168 << ".readStrongBinder());\n";
169 } else {
170 out << parcelObj
171 << ".writeStrongBinder("
172 << argName
173 << " == null ? null : "
174 << argName
175 << ".asBinder());\n";
176 }
177}
178
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700179status_t Interface::emitVtsAttributeDeclaration(Formatter &out) const {
180 for (const auto &type : getSubTypes()) {
181 out << "attribute: {\n";
182 out.indent();
183 status_t status = type->emitVtsTypeDeclarations(out);
184 if (status != OK) {
185 return status;
186 }
187 out.unindent();
188 out << "}\n\n";
189 }
190 return OK;
191}
192
193status_t Interface::emitVtsMethodDeclaration(Formatter &out) const {
194 for (const auto &method : mMethods) {
195 out << "api: {\n";
196 out.indent();
197 out << "name: \"" << method->name() << "\"\n";
198 // Generate declaration for each return value.
199 for (const auto &result : method->results()) {
200 out << "return_type_hidl: {\n";
201 out.indent();
202 status_t status = result->type().emitVtsAttributeType(out);
203 if (status != OK) {
204 return status;
205 }
206 out.unindent();
207 out << "}\n";
208 }
209 // Generate declaration for each input argument
210 for (const auto &arg : method->args()) {
211 out << "arg: {\n";
212 out.indent();
213 status_t status = arg->type().emitVtsAttributeType(out);
214 if (status != OK) {
215 return status;
216 }
217 out.unindent();
218 out << "}\n";
219 }
220 // Generate declaration for each annotation.
Steven Morelandd537ab02016-09-12 10:32:01 -0700221 for (const auto &annotation : method->annotations()) {
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700222 out << "callflow: {\n";
223 out.indent();
Steven Morelandd537ab02016-09-12 10:32:01 -0700224 std::string name = annotation->name();
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700225 if (name == "entry") {
226 out << "entry: true\n";
227 } else if (name == "exit") {
228 out << "exit: true\n";
229 } else if (name == "callflow") {
Steven Morelandd537ab02016-09-12 10:32:01 -0700230 const AnnotationParam *param =
231 annotation->getParam("next");
232 if (param != nullptr) {
233 for (auto value : *param->getValues()) {
234 out << "next: " << value << "\n";
235 }
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700236 }
237 } else {
238 std::cerr << "Invalid annotation '"
239 << name << "' for method: " << method->name()
240 << ". Should be one of: entry, exit, callflow. \n";
241 return UNKNOWN_ERROR;
242 }
243 out.unindent();
244 out << "}\n";
245 }
246 out.unindent();
247 out << "}\n\n";
248 }
249 return OK;
250}
251
252status_t Interface::emitVtsAttributeType(Formatter &out) const {
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700253 out << "type: TYPE_HIDL_CALLBACK\n"
254 << "predefined_type: \""
255 << localName()
Zhuoyao Zhang19933522016-08-29 15:06:38 -0700256 << "\"\n"
257 << "is_callback: true\n";
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700258 return OK;
259}
260
Andreas Huber70a59e12016-08-16 12:57:01 -0700261bool Interface::isJavaCompatible() const {
Andreas Huberea081b32016-08-17 15:57:47 -0700262 if (mIsJavaCompatibleInProgress) {
263 // We're currently trying to determine if this Interface is
264 // java-compatible and something is referencing this interface through
265 // one of its methods. Assume we'll ultimately succeed, if we were wrong
266 // the original invocation of Interface::isJavaCompatible() will then
267 // return the correct "false" result.
268 return true;
269 }
270
Andreas Huber0fa9e392016-08-31 09:05:44 -0700271 if (mSuperType != nullptr && !mSuperType->isJavaCompatible()) {
272 mIsJavaCompatibleInProgress = false;
273 return false;
274 }
275
Andreas Huberea081b32016-08-17 15:57:47 -0700276 mIsJavaCompatibleInProgress = true;
277
Andreas Huber70a59e12016-08-16 12:57:01 -0700278 if (!Scope::isJavaCompatible()) {
Andreas Huberea081b32016-08-17 15:57:47 -0700279 mIsJavaCompatibleInProgress = false;
Andreas Huber70a59e12016-08-16 12:57:01 -0700280 return false;
281 }
282
283 for (const auto &method : mMethods) {
284 if (!method->isJavaCompatible()) {
Andreas Huberea081b32016-08-17 15:57:47 -0700285 mIsJavaCompatibleInProgress = false;
Andreas Huber70a59e12016-08-16 12:57:01 -0700286 return false;
287 }
288 }
289
Andreas Huberea081b32016-08-17 15:57:47 -0700290 mIsJavaCompatibleInProgress = false;
291
Andreas Huber70a59e12016-08-16 12:57:01 -0700292 return true;
293}
294
Andreas Huberc9410c72016-07-28 12:18:40 -0700295} // namespace android
296