blob: 86e785c6b622fa2fc8d86caa34b68ab3f68cf2f2 [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 Huber2831d512016-08-15 09:33:47 -070017#include "AST.h"
18
19#include "Coordinator.h"
Andreas Huber2831d512016-08-15 09:33:47 -070020#include "Interface.h"
21#include "Method.h"
Timur Iskhakov7fa79f62017-08-09 11:04:54 -070022#include "Reference.h"
Andreas Huber2831d512016-08-15 09:33:47 -070023#include "Scope.h"
24
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070025#include <hidl-util/Formatter.h>
Andreas Huber2831d512016-08-15 09:33:47 -070026#include <android-base/logging.h>
27
28namespace android {
29
Timur Iskhakov7fa79f62017-08-09 11:04:54 -070030void AST::emitJavaReaderWriter(Formatter& out, const std::string& parcelObj,
31 const NamedReference<Type>* arg, bool isReader,
32 bool addPrefixToName) const {
Andreas Huber2831d512016-08-15 09:33:47 -070033 if (isReader) {
Yifan Hong4ed13472016-11-02 10:44:11 -070034 out << arg->type().getJavaType()
Andreas Huber2831d512016-08-15 09:33:47 -070035 << " "
Yifan Honga47eef32016-12-12 10:38:54 -080036 << (addPrefixToName ? "_hidl_out_" : "")
Andreas Huber2831d512016-08-15 09:33:47 -070037 << arg->name()
38 << " = ";
39 }
40
Yifan Honga47eef32016-12-12 10:38:54 -080041 arg->type().emitJavaReaderWriter(out, parcelObj,
42 (addPrefixToName ? "_hidl_out_" : "") + arg->name(),
43 isReader);
Andreas Huber2831d512016-08-15 09:33:47 -070044}
45
Andreas Huber0fa9e392016-08-31 09:05:44 -070046status_t AST::generateJavaTypes(
Andreas Huberd29724f2016-09-14 09:33:13 -070047 const std::string &outputPath, const std::string &limitToType) const {
Andreas Huber85eabdb2016-08-25 11:24:49 -070048 // Splits types.hal up into one java file per declared type.
49
Timur Iskhakovcb0ba522017-07-17 20:01:37 -070050 for (const auto& type : mRootScope.getSubTypes()) {
Steven Morelandd537ab02016-09-12 10:32:01 -070051 std::string typeName = type->localName();
Andreas Huber85eabdb2016-08-25 11:24:49 -070052
53 if (type->isTypeDef()) {
54 continue;
55 }
56
Andreas Huberd29724f2016-09-14 09:33:13 -070057 if (!limitToType.empty() && typeName != limitToType) {
Andreas Huber0fa9e392016-08-31 09:05:44 -070058 continue;
59 }
60
Andreas Huber85eabdb2016-08-25 11:24:49 -070061 std::string path = outputPath;
62 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Yifan Hong97288ac2016-12-12 16:03:51 -080063 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */,
64 true /* sanitized */));
Andreas Huber85eabdb2016-08-25 11:24:49 -070065 path.append(typeName);
66 path.append(".java");
67
Steven Morelandf7fa0682017-05-11 16:14:55 -070068 CHECK(Coordinator::MakeParentHierarchy(path)) << path;
Andreas Huber85eabdb2016-08-25 11:24:49 -070069 FILE *file = fopen(path.c_str(), "w");
70
71 if (file == NULL) {
72 return -errno;
73 }
74
75 Formatter out(file);
76
77 std::vector<std::string> packageComponents;
78 getPackageAndVersionComponents(
79 &packageComponents, true /* cpp_compatible */);
80
81 out << "package " << mPackage.javaPackage() << ";\n\n";
82
Iliyan Malchev800273d2016-09-02 15:25:07 -070083 out << "\n";
84
Andreas Huber85eabdb2016-08-25 11:24:49 -070085 status_t err =
86 type->emitJavaTypeDeclarations(out, true /* atTopLevel */);
87
88 if (err != OK) {
89 return err;
90 }
91 }
92
93 return OK;
94}
95
Andreas Huber0fa9e392016-08-31 09:05:44 -070096status_t AST::generateJava(
Andreas Huberd29724f2016-09-14 09:33:13 -070097 const std::string &outputPath, const std::string &limitToType) const {
Andreas Huber0fa9e392016-08-31 09:05:44 -070098 if (!isJavaCompatible()) {
Andreas Huber70a59e12016-08-16 12:57:01 -070099 fprintf(stderr,
100 "ERROR: This interface is not Java compatible. The Java backend"
Andreas Huberf03332a2016-09-22 15:35:43 -0700101 " does NOT support union types nor native handles. "
102 "In addition, vectors of arrays are limited to at most "
Andreas Huber86a112b2016-10-19 14:25:16 -0700103 "one-dimensional arrays and vectors of {vectors,interfaces} are"
104 " not supported.\n");
Andreas Huber70a59e12016-08-16 12:57:01 -0700105
Andreas Huber2831d512016-08-15 09:33:47 -0700106 return UNKNOWN_ERROR;
107 }
108
Steven Moreland19f11b52017-05-12 18:22:21 -0700109 if (!AST::isInterface()) {
Andreas Huber0fa9e392016-08-31 09:05:44 -0700110 return generateJavaTypes(outputPath, limitToType);
111 }
112
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700113 const Interface* iface = mRootScope.getInterface();
Steven Moreland19f11b52017-05-12 18:22:21 -0700114 std::string ifaceName = iface->localName();
Andreas Huber0fa9e392016-08-31 09:05:44 -0700115
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700116 const std::string baseName = iface->getBaseName();
Andreas Huber2831d512016-08-15 09:33:47 -0700117
118 std::string path = outputPath;
119 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Yifan Hong97288ac2016-12-12 16:03:51 -0800120 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */,
121 true /* sanitized */));
Andreas Huber2831d512016-08-15 09:33:47 -0700122 path.append(ifaceName);
123 path.append(".java");
124
125 CHECK(Coordinator::MakeParentHierarchy(path));
126 FILE *file = fopen(path.c_str(), "w");
127
128 if (file == NULL) {
129 return -errno;
130 }
131
132 Formatter out(file);
133
134 std::vector<std::string> packageComponents;
135 getPackageAndVersionComponents(
136 &packageComponents, true /* cpp_compatible */);
137
138 out << "package " << mPackage.javaPackage() << ";\n\n";
139
Andreas Huber2831d512016-08-15 09:33:47 -0700140 out.setNamespace(mPackage.javaPackage() + ".");
141
Andreas Huber2831d512016-08-15 09:33:47 -0700142 const Interface *superType = iface->superType();
143
144 out << "public interface " << ifaceName << " extends ";
145
146 if (superType != NULL) {
147 out << superType->fullJavaName();
148 } else {
Yifan Hong1af73532016-11-09 14:32:58 -0800149 out << "android.os.IHwInterface";
Andreas Huber2831d512016-08-15 09:33:47 -0700150 }
151
152 out << " {\n";
153 out.indent();
154
155 out << "public static final String kInterfaceName = \""
156 << mPackage.string()
157 << "::"
158 << ifaceName
159 << "\";\n\n";
160
Andreas Hubera2abe982017-04-04 14:42:09 -0700161 out << "/* package private */ static "
Andreas Huber2831d512016-08-15 09:33:47 -0700162 << ifaceName
Yifan Hong1af73532016-11-09 14:32:58 -0800163 << " asInterface(android.os.IHwBinder binder) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700164
165 out.indent();
166
167 out << "if (binder == null) {\n";
168 out.indent();
169 out << "return null;\n";
170 out.unindent();
171 out << "}\n\n";
172
Yifan Hong1af73532016-11-09 14:32:58 -0800173 out << "android.os.IHwInterface iface =\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700174 out.indent();
175 out.indent();
176 out << "binder.queryLocalInterface(kInterfaceName);\n\n";
177 out.unindent();
178 out.unindent();
179
180 out << "if ((iface != null) && (iface instanceof "
181 << ifaceName
182 << ")) {\n";
183
184 out.indent();
185 out << "return (" << ifaceName << ")iface;\n";
186 out.unindent();
187 out << "}\n\n";
188
Andreas Hubera2abe982017-04-04 14:42:09 -0700189 out << ifaceName << " proxy = new " << ifaceName << ".Proxy(binder);\n\n";
190 out << "try {\n";
191 out.indent();
192 out << "for (String descriptor : proxy.interfaceChain()) {\n";
193 out.indent();
194 out << "if (descriptor.equals(kInterfaceName)) {\n";
195 out.indent();
196 out << "return proxy;\n";
197 out.unindent();
198 out << "}\n";
199 out.unindent();
200 out << "}\n";
201 out.unindent();
202 out << "} catch (android.os.RemoteException e) {\n";
203 out.indent();
204 out.unindent();
205 out << "}\n\n";
206
207 out << "return null;\n";
208
209 out.unindent();
210 out << "}\n\n";
211
212 out << "public static "
213 << ifaceName
214 << " castFrom(android.os.IHwInterface iface) {\n";
215 out.indent();
216
217 out << "return (iface == null) ? null : "
218 << ifaceName
219 << ".asInterface(iface.asBinder());\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700220
221 out.unindent();
222 out << "}\n\n";
223
Yifan Hong084d11f2016-12-21 15:33:43 -0800224 out << "@Override\npublic android.os.IHwBinder asBinder();\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700225
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700226 out << "public static "
227 << ifaceName
Yifan Hong320a3492017-03-27 10:33:09 -0700228 << " getService(String serviceName) throws android.os.RemoteException {\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700229
230 out.indent();
231
232 out << "return "
233 << ifaceName
Yifan Hong1af73532016-11-09 14:32:58 -0800234 << ".asInterface(android.os.HwBinder.getService(\""
Steven Moreland7e367bf2016-11-04 11:31:41 -0700235 << iface->fqName().string()
236 << "\",serviceName));\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700237
238 out.unindent();
239
240 out << "}\n\n";
241
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800242 out << "public static "
243 << ifaceName
Yifan Hong320a3492017-03-27 10:33:09 -0700244 << " getService() throws android.os.RemoteException {\n";
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800245
246 out.indent();
247
248 out << "return "
249 << ifaceName
250 << ".asInterface(android.os.HwBinder.getService(\""
251 << iface->fqName().string()
252 << "\",\"default\"));\n";
253
254 out.unindent();
255
256 out << "}\n\n";
257
Andreas Huber2831d512016-08-15 09:33:47 -0700258 status_t err = emitJavaTypeDeclarations(out);
259
260 if (err != OK) {
261 return err;
262 }
263
Andreas Huber2831d512016-08-15 09:33:47 -0700264 for (const auto &method : iface->methods()) {
Andreas Huber37065d62017-02-07 14:36:54 -0800265 if (method->isHiddenFromJava()) {
266 continue;
267 }
268
Andreas Huber2831d512016-08-15 09:33:47 -0700269 const bool returnsValue = !method->results().empty();
270 const bool needsCallback = method->results().size() > 1;
271
272 if (needsCallback) {
Yifan Hong601cfca2017-05-24 12:20:17 -0700273 out << "\n@java.lang.FunctionalInterface\npublic interface " << method->name()
Andreas Huber2831d512016-08-15 09:33:47 -0700274 << "Callback {\n";
275
276 out.indent();
277
Yifan Hong932464e2017-03-30 15:40:22 -0700278 out << "public void onValues(";
279 method->emitJavaResultSignature(out);
280 out << ");\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700281
282 out.unindent();
283 out << "}\n\n";
284 }
285
286 if (returnsValue && !needsCallback) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700287 out << method->results()[0]->type().getJavaType();
Andreas Huber2831d512016-08-15 09:33:47 -0700288 } else {
289 out << "void";
290 }
291
292 out << " "
293 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700294 << "(";
295 method->emitJavaArgSignature(out);
Andreas Huber2831d512016-08-15 09:33:47 -0700296
297 if (needsCallback) {
298 if (!method->args().empty()) {
299 out << ", ";
300 }
301
302 out << method->name()
Steven Moreland4ddd8332017-04-27 19:27:18 -0700303 << "Callback _hidl_cb";
Andreas Huber2831d512016-08-15 09:33:47 -0700304 }
305
Steven Morelanddad1b302016-12-20 15:56:00 -0800306 out << ")\n";
307 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700308 out << "throws android.os.RemoteException;\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800309 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700310 }
311
312 out << "\npublic static final class Proxy implements "
313 << ifaceName
314 << " {\n";
315
316 out.indent();
317
Yifan Hong1af73532016-11-09 14:32:58 -0800318 out << "private android.os.IHwBinder mRemote;\n\n";
319 out << "public Proxy(android.os.IHwBinder remote) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700320 out.indent();
Yifan Hong729e7962016-12-21 16:04:27 -0800321 out << "mRemote = java.util.Objects.requireNonNull(remote);\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700322 out.unindent();
323 out << "}\n\n";
324
Yifan Hong084d11f2016-12-21 15:33:43 -0800325 out << "@Override\npublic android.os.IHwBinder asBinder() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700326 out.indent();
327 out << "return mRemote;\n";
328 out.unindent();
329 out << "}\n\n";
330
Yifan Honge45b5302017-02-22 10:49:07 -0800331
332 out << "@Override\npublic String toString() ";
333 out.block([&] {
334 out.sTry([&] {
335 out << "return this.interfaceDescriptor() + \"@Proxy\";\n";
Yifan Hong320a3492017-03-27 10:33:09 -0700336 }).sCatch("android.os.RemoteException ex", [&] {
Yifan Honge45b5302017-02-22 10:49:07 -0800337 out << "/* ignored; handled below. */\n";
338 }).endl();
339 out << "return \"[class or subclass of \" + "
340 << ifaceName << ".kInterfaceName + \"]@Proxy\";\n";
341 }).endl().endl();
342
Yifan Hong10fe0b52016-10-19 14:20:17 -0700343 const Interface *prevInterface = nullptr;
344 for (const auto &tuple : iface->allMethodsFromRoot()) {
345 const Method *method = tuple.method();
Andreas Huber37065d62017-02-07 14:36:54 -0800346
347 if (method->isHiddenFromJava()) {
348 continue;
349 }
350
Yifan Hong10fe0b52016-10-19 14:20:17 -0700351 const Interface *superInterface = tuple.interface();
352 if (prevInterface != superInterface) {
353 out << "// Methods from "
354 << superInterface->fullName()
355 << " follow.\n";
356 prevInterface = superInterface;
357 }
358 const bool returnsValue = !method->results().empty();
359 const bool needsCallback = method->results().size() > 1;
Andreas Huber2831d512016-08-15 09:33:47 -0700360
Yifan Hong084d11f2016-12-21 15:33:43 -0800361 out << "@Override\npublic ";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700362 if (returnsValue && !needsCallback) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700363 out << method->results()[0]->type().getJavaType();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700364 } else {
365 out << "void";
366 }
Andreas Huber2831d512016-08-15 09:33:47 -0700367
Yifan Hong10fe0b52016-10-19 14:20:17 -0700368 out << " "
369 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700370 << "(";
371 method->emitJavaArgSignature(out);
Andreas Huber2831d512016-08-15 09:33:47 -0700372
Yifan Hong10fe0b52016-10-19 14:20:17 -0700373 if (needsCallback) {
374 if (!method->args().empty()) {
375 out << ", ";
Andreas Huber2831d512016-08-15 09:33:47 -0700376 }
377
Yifan Hong10fe0b52016-10-19 14:20:17 -0700378 out << method->name()
Steven Moreland4ddd8332017-04-27 19:27:18 -0700379 << "Callback _hidl_cb";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700380 }
Andreas Huber2831d512016-08-15 09:33:47 -0700381
Steven Morelanddad1b302016-12-20 15:56:00 -0800382 out << ")\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700383 out.indent();
Steven Morelanddad1b302016-12-20 15:56:00 -0800384 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700385 out << "throws android.os.RemoteException {\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800386 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700387
Martijn Coenen115d4282016-12-19 05:14:04 +0100388 if (method->isHidlReserved() && method->overridesJavaImpl(IMPL_PROXY)) {
389 method->javaImpl(IMPL_PROXY, out);
390 out.unindent();
391 out << "}\n";
392 continue;
393 }
Steven Moreland4b39bc12016-11-16 10:42:24 -0800394 out << "android.os.HwParcel _hidl_request = new android.os.HwParcel();\n";
395 out << "_hidl_request.writeInterfaceToken("
Yifan Hong10fe0b52016-10-19 14:20:17 -0700396 << superInterface->fullJavaName()
397 << ".kInterfaceName);\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700398
Yifan Hong10fe0b52016-10-19 14:20:17 -0700399 for (const auto &arg : method->args()) {
400 emitJavaReaderWriter(
401 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800402 "_hidl_request",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700403 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800404 false /* isReader */,
405 false /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700406 }
Andreas Huber2831d512016-08-15 09:33:47 -0700407
Martijn Coenen4de083b2017-03-16 18:49:43 +0100408 out << "\nandroid.os.HwParcel _hidl_reply = new android.os.HwParcel();\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700409
Martijn Coenen4de083b2017-03-16 18:49:43 +0100410 out.sTry([&] {
411 out << "mRemote.transact("
412 << method->getSerialId()
413 << " /* "
414 << method->name()
415 << " */, _hidl_request, _hidl_reply, ";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700416
Martijn Coenen4de083b2017-03-16 18:49:43 +0100417 if (method->isOneway()) {
418 out << "android.os.IHwBinder.FLAG_ONEWAY";
419 } else {
420 out << "0 /* flags */";
Andreas Huber2831d512016-08-15 09:33:47 -0700421 }
422
Martijn Coenen4de083b2017-03-16 18:49:43 +0100423 out << ");\n";
Andreas Huber8b5da222016-08-18 14:28:18 -0700424
Martijn Coenen4de083b2017-03-16 18:49:43 +0100425 if (!method->isOneway()) {
426 out << "_hidl_reply.verifySuccess();\n";
427 } else {
428 CHECK(!returnsValue);
429 }
430
431 out << "_hidl_request.releaseTemporaryStorage();\n";
432
433 if (returnsValue) {
434 out << "\n";
435
Andreas Huber2831d512016-08-15 09:33:47 -0700436 for (const auto &arg : method->results()) {
Martijn Coenen4de083b2017-03-16 18:49:43 +0100437 emitJavaReaderWriter(
438 out,
439 "_hidl_reply",
440 arg,
441 true /* isReader */,
442 true /* addPrefixToName */);
Andreas Huber2831d512016-08-15 09:33:47 -0700443 }
Andreas Huber2831d512016-08-15 09:33:47 -0700444
Martijn Coenen4de083b2017-03-16 18:49:43 +0100445 if (needsCallback) {
Steven Moreland4ddd8332017-04-27 19:27:18 -0700446 out << "_hidl_cb.onValues(";
Martijn Coenen4de083b2017-03-16 18:49:43 +0100447
448 bool firstField = true;
449 for (const auto &arg : method->results()) {
450 if (!firstField) {
451 out << ", ";
452 }
453
454 out << "_hidl_out_" << arg->name();
455 firstField = false;
456 }
457
458 out << ");\n";
459 } else {
460 const std::string returnName = method->results()[0]->name();
461 out << "return _hidl_out_" << returnName << ";\n";
462 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700463 }
Martijn Coenen4de083b2017-03-16 18:49:43 +0100464 }).sFinally([&] {
465 out << "_hidl_reply.release();\n";
466 }).endl();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700467
468 out.unindent();
469 out << "}\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700470 }
471
472 out.unindent();
473 out << "}\n";
474
475 ////////////////////////////////////////////////////////////////////////////
476
Yifan Hong1af73532016-11-09 14:32:58 -0800477 out << "\npublic static abstract class Stub extends android.os.HwBinder "
Andreas Huber2831d512016-08-15 09:33:47 -0700478 << "implements "
479 << ifaceName << " {\n";
480
481 out.indent();
482
Yifan Hong084d11f2016-12-21 15:33:43 -0800483 out << "@Override\npublic android.os.IHwBinder asBinder() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700484 out.indent();
485 out << "return this;\n";
486 out.unindent();
487 out << "}\n\n";
488
Yifan Hong10fe0b52016-10-19 14:20:17 -0700489 for (Method *method : iface->hidlReservedMethods()) {
Andreas Huber37065d62017-02-07 14:36:54 -0800490 if (method->isHiddenFromJava()) {
491 continue;
492 }
493
Martijn Coenenaf712c02016-11-16 15:26:27 +0100494 // b/32383557 this is a hack. We need to change this if we have more reserved methods.
495 CHECK_LE(method->results().size(), 1u);
496 std::string resultType = method->results().size() == 0 ? "void" :
497 method->results()[0]->type().getJavaType();
Yifan Hong084d11f2016-12-21 15:33:43 -0800498 out << "@Override\npublic final "
Martijn Coenenaf712c02016-11-16 15:26:27 +0100499 << resultType
Yifan Hong10fe0b52016-10-19 14:20:17 -0700500 << " "
501 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700502 << "(";
503 method->emitJavaArgSignature(out);
504 out << ") {\n";
Martijn Coenen115d4282016-12-19 05:14:04 +0100505
Yifan Hong10fe0b52016-10-19 14:20:17 -0700506 out.indent();
Steven Moreland937408a2017-03-20 09:54:18 -0700507 method->javaImpl(IMPL_INTERFACE, out);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700508 out.unindent();
509 out << "\n}\n\n";
510 }
511
Yifan Hong084d11f2016-12-21 15:33:43 -0800512 out << "@Override\n"
513 << "public android.os.IHwInterface queryLocalInterface(String descriptor) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700514 out.indent();
515 // XXX what about potential superClasses?
516 out << "if (kInterfaceName.equals(descriptor)) {\n";
517 out.indent();
518 out << "return this;\n";
519 out.unindent();
520 out << "}\n";
521 out << "return null;\n";
522 out.unindent();
523 out << "}\n\n";
524
Yifan Hong320a3492017-03-27 10:33:09 -0700525 out << "public void registerAsService(String serviceName) throws android.os.RemoteException {\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700526 out.indent();
527
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100528 out << "registerService(serviceName);\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700529
530 out.unindent();
531 out << "}\n\n";
532
Yifan Honge45b5302017-02-22 10:49:07 -0800533 out << "@Override\npublic String toString() ";
534 out.block([&] {
535 out << "return this.interfaceDescriptor() + \"@Stub\";\n";
536 }).endl().endl();
537
Yifan Hong084d11f2016-12-21 15:33:43 -0800538 out << "@Override\n"
539 << "public void onTransact("
Steven Moreland4b39bc12016-11-16 10:42:24 -0800540 << "int _hidl_code, "
541 << "android.os.HwParcel _hidl_request, "
542 << "final android.os.HwParcel _hidl_reply, "
Steven Morelanddad1b302016-12-20 15:56:00 -0800543 << "int _hidl_flags)\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700544 out.indent();
Steven Morelanddad1b302016-12-20 15:56:00 -0800545 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700546 out << "throws android.os.RemoteException {\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800547 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700548
Steven Moreland4b39bc12016-11-16 10:42:24 -0800549 out << "switch (_hidl_code) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700550
551 out.indent();
552
Yifan Hong10fe0b52016-10-19 14:20:17 -0700553 for (const auto &tuple : iface->allMethodsFromRoot()) {
554 const Method *method = tuple.method();
Andreas Huber37065d62017-02-07 14:36:54 -0800555
Yifan Hong10fe0b52016-10-19 14:20:17 -0700556 const Interface *superInterface = tuple.interface();
557 const bool returnsValue = !method->results().empty();
558 const bool needsCallback = method->results().size() > 1;
Andreas Huber2831d512016-08-15 09:33:47 -0700559
Yifan Hong10fe0b52016-10-19 14:20:17 -0700560 out << "case "
561 << method->getSerialId()
562 << " /* "
563 << method->name()
564 << " */:\n{\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700565
Yifan Hong10fe0b52016-10-19 14:20:17 -0700566 out.indent();
Andreas Huber37065d62017-02-07 14:36:54 -0800567
Martijn Coenen115d4282016-12-19 05:14:04 +0100568 if (method->isHidlReserved() && method->overridesJavaImpl(IMPL_STUB)) {
569 method->javaImpl(IMPL_STUB, out);
570 out.unindent();
571 out << "break;\n";
572 out << "}\n\n";
573 continue;
574 }
Andreas Huber2831d512016-08-15 09:33:47 -0700575
Steven Moreland4b39bc12016-11-16 10:42:24 -0800576 out << "_hidl_request.enforceInterface("
Yifan Hong10fe0b52016-10-19 14:20:17 -0700577 << superInterface->fullJavaName()
578 << ".kInterfaceName);\n\n";
579
Andreas Huber37065d62017-02-07 14:36:54 -0800580 if (method->isHiddenFromJava()) {
581 // This is a method hidden from the Java side of things, it must not
582 // return any value and will simply signal success.
583 CHECK(!returnsValue);
584
585 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
586 out << "_hidl_reply.send();\n";
587 out << "break;\n";
588 out.unindent();
589 out << "}\n\n";
590 continue;
591 }
592
Yifan Hong10fe0b52016-10-19 14:20:17 -0700593 for (const auto &arg : method->args()) {
594 emitJavaReaderWriter(
595 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800596 "_hidl_request",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700597 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800598 true /* isReader */,
599 false /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700600 }
601
602 if (!needsCallback && returnsValue) {
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700603 const NamedReference<Type>* returnArg = method->results()[0];
Yifan Hong10fe0b52016-10-19 14:20:17 -0700604
Yifan Hong4ed13472016-11-02 10:44:11 -0700605 out << returnArg->type().getJavaType()
Yifan Honga47eef32016-12-12 10:38:54 -0800606 << " _hidl_out_"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700607 << returnArg->name()
608 << " = ";
609 }
610
611 out << method->name()
612 << "(";
613
614 bool firstField = true;
615 for (const auto &arg : method->args()) {
616 if (!firstField) {
617 out << ", ";
618 }
619
620 out << arg->name();
621
622 firstField = false;
623 }
624
625 if (needsCallback) {
626 if (!firstField) {
627 out << ", ";
628 }
629
630 out << "new " << method->name() << "Callback() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700631 out.indent();
632
Yifan Hong10fe0b52016-10-19 14:20:17 -0700633 out << "@Override\n"
Yifan Hong932464e2017-03-30 15:40:22 -0700634 << "public void onValues(";
635 method->emitJavaResultSignature(out);
636 out << ") {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700637
Yifan Hong10fe0b52016-10-19 14:20:17 -0700638 out.indent();
Steven Moreland4b39bc12016-11-16 10:42:24 -0800639 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700640
641 for (const auto &arg : method->results()) {
Andreas Huber2831d512016-08-15 09:33:47 -0700642 emitJavaReaderWriter(
643 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800644 "_hidl_reply",
Andreas Huber2831d512016-08-15 09:33:47 -0700645 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800646 false /* isReader */,
647 false /* addPrefixToName */);
648 // no need to add _hidl_out because out vars are are scoped
Andreas Huber2831d512016-08-15 09:33:47 -0700649 }
650
Steven Moreland4b39bc12016-11-16 10:42:24 -0800651 out << "_hidl_reply.send();\n"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700652 << "}}";
Andreas Huber2831d512016-08-15 09:33:47 -0700653
Andreas Huber2831d512016-08-15 09:33:47 -0700654 out.unindent();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700655 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700656 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700657
658 out << ");\n";
659
Martijn Coenen0bb0d412017-02-08 10:21:30 +0100660 if (!needsCallback && !method->isOneway()) {
Steven Moreland4b39bc12016-11-16 10:42:24 -0800661 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700662
663 if (returnsValue) {
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700664 const NamedReference<Type>* returnArg = method->results()[0];
Yifan Hong10fe0b52016-10-19 14:20:17 -0700665
666 emitJavaReaderWriter(
667 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800668 "_hidl_reply",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700669 returnArg,
Yifan Honga47eef32016-12-12 10:38:54 -0800670 false /* isReader */,
671 true /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700672 }
673
Steven Moreland4b39bc12016-11-16 10:42:24 -0800674 out << "_hidl_reply.send();\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700675 }
676
677 out << "break;\n";
678 out.unindent();
679 out << "}\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700680 }
681
682 out.unindent();
683 out << "}\n";
684
685 out.unindent();
686 out << "}\n";
687
688 out.unindent();
689 out << "}\n";
690
691 out.unindent();
692 out << "}\n";
693
694 return OK;
695}
696
697status_t AST::emitJavaTypeDeclarations(Formatter &out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700698 return mRootScope.emitJavaTypeDeclarations(out, false /* atTopLevel */);
Andreas Huber2831d512016-08-15 09:33:47 -0700699}
700
701} // namespace android