blob: 0a589ae36feb8b5e909c98ce53bf0911bcc8266c [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"
22#include "Scope.h"
23
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070024#include <hidl-util/Formatter.h>
Andreas Huber2831d512016-08-15 09:33:47 -070025#include <android-base/logging.h>
26
27namespace android {
28
Andreas Huber2831d512016-08-15 09:33:47 -070029void AST::emitJavaReaderWriter(
30 Formatter &out,
31 const std::string &parcelObj,
32 const TypedVar *arg,
Yifan Honga47eef32016-12-12 10:38:54 -080033 bool isReader,
34 bool addPrefixToName) const {
Andreas Huber2831d512016-08-15 09:33:47 -070035 if (isReader) {
Yifan Hong4ed13472016-11-02 10:44:11 -070036 out << arg->type().getJavaType()
Andreas Huber2831d512016-08-15 09:33:47 -070037 << " "
Yifan Honga47eef32016-12-12 10:38:54 -080038 << (addPrefixToName ? "_hidl_out_" : "")
Andreas Huber2831d512016-08-15 09:33:47 -070039 << arg->name()
40 << " = ";
41 }
42
Yifan Honga47eef32016-12-12 10:38:54 -080043 arg->type().emitJavaReaderWriter(out, parcelObj,
44 (addPrefixToName ? "_hidl_out_" : "") + arg->name(),
45 isReader);
Andreas Huber2831d512016-08-15 09:33:47 -070046}
47
Andreas Huber0fa9e392016-08-31 09:05:44 -070048status_t AST::generateJavaTypes(
Andreas Huberd29724f2016-09-14 09:33:13 -070049 const std::string &outputPath, const std::string &limitToType) const {
Andreas Huber85eabdb2016-08-25 11:24:49 -070050 // Splits types.hal up into one java file per declared type.
51
Steven Morelandd537ab02016-09-12 10:32:01 -070052 for (const auto &type : mRootScope->getSubTypes()) {
53 std::string typeName = type->localName();
Andreas Huber85eabdb2016-08-25 11:24:49 -070054
55 if (type->isTypeDef()) {
56 continue;
57 }
58
Andreas Huberd29724f2016-09-14 09:33:13 -070059 if (!limitToType.empty() && typeName != limitToType) {
Andreas Huber0fa9e392016-08-31 09:05:44 -070060 continue;
61 }
62
Andreas Huber85eabdb2016-08-25 11:24:49 -070063 std::string path = outputPath;
64 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Yifan Hong97288ac2016-12-12 16:03:51 -080065 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */,
66 true /* sanitized */));
Andreas Huber85eabdb2016-08-25 11:24:49 -070067 path.append(typeName);
68 path.append(".java");
69
Steven Morelandf7fa0682017-05-11 16:14:55 -070070 CHECK(Coordinator::MakeParentHierarchy(path)) << path;
Andreas Huber85eabdb2016-08-25 11:24:49 -070071 FILE *file = fopen(path.c_str(), "w");
72
73 if (file == NULL) {
74 return -errno;
75 }
76
77 Formatter out(file);
78
79 std::vector<std::string> packageComponents;
80 getPackageAndVersionComponents(
81 &packageComponents, true /* cpp_compatible */);
82
83 out << "package " << mPackage.javaPackage() << ";\n\n";
84
Iliyan Malchev800273d2016-09-02 15:25:07 -070085 out << "\n";
86
Andreas Huber85eabdb2016-08-25 11:24:49 -070087 status_t err =
88 type->emitJavaTypeDeclarations(out, true /* atTopLevel */);
89
90 if (err != OK) {
91 return err;
92 }
93 }
94
95 return OK;
96}
97
Andreas Huber0fa9e392016-08-31 09:05:44 -070098status_t AST::generateJava(
Andreas Huberd29724f2016-09-14 09:33:13 -070099 const std::string &outputPath, const std::string &limitToType) const {
Andreas Huber0fa9e392016-08-31 09:05:44 -0700100 if (!isJavaCompatible()) {
Andreas Huber70a59e12016-08-16 12:57:01 -0700101 fprintf(stderr,
102 "ERROR: This interface is not Java compatible. The Java backend"
Andreas Huberf03332a2016-09-22 15:35:43 -0700103 " does NOT support union types nor native handles. "
104 "In addition, vectors of arrays are limited to at most "
Andreas Huber86a112b2016-10-19 14:25:16 -0700105 "one-dimensional arrays and vectors of {vectors,interfaces} are"
106 " not supported.\n");
Andreas Huber70a59e12016-08-16 12:57:01 -0700107
Andreas Huber2831d512016-08-15 09:33:47 -0700108 return UNKNOWN_ERROR;
109 }
110
Steven Moreland19f11b52017-05-12 18:22:21 -0700111 if (!AST::isInterface()) {
Andreas Huber0fa9e392016-08-31 09:05:44 -0700112 return generateJavaTypes(outputPath, limitToType);
113 }
114
115 const Interface *iface = mRootScope->getInterface();
Steven Moreland19f11b52017-05-12 18:22:21 -0700116 std::string ifaceName = iface->localName();
Andreas Huber0fa9e392016-08-31 09:05:44 -0700117
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700118 const std::string baseName = iface->getBaseName();
Andreas Huber2831d512016-08-15 09:33:47 -0700119
120 std::string path = outputPath;
121 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Yifan Hong97288ac2016-12-12 16:03:51 -0800122 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */,
123 true /* sanitized */));
Andreas Huber2831d512016-08-15 09:33:47 -0700124 path.append(ifaceName);
125 path.append(".java");
126
127 CHECK(Coordinator::MakeParentHierarchy(path));
128 FILE *file = fopen(path.c_str(), "w");
129
130 if (file == NULL) {
131 return -errno;
132 }
133
134 Formatter out(file);
135
136 std::vector<std::string> packageComponents;
137 getPackageAndVersionComponents(
138 &packageComponents, true /* cpp_compatible */);
139
140 out << "package " << mPackage.javaPackage() << ";\n\n";
141
Andreas Huber2831d512016-08-15 09:33:47 -0700142 out.setNamespace(mPackage.javaPackage() + ".");
143
Andreas Huber2831d512016-08-15 09:33:47 -0700144 const Interface *superType = iface->superType();
145
146 out << "public interface " << ifaceName << " extends ";
147
148 if (superType != NULL) {
149 out << superType->fullJavaName();
150 } else {
Yifan Hong1af73532016-11-09 14:32:58 -0800151 out << "android.os.IHwInterface";
Andreas Huber2831d512016-08-15 09:33:47 -0700152 }
153
154 out << " {\n";
155 out.indent();
156
157 out << "public static final String kInterfaceName = \""
158 << mPackage.string()
159 << "::"
160 << ifaceName
161 << "\";\n\n";
162
Andreas Hubera2abe982017-04-04 14:42:09 -0700163 out << "/* package private */ static "
Andreas Huber2831d512016-08-15 09:33:47 -0700164 << ifaceName
Yifan Hong1af73532016-11-09 14:32:58 -0800165 << " asInterface(android.os.IHwBinder binder) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700166
167 out.indent();
168
169 out << "if (binder == null) {\n";
170 out.indent();
171 out << "return null;\n";
172 out.unindent();
173 out << "}\n\n";
174
Yifan Hong1af73532016-11-09 14:32:58 -0800175 out << "android.os.IHwInterface iface =\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700176 out.indent();
177 out.indent();
178 out << "binder.queryLocalInterface(kInterfaceName);\n\n";
179 out.unindent();
180 out.unindent();
181
182 out << "if ((iface != null) && (iface instanceof "
183 << ifaceName
184 << ")) {\n";
185
186 out.indent();
187 out << "return (" << ifaceName << ")iface;\n";
188 out.unindent();
189 out << "}\n\n";
190
Andreas Hubera2abe982017-04-04 14:42:09 -0700191 out << ifaceName << " proxy = new " << ifaceName << ".Proxy(binder);\n\n";
192 out << "try {\n";
193 out.indent();
194 out << "for (String descriptor : proxy.interfaceChain()) {\n";
195 out.indent();
196 out << "if (descriptor.equals(kInterfaceName)) {\n";
197 out.indent();
198 out << "return proxy;\n";
199 out.unindent();
200 out << "}\n";
201 out.unindent();
202 out << "}\n";
203 out.unindent();
204 out << "} catch (android.os.RemoteException e) {\n";
205 out.indent();
206 out.unindent();
207 out << "}\n\n";
208
209 out << "return null;\n";
210
211 out.unindent();
212 out << "}\n\n";
213
214 out << "public static "
215 << ifaceName
216 << " castFrom(android.os.IHwInterface iface) {\n";
217 out.indent();
218
219 out << "return (iface == null) ? null : "
220 << ifaceName
221 << ".asInterface(iface.asBinder());\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700222
223 out.unindent();
224 out << "}\n\n";
225
Yifan Hong084d11f2016-12-21 15:33:43 -0800226 out << "@Override\npublic android.os.IHwBinder asBinder();\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700227
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700228 out << "public static "
229 << ifaceName
Yifan Hong320a3492017-03-27 10:33:09 -0700230 << " getService(String serviceName) throws android.os.RemoteException {\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700231
232 out.indent();
233
234 out << "return "
235 << ifaceName
Yifan Hong1af73532016-11-09 14:32:58 -0800236 << ".asInterface(android.os.HwBinder.getService(\""
Steven Moreland7e367bf2016-11-04 11:31:41 -0700237 << iface->fqName().string()
238 << "\",serviceName));\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700239
240 out.unindent();
241
242 out << "}\n\n";
243
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800244 out << "public static "
245 << ifaceName
Yifan Hong320a3492017-03-27 10:33:09 -0700246 << " getService() throws android.os.RemoteException {\n";
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800247
248 out.indent();
249
250 out << "return "
251 << ifaceName
252 << ".asInterface(android.os.HwBinder.getService(\""
253 << iface->fqName().string()
254 << "\",\"default\"));\n";
255
256 out.unindent();
257
258 out << "}\n\n";
259
Andreas Huber2831d512016-08-15 09:33:47 -0700260 status_t err = emitJavaTypeDeclarations(out);
261
262 if (err != OK) {
263 return err;
264 }
265
Andreas Huber2831d512016-08-15 09:33:47 -0700266 for (const auto &method : iface->methods()) {
Andreas Huber37065d62017-02-07 14:36:54 -0800267 if (method->isHiddenFromJava()) {
268 continue;
269 }
270
Andreas Huber2831d512016-08-15 09:33:47 -0700271 const bool returnsValue = !method->results().empty();
272 const bool needsCallback = method->results().size() > 1;
273
274 if (needsCallback) {
Yifan Hong601cfca2017-05-24 12:20:17 -0700275 out << "\n@java.lang.FunctionalInterface\npublic interface " << method->name()
Andreas Huber2831d512016-08-15 09:33:47 -0700276 << "Callback {\n";
277
278 out.indent();
279
Yifan Hong932464e2017-03-30 15:40:22 -0700280 out << "public void onValues(";
281 method->emitJavaResultSignature(out);
282 out << ");\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700283
284 out.unindent();
285 out << "}\n\n";
286 }
287
288 if (returnsValue && !needsCallback) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700289 out << method->results()[0]->type().getJavaType();
Andreas Huber2831d512016-08-15 09:33:47 -0700290 } else {
291 out << "void";
292 }
293
294 out << " "
295 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700296 << "(";
297 method->emitJavaArgSignature(out);
Andreas Huber2831d512016-08-15 09:33:47 -0700298
299 if (needsCallback) {
300 if (!method->args().empty()) {
301 out << ", ";
302 }
303
304 out << method->name()
Steven Moreland4ddd8332017-04-27 19:27:18 -0700305 << "Callback _hidl_cb";
Andreas Huber2831d512016-08-15 09:33:47 -0700306 }
307
Steven Morelanddad1b302016-12-20 15:56:00 -0800308 out << ")\n";
309 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700310 out << "throws android.os.RemoteException;\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800311 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700312 }
313
314 out << "\npublic static final class Proxy implements "
315 << ifaceName
316 << " {\n";
317
318 out.indent();
319
Yifan Hong1af73532016-11-09 14:32:58 -0800320 out << "private android.os.IHwBinder mRemote;\n\n";
321 out << "public Proxy(android.os.IHwBinder remote) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700322 out.indent();
Yifan Hong729e7962016-12-21 16:04:27 -0800323 out << "mRemote = java.util.Objects.requireNonNull(remote);\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700324 out.unindent();
325 out << "}\n\n";
326
Yifan Hong084d11f2016-12-21 15:33:43 -0800327 out << "@Override\npublic android.os.IHwBinder asBinder() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700328 out.indent();
329 out << "return mRemote;\n";
330 out.unindent();
331 out << "}\n\n";
332
Yifan Honge45b5302017-02-22 10:49:07 -0800333
334 out << "@Override\npublic String toString() ";
335 out.block([&] {
336 out.sTry([&] {
337 out << "return this.interfaceDescriptor() + \"@Proxy\";\n";
Yifan Hong320a3492017-03-27 10:33:09 -0700338 }).sCatch("android.os.RemoteException ex", [&] {
Yifan Honge45b5302017-02-22 10:49:07 -0800339 out << "/* ignored; handled below. */\n";
340 }).endl();
341 out << "return \"[class or subclass of \" + "
342 << ifaceName << ".kInterfaceName + \"]@Proxy\";\n";
343 }).endl().endl();
344
Yifan Hong10fe0b52016-10-19 14:20:17 -0700345 const Interface *prevInterface = nullptr;
346 for (const auto &tuple : iface->allMethodsFromRoot()) {
347 const Method *method = tuple.method();
Andreas Huber37065d62017-02-07 14:36:54 -0800348
349 if (method->isHiddenFromJava()) {
350 continue;
351 }
352
Yifan Hong10fe0b52016-10-19 14:20:17 -0700353 const Interface *superInterface = tuple.interface();
354 if (prevInterface != superInterface) {
355 out << "// Methods from "
356 << superInterface->fullName()
357 << " follow.\n";
358 prevInterface = superInterface;
359 }
360 const bool returnsValue = !method->results().empty();
361 const bool needsCallback = method->results().size() > 1;
Andreas Huber2831d512016-08-15 09:33:47 -0700362
Yifan Hong084d11f2016-12-21 15:33:43 -0800363 out << "@Override\npublic ";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700364 if (returnsValue && !needsCallback) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700365 out << method->results()[0]->type().getJavaType();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700366 } else {
367 out << "void";
368 }
Andreas Huber2831d512016-08-15 09:33:47 -0700369
Yifan Hong10fe0b52016-10-19 14:20:17 -0700370 out << " "
371 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700372 << "(";
373 method->emitJavaArgSignature(out);
Andreas Huber2831d512016-08-15 09:33:47 -0700374
Yifan Hong10fe0b52016-10-19 14:20:17 -0700375 if (needsCallback) {
376 if (!method->args().empty()) {
377 out << ", ";
Andreas Huber2831d512016-08-15 09:33:47 -0700378 }
379
Yifan Hong10fe0b52016-10-19 14:20:17 -0700380 out << method->name()
Steven Moreland4ddd8332017-04-27 19:27:18 -0700381 << "Callback _hidl_cb";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700382 }
Andreas Huber2831d512016-08-15 09:33:47 -0700383
Steven Morelanddad1b302016-12-20 15:56:00 -0800384 out << ")\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700385 out.indent();
Steven Morelanddad1b302016-12-20 15:56:00 -0800386 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700387 out << "throws android.os.RemoteException {\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800388 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700389
Martijn Coenen115d4282016-12-19 05:14:04 +0100390 if (method->isHidlReserved() && method->overridesJavaImpl(IMPL_PROXY)) {
391 method->javaImpl(IMPL_PROXY, out);
392 out.unindent();
393 out << "}\n";
394 continue;
395 }
Steven Moreland4b39bc12016-11-16 10:42:24 -0800396 out << "android.os.HwParcel _hidl_request = new android.os.HwParcel();\n";
397 out << "_hidl_request.writeInterfaceToken("
Yifan Hong10fe0b52016-10-19 14:20:17 -0700398 << superInterface->fullJavaName()
399 << ".kInterfaceName);\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700400
Yifan Hong10fe0b52016-10-19 14:20:17 -0700401 for (const auto &arg : method->args()) {
402 emitJavaReaderWriter(
403 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800404 "_hidl_request",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700405 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800406 false /* isReader */,
407 false /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700408 }
Andreas Huber2831d512016-08-15 09:33:47 -0700409
Martijn Coenen4de083b2017-03-16 18:49:43 +0100410 out << "\nandroid.os.HwParcel _hidl_reply = new android.os.HwParcel();\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700411
Martijn Coenen4de083b2017-03-16 18:49:43 +0100412 out.sTry([&] {
413 out << "mRemote.transact("
414 << method->getSerialId()
415 << " /* "
416 << method->name()
417 << " */, _hidl_request, _hidl_reply, ";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700418
Martijn Coenen4de083b2017-03-16 18:49:43 +0100419 if (method->isOneway()) {
420 out << "android.os.IHwBinder.FLAG_ONEWAY";
421 } else {
422 out << "0 /* flags */";
Andreas Huber2831d512016-08-15 09:33:47 -0700423 }
424
Martijn Coenen4de083b2017-03-16 18:49:43 +0100425 out << ");\n";
Andreas Huber8b5da222016-08-18 14:28:18 -0700426
Martijn Coenen4de083b2017-03-16 18:49:43 +0100427 if (!method->isOneway()) {
428 out << "_hidl_reply.verifySuccess();\n";
429 } else {
430 CHECK(!returnsValue);
431 }
432
433 out << "_hidl_request.releaseTemporaryStorage();\n";
434
435 if (returnsValue) {
436 out << "\n";
437
Andreas Huber2831d512016-08-15 09:33:47 -0700438 for (const auto &arg : method->results()) {
Martijn Coenen4de083b2017-03-16 18:49:43 +0100439 emitJavaReaderWriter(
440 out,
441 "_hidl_reply",
442 arg,
443 true /* isReader */,
444 true /* addPrefixToName */);
Andreas Huber2831d512016-08-15 09:33:47 -0700445 }
Andreas Huber2831d512016-08-15 09:33:47 -0700446
Martijn Coenen4de083b2017-03-16 18:49:43 +0100447 if (needsCallback) {
Steven Moreland4ddd8332017-04-27 19:27:18 -0700448 out << "_hidl_cb.onValues(";
Martijn Coenen4de083b2017-03-16 18:49:43 +0100449
450 bool firstField = true;
451 for (const auto &arg : method->results()) {
452 if (!firstField) {
453 out << ", ";
454 }
455
456 out << "_hidl_out_" << arg->name();
457 firstField = false;
458 }
459
460 out << ");\n";
461 } else {
462 const std::string returnName = method->results()[0]->name();
463 out << "return _hidl_out_" << returnName << ";\n";
464 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700465 }
Martijn Coenen4de083b2017-03-16 18:49:43 +0100466 }).sFinally([&] {
467 out << "_hidl_reply.release();\n";
468 }).endl();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700469
470 out.unindent();
471 out << "}\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700472 }
473
474 out.unindent();
475 out << "}\n";
476
477 ////////////////////////////////////////////////////////////////////////////
478
Yifan Hong1af73532016-11-09 14:32:58 -0800479 out << "\npublic static abstract class Stub extends android.os.HwBinder "
Andreas Huber2831d512016-08-15 09:33:47 -0700480 << "implements "
481 << ifaceName << " {\n";
482
483 out.indent();
484
Yifan Hong084d11f2016-12-21 15:33:43 -0800485 out << "@Override\npublic android.os.IHwBinder asBinder() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700486 out.indent();
487 out << "return this;\n";
488 out.unindent();
489 out << "}\n\n";
490
Yifan Hong10fe0b52016-10-19 14:20:17 -0700491 for (Method *method : iface->hidlReservedMethods()) {
Andreas Huber37065d62017-02-07 14:36:54 -0800492 if (method->isHiddenFromJava()) {
493 continue;
494 }
495
Martijn Coenenaf712c02016-11-16 15:26:27 +0100496 // b/32383557 this is a hack. We need to change this if we have more reserved methods.
497 CHECK_LE(method->results().size(), 1u);
498 std::string resultType = method->results().size() == 0 ? "void" :
499 method->results()[0]->type().getJavaType();
Yifan Hong084d11f2016-12-21 15:33:43 -0800500 out << "@Override\npublic final "
Martijn Coenenaf712c02016-11-16 15:26:27 +0100501 << resultType
Yifan Hong10fe0b52016-10-19 14:20:17 -0700502 << " "
503 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700504 << "(";
505 method->emitJavaArgSignature(out);
506 out << ") {\n";
Martijn Coenen115d4282016-12-19 05:14:04 +0100507
Yifan Hong10fe0b52016-10-19 14:20:17 -0700508 out.indent();
Steven Moreland937408a2017-03-20 09:54:18 -0700509 method->javaImpl(IMPL_INTERFACE, out);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700510 out.unindent();
511 out << "\n}\n\n";
512 }
513
Yifan Hong084d11f2016-12-21 15:33:43 -0800514 out << "@Override\n"
515 << "public android.os.IHwInterface queryLocalInterface(String descriptor) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700516 out.indent();
517 // XXX what about potential superClasses?
518 out << "if (kInterfaceName.equals(descriptor)) {\n";
519 out.indent();
520 out << "return this;\n";
521 out.unindent();
522 out << "}\n";
523 out << "return null;\n";
524 out.unindent();
525 out << "}\n\n";
526
Yifan Hong320a3492017-03-27 10:33:09 -0700527 out << "public void registerAsService(String serviceName) throws android.os.RemoteException {\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700528 out.indent();
529
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100530 out << "registerService(serviceName);\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700531
532 out.unindent();
533 out << "}\n\n";
534
Yifan Honge45b5302017-02-22 10:49:07 -0800535 out << "@Override\npublic String toString() ";
536 out.block([&] {
537 out << "return this.interfaceDescriptor() + \"@Stub\";\n";
538 }).endl().endl();
539
Yifan Hong084d11f2016-12-21 15:33:43 -0800540 out << "@Override\n"
541 << "public void onTransact("
Steven Moreland4b39bc12016-11-16 10:42:24 -0800542 << "int _hidl_code, "
543 << "android.os.HwParcel _hidl_request, "
544 << "final android.os.HwParcel _hidl_reply, "
Steven Morelanddad1b302016-12-20 15:56:00 -0800545 << "int _hidl_flags)\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700546 out.indent();
Steven Morelanddad1b302016-12-20 15:56:00 -0800547 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700548 out << "throws android.os.RemoteException {\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800549 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700550
Steven Moreland4b39bc12016-11-16 10:42:24 -0800551 out << "switch (_hidl_code) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700552
553 out.indent();
554
Yifan Hong10fe0b52016-10-19 14:20:17 -0700555 for (const auto &tuple : iface->allMethodsFromRoot()) {
556 const Method *method = tuple.method();
Andreas Huber37065d62017-02-07 14:36:54 -0800557
Yifan Hong10fe0b52016-10-19 14:20:17 -0700558 const Interface *superInterface = tuple.interface();
559 const bool returnsValue = !method->results().empty();
560 const bool needsCallback = method->results().size() > 1;
Andreas Huber2831d512016-08-15 09:33:47 -0700561
Yifan Hong10fe0b52016-10-19 14:20:17 -0700562 out << "case "
563 << method->getSerialId()
564 << " /* "
565 << method->name()
566 << " */:\n{\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700567
Yifan Hong10fe0b52016-10-19 14:20:17 -0700568 out.indent();
Andreas Huber37065d62017-02-07 14:36:54 -0800569
Martijn Coenen115d4282016-12-19 05:14:04 +0100570 if (method->isHidlReserved() && method->overridesJavaImpl(IMPL_STUB)) {
571 method->javaImpl(IMPL_STUB, out);
572 out.unindent();
573 out << "break;\n";
574 out << "}\n\n";
575 continue;
576 }
Andreas Huber2831d512016-08-15 09:33:47 -0700577
Steven Moreland4b39bc12016-11-16 10:42:24 -0800578 out << "_hidl_request.enforceInterface("
Yifan Hong10fe0b52016-10-19 14:20:17 -0700579 << superInterface->fullJavaName()
580 << ".kInterfaceName);\n\n";
581
Andreas Huber37065d62017-02-07 14:36:54 -0800582 if (method->isHiddenFromJava()) {
583 // This is a method hidden from the Java side of things, it must not
584 // return any value and will simply signal success.
585 CHECK(!returnsValue);
586
587 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
588 out << "_hidl_reply.send();\n";
589 out << "break;\n";
590 out.unindent();
591 out << "}\n\n";
592 continue;
593 }
594
Yifan Hong10fe0b52016-10-19 14:20:17 -0700595 for (const auto &arg : method->args()) {
596 emitJavaReaderWriter(
597 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800598 "_hidl_request",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700599 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800600 true /* isReader */,
601 false /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700602 }
603
604 if (!needsCallback && returnsValue) {
605 const TypedVar *returnArg = method->results()[0];
Yifan Hong10fe0b52016-10-19 14:20:17 -0700606
Yifan Hong4ed13472016-11-02 10:44:11 -0700607 out << returnArg->type().getJavaType()
Yifan Honga47eef32016-12-12 10:38:54 -0800608 << " _hidl_out_"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700609 << returnArg->name()
610 << " = ";
611 }
612
613 out << method->name()
614 << "(";
615
616 bool firstField = true;
617 for (const auto &arg : method->args()) {
618 if (!firstField) {
619 out << ", ";
620 }
621
622 out << arg->name();
623
624 firstField = false;
625 }
626
627 if (needsCallback) {
628 if (!firstField) {
629 out << ", ";
630 }
631
632 out << "new " << method->name() << "Callback() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700633 out.indent();
634
Yifan Hong10fe0b52016-10-19 14:20:17 -0700635 out << "@Override\n"
Yifan Hong932464e2017-03-30 15:40:22 -0700636 << "public void onValues(";
637 method->emitJavaResultSignature(out);
638 out << ") {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700639
Yifan Hong10fe0b52016-10-19 14:20:17 -0700640 out.indent();
Steven Moreland4b39bc12016-11-16 10:42:24 -0800641 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700642
643 for (const auto &arg : method->results()) {
Andreas Huber2831d512016-08-15 09:33:47 -0700644 emitJavaReaderWriter(
645 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800646 "_hidl_reply",
Andreas Huber2831d512016-08-15 09:33:47 -0700647 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800648 false /* isReader */,
649 false /* addPrefixToName */);
650 // no need to add _hidl_out because out vars are are scoped
Andreas Huber2831d512016-08-15 09:33:47 -0700651 }
652
Steven Moreland4b39bc12016-11-16 10:42:24 -0800653 out << "_hidl_reply.send();\n"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700654 << "}}";
Andreas Huber2831d512016-08-15 09:33:47 -0700655
Andreas Huber2831d512016-08-15 09:33:47 -0700656 out.unindent();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700657 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700658 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700659
660 out << ");\n";
661
Martijn Coenen0bb0d412017-02-08 10:21:30 +0100662 if (!needsCallback && !method->isOneway()) {
Steven Moreland4b39bc12016-11-16 10:42:24 -0800663 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700664
665 if (returnsValue) {
666 const TypedVar *returnArg = method->results()[0];
667
668 emitJavaReaderWriter(
669 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800670 "_hidl_reply",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700671 returnArg,
Yifan Honga47eef32016-12-12 10:38:54 -0800672 false /* isReader */,
673 true /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700674 }
675
Steven Moreland4b39bc12016-11-16 10:42:24 -0800676 out << "_hidl_reply.send();\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700677 }
678
679 out << "break;\n";
680 out.unindent();
681 out << "}\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700682 }
683
684 out.unindent();
685 out << "}\n";
686
687 out.unindent();
688 out << "}\n";
689
690 out.unindent();
691 out << "}\n";
692
693 out.unindent();
694 out << "}\n";
695
696 return OK;
697}
698
699status_t AST::emitJavaTypeDeclarations(Formatter &out) const {
Andreas Huber85eabdb2016-08-25 11:24:49 -0700700 return mRootScope->emitJavaTypeDeclarations(out, false /* atTopLevel */);
Andreas Huber2831d512016-08-15 09:33:47 -0700701}
702
703} // namespace android