blob: 3e8d493a07860c05ec79e673cd50413a829a586d [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
70 CHECK(Coordinator::MakeParentHierarchy(path));
71 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
Andreas Huber0fa9e392016-08-31 09:05:44 -0700111 std::string ifaceName;
112 if (!AST::isInterface(&ifaceName)) {
113 return generateJavaTypes(outputPath, limitToType);
114 }
115
116 const Interface *iface = mRootScope->getInterface();
117
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
Steven Morelanddad1b302016-12-20 15:56:00 -0800142 out << "import android.os.RemoteException;\n\n";
143
Andreas Huber2831d512016-08-15 09:33:47 -0700144 out.setNamespace(mPackage.javaPackage() + ".");
145
Andreas Huber2831d512016-08-15 09:33:47 -0700146 const Interface *superType = iface->superType();
147
148 out << "public interface " << ifaceName << " extends ";
149
150 if (superType != NULL) {
151 out << superType->fullJavaName();
152 } else {
Yifan Hong1af73532016-11-09 14:32:58 -0800153 out << "android.os.IHwInterface";
Andreas Huber2831d512016-08-15 09:33:47 -0700154 }
155
156 out << " {\n";
157 out.indent();
158
159 out << "public static final String kInterfaceName = \""
160 << mPackage.string()
161 << "::"
162 << ifaceName
163 << "\";\n\n";
164
165 out << "public static "
166 << ifaceName
Yifan Hong1af73532016-11-09 14:32:58 -0800167 << " asInterface(android.os.IHwBinder binder) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700168
169 out.indent();
170
171 out << "if (binder == null) {\n";
172 out.indent();
173 out << "return null;\n";
174 out.unindent();
175 out << "}\n\n";
176
Yifan Hong1af73532016-11-09 14:32:58 -0800177 out << "android.os.IHwInterface iface =\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700178 out.indent();
179 out.indent();
180 out << "binder.queryLocalInterface(kInterfaceName);\n\n";
181 out.unindent();
182 out.unindent();
183
184 out << "if ((iface != null) && (iface instanceof "
185 << ifaceName
186 << ")) {\n";
187
188 out.indent();
189 out << "return (" << ifaceName << ")iface;\n";
190 out.unindent();
191 out << "}\n\n";
192
193 out << "return new " << ifaceName << ".Proxy(binder);\n";
194
195 out.unindent();
196 out << "}\n\n";
197
Yifan Hong084d11f2016-12-21 15:33:43 -0800198 out << "@Override\npublic android.os.IHwBinder asBinder();\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700199
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700200 out << "public static "
201 << ifaceName
Steven Moreland64af5e82017-01-04 10:58:55 -0800202 << " getService(String serviceName) throws RemoteException {\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700203
204 out.indent();
205
206 out << "return "
207 << ifaceName
Yifan Hong1af73532016-11-09 14:32:58 -0800208 << ".asInterface(android.os.HwBinder.getService(\""
Steven Moreland7e367bf2016-11-04 11:31:41 -0700209 << iface->fqName().string()
210 << "\",serviceName));\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700211
212 out.unindent();
213
214 out << "}\n\n";
215
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800216 out << "public static "
217 << ifaceName
218 << " getService() throws RemoteException {\n";
219
220 out.indent();
221
222 out << "return "
223 << ifaceName
224 << ".asInterface(android.os.HwBinder.getService(\""
225 << iface->fqName().string()
226 << "\",\"default\"));\n";
227
228 out.unindent();
229
230 out << "}\n\n";
231
Andreas Huber2831d512016-08-15 09:33:47 -0700232 status_t err = emitJavaTypeDeclarations(out);
233
234 if (err != OK) {
235 return err;
236 }
237
Andreas Huber2831d512016-08-15 09:33:47 -0700238 for (const auto &method : iface->methods()) {
Andreas Huber37065d62017-02-07 14:36:54 -0800239 if (method->isHiddenFromJava()) {
240 continue;
241 }
242
Andreas Huber2831d512016-08-15 09:33:47 -0700243 const bool returnsValue = !method->results().empty();
244 const bool needsCallback = method->results().size() > 1;
245
246 if (needsCallback) {
Steven Morelandbcd79032016-12-16 20:50:23 -0800247 out << "\npublic interface "
Andreas Huber2831d512016-08-15 09:33:47 -0700248 << method->name()
249 << "Callback {\n";
250
251 out.indent();
252
Steven Morelandbcd79032016-12-16 20:50:23 -0800253 out << "public void onValues("
Steven Morelanda7a421a2016-09-07 08:35:18 -0700254 << Method::GetJavaArgSignature(method->results())
Andreas Huber2831d512016-08-15 09:33:47 -0700255 << ");\n";
256
257 out.unindent();
258 out << "}\n\n";
259 }
260
261 if (returnsValue && !needsCallback) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700262 out << method->results()[0]->type().getJavaType();
Andreas Huber2831d512016-08-15 09:33:47 -0700263 } else {
264 out << "void";
265 }
266
267 out << " "
268 << method->name()
269 << "("
Steven Morelanda7a421a2016-09-07 08:35:18 -0700270 << Method::GetJavaArgSignature(method->args());
Andreas Huber2831d512016-08-15 09:33:47 -0700271
272 if (needsCallback) {
273 if (!method->args().empty()) {
274 out << ", ";
275 }
276
277 out << method->name()
278 << "Callback cb";
279 }
280
Steven Morelanddad1b302016-12-20 15:56:00 -0800281 out << ")\n";
282 out.indent();
283 out << "throws RemoteException;\n";
284 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700285 }
286
287 out << "\npublic static final class Proxy implements "
288 << ifaceName
289 << " {\n";
290
291 out.indent();
292
Yifan Hong1af73532016-11-09 14:32:58 -0800293 out << "private android.os.IHwBinder mRemote;\n\n";
294 out << "public Proxy(android.os.IHwBinder remote) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700295 out.indent();
Yifan Hong729e7962016-12-21 16:04:27 -0800296 out << "mRemote = java.util.Objects.requireNonNull(remote);\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700297 out.unindent();
298 out << "}\n\n";
299
Yifan Hong084d11f2016-12-21 15:33:43 -0800300 out << "@Override\npublic android.os.IHwBinder asBinder() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700301 out.indent();
302 out << "return mRemote;\n";
303 out.unindent();
304 out << "}\n\n";
305
Yifan Honge45b5302017-02-22 10:49:07 -0800306
307 out << "@Override\npublic String toString() ";
308 out.block([&] {
309 out.sTry([&] {
310 out << "return this.interfaceDescriptor() + \"@Proxy\";\n";
311 }).sCatch("RemoteException ex", [&] {
312 out << "/* ignored; handled below. */\n";
313 }).endl();
314 out << "return \"[class or subclass of \" + "
315 << ifaceName << ".kInterfaceName + \"]@Proxy\";\n";
316 }).endl().endl();
317
Yifan Hong10fe0b52016-10-19 14:20:17 -0700318 const Interface *prevInterface = nullptr;
319 for (const auto &tuple : iface->allMethodsFromRoot()) {
320 const Method *method = tuple.method();
Andreas Huber37065d62017-02-07 14:36:54 -0800321
322 if (method->isHiddenFromJava()) {
323 continue;
324 }
325
Yifan Hong10fe0b52016-10-19 14:20:17 -0700326 const Interface *superInterface = tuple.interface();
327 if (prevInterface != superInterface) {
328 out << "// Methods from "
329 << superInterface->fullName()
330 << " follow.\n";
331 prevInterface = superInterface;
332 }
333 const bool returnsValue = !method->results().empty();
334 const bool needsCallback = method->results().size() > 1;
Andreas Huber2831d512016-08-15 09:33:47 -0700335
Yifan Hong084d11f2016-12-21 15:33:43 -0800336 out << "@Override\npublic ";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700337 if (returnsValue && !needsCallback) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700338 out << method->results()[0]->type().getJavaType();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700339 } else {
340 out << "void";
341 }
Andreas Huber2831d512016-08-15 09:33:47 -0700342
Yifan Hong10fe0b52016-10-19 14:20:17 -0700343 out << " "
344 << method->name()
345 << "("
346 << Method::GetJavaArgSignature(method->args());
Andreas Huber2831d512016-08-15 09:33:47 -0700347
Yifan Hong10fe0b52016-10-19 14:20:17 -0700348 if (needsCallback) {
349 if (!method->args().empty()) {
350 out << ", ";
Andreas Huber2831d512016-08-15 09:33:47 -0700351 }
352
Yifan Hong10fe0b52016-10-19 14:20:17 -0700353 out << method->name()
354 << "Callback cb";
355 }
Andreas Huber2831d512016-08-15 09:33:47 -0700356
Steven Morelanddad1b302016-12-20 15:56:00 -0800357 out << ")\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700358 out.indent();
Steven Morelanddad1b302016-12-20 15:56:00 -0800359 out.indent();
360 out << "throws RemoteException {\n";
361 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700362
Martijn Coenen115d4282016-12-19 05:14:04 +0100363 if (method->isHidlReserved() && method->overridesJavaImpl(IMPL_PROXY)) {
364 method->javaImpl(IMPL_PROXY, out);
365 out.unindent();
366 out << "}\n";
367 continue;
368 }
Steven Moreland4b39bc12016-11-16 10:42:24 -0800369 out << "android.os.HwParcel _hidl_request = new android.os.HwParcel();\n";
370 out << "_hidl_request.writeInterfaceToken("
Yifan Hong10fe0b52016-10-19 14:20:17 -0700371 << superInterface->fullJavaName()
372 << ".kInterfaceName);\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700373
Yifan Hong10fe0b52016-10-19 14:20:17 -0700374 for (const auto &arg : method->args()) {
375 emitJavaReaderWriter(
376 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800377 "_hidl_request",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700378 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800379 false /* isReader */,
380 false /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700381 }
Andreas Huber2831d512016-08-15 09:33:47 -0700382
Steven Moreland4b39bc12016-11-16 10:42:24 -0800383 out << "\nandroid.os.HwParcel _hidl_reply = new android.os.HwParcel();\n"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700384 << "mRemote.transact("
385 << method->getSerialId()
386 << " /* "
387 << method->name()
Steven Moreland4b39bc12016-11-16 10:42:24 -0800388 << " */, _hidl_request, _hidl_reply, ";
Andreas Huber2831d512016-08-15 09:33:47 -0700389
Yifan Hong10fe0b52016-10-19 14:20:17 -0700390 if (method->isOneway()) {
Yifan Hong1af73532016-11-09 14:32:58 -0800391 out << "android.os.IHwBinder.FLAG_ONEWAY";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700392 } else {
393 out << "0 /* flags */";
394 }
395
396 out << ");\n";
397
398 if (!method->isOneway()) {
Steven Moreland4b39bc12016-11-16 10:42:24 -0800399 out << "_hidl_reply.verifySuccess();\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700400 } else {
401 CHECK(!returnsValue);
402 }
403
Steven Moreland4b39bc12016-11-16 10:42:24 -0800404 out << "_hidl_request.releaseTemporaryStorage();\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700405
406 if (returnsValue) {
407 out << "\n";
408
409 for (const auto &arg : method->results()) {
Andreas Huber2831d512016-08-15 09:33:47 -0700410 emitJavaReaderWriter(
411 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800412 "_hidl_reply",
Andreas Huber2831d512016-08-15 09:33:47 -0700413 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800414 true /* isReader */,
415 true /* addPrefixToName */);
Andreas Huber2831d512016-08-15 09:33:47 -0700416 }
417
Yifan Hong10fe0b52016-10-19 14:20:17 -0700418 if (needsCallback) {
419 out << "cb.onValues(";
Andreas Huber8b5da222016-08-18 14:28:18 -0700420
Yifan Hong10fe0b52016-10-19 14:20:17 -0700421 bool firstField = true;
Andreas Huber2831d512016-08-15 09:33:47 -0700422 for (const auto &arg : method->results()) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700423 if (!firstField) {
424 out << ", ";
Andreas Huber2831d512016-08-15 09:33:47 -0700425 }
426
Yifan Honga47eef32016-12-12 10:38:54 -0800427 out << "_hidl_out_" << arg->name();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700428 firstField = false;
Andreas Huber2831d512016-08-15 09:33:47 -0700429 }
Andreas Huber2831d512016-08-15 09:33:47 -0700430
Yifan Hong10fe0b52016-10-19 14:20:17 -0700431 out << ");\n";
432 } else {
433 const std::string returnName = method->results()[0]->name();
Yifan Honga47eef32016-12-12 10:38:54 -0800434 out << "return _hidl_out_" << returnName << ";\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700435 }
Andreas Huber2831d512016-08-15 09:33:47 -0700436 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700437
438 out.unindent();
439 out << "}\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700440 }
441
442 out.unindent();
443 out << "}\n";
444
445 ////////////////////////////////////////////////////////////////////////////
446
Yifan Hong1af73532016-11-09 14:32:58 -0800447 out << "\npublic static abstract class Stub extends android.os.HwBinder "
Andreas Huber2831d512016-08-15 09:33:47 -0700448 << "implements "
449 << ifaceName << " {\n";
450
451 out.indent();
452
Yifan Hong084d11f2016-12-21 15:33:43 -0800453 out << "@Override\npublic android.os.IHwBinder asBinder() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700454 out.indent();
455 out << "return this;\n";
456 out.unindent();
457 out << "}\n\n";
458
Yifan Hong10fe0b52016-10-19 14:20:17 -0700459 for (Method *method : iface->hidlReservedMethods()) {
Andreas Huber37065d62017-02-07 14:36:54 -0800460 if (method->isHiddenFromJava()) {
461 continue;
462 }
463
Martijn Coenenaf712c02016-11-16 15:26:27 +0100464 // b/32383557 this is a hack. We need to change this if we have more reserved methods.
465 CHECK_LE(method->results().size(), 1u);
466 std::string resultType = method->results().size() == 0 ? "void" :
467 method->results()[0]->type().getJavaType();
Yifan Hong084d11f2016-12-21 15:33:43 -0800468 out << "@Override\npublic final "
Martijn Coenenaf712c02016-11-16 15:26:27 +0100469 << resultType
Yifan Hong10fe0b52016-10-19 14:20:17 -0700470 << " "
471 << method->name()
Martijn Coenen115d4282016-12-19 05:14:04 +0100472 << "("
473 << Method::GetJavaArgSignature(method->args())
474 << ") {\n";
475
Yifan Hong10fe0b52016-10-19 14:20:17 -0700476 out.indent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100477 method->javaImpl(IMPL_HEADER, out);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700478 out.unindent();
479 out << "\n}\n\n";
480 }
481
Yifan Hong084d11f2016-12-21 15:33:43 -0800482 out << "@Override\n"
483 << "public android.os.IHwInterface queryLocalInterface(String descriptor) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700484 out.indent();
485 // XXX what about potential superClasses?
486 out << "if (kInterfaceName.equals(descriptor)) {\n";
487 out.indent();
488 out << "return this;\n";
489 out.unindent();
490 out << "}\n";
491 out << "return null;\n";
492 out.unindent();
493 out << "}\n\n";
494
Steven Moreland64af5e82017-01-04 10:58:55 -0800495 out << "public void registerAsService(String serviceName) throws RemoteException {\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700496 out.indent();
497
Steven Moreland7e367bf2016-11-04 11:31:41 -0700498 out << "registerService(interfaceChain(), serviceName);\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700499
500 out.unindent();
501 out << "}\n\n";
502
Yifan Honge45b5302017-02-22 10:49:07 -0800503 out << "@Override\npublic String toString() ";
504 out.block([&] {
505 out << "return this.interfaceDescriptor() + \"@Stub\";\n";
506 }).endl().endl();
507
Yifan Hong084d11f2016-12-21 15:33:43 -0800508 out << "@Override\n"
509 << "public void onTransact("
Steven Moreland4b39bc12016-11-16 10:42:24 -0800510 << "int _hidl_code, "
511 << "android.os.HwParcel _hidl_request, "
512 << "final android.os.HwParcel _hidl_reply, "
Steven Morelanddad1b302016-12-20 15:56:00 -0800513 << "int _hidl_flags)\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700514 out.indent();
Steven Morelanddad1b302016-12-20 15:56:00 -0800515 out.indent();
516 out << "throws RemoteException {\n";
517 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700518
Steven Moreland4b39bc12016-11-16 10:42:24 -0800519 out << "switch (_hidl_code) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700520
521 out.indent();
522
Yifan Hong10fe0b52016-10-19 14:20:17 -0700523 for (const auto &tuple : iface->allMethodsFromRoot()) {
524 const Method *method = tuple.method();
Andreas Huber37065d62017-02-07 14:36:54 -0800525
Yifan Hong10fe0b52016-10-19 14:20:17 -0700526 const Interface *superInterface = tuple.interface();
527 const bool returnsValue = !method->results().empty();
528 const bool needsCallback = method->results().size() > 1;
Andreas Huber2831d512016-08-15 09:33:47 -0700529
Yifan Hong10fe0b52016-10-19 14:20:17 -0700530 out << "case "
531 << method->getSerialId()
532 << " /* "
533 << method->name()
534 << " */:\n{\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700535
Yifan Hong10fe0b52016-10-19 14:20:17 -0700536 out.indent();
Andreas Huber37065d62017-02-07 14:36:54 -0800537
Martijn Coenen115d4282016-12-19 05:14:04 +0100538 if (method->isHidlReserved() && method->overridesJavaImpl(IMPL_STUB)) {
539 method->javaImpl(IMPL_STUB, out);
540 out.unindent();
541 out << "break;\n";
542 out << "}\n\n";
543 continue;
544 }
Andreas Huber2831d512016-08-15 09:33:47 -0700545
Steven Moreland4b39bc12016-11-16 10:42:24 -0800546 out << "_hidl_request.enforceInterface("
Yifan Hong10fe0b52016-10-19 14:20:17 -0700547 << superInterface->fullJavaName()
548 << ".kInterfaceName);\n\n";
549
Andreas Huber37065d62017-02-07 14:36:54 -0800550 if (method->isHiddenFromJava()) {
551 // This is a method hidden from the Java side of things, it must not
552 // return any value and will simply signal success.
553 CHECK(!returnsValue);
554
555 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
556 out << "_hidl_reply.send();\n";
557 out << "break;\n";
558 out.unindent();
559 out << "}\n\n";
560 continue;
561 }
562
Yifan Hong10fe0b52016-10-19 14:20:17 -0700563 for (const auto &arg : method->args()) {
564 emitJavaReaderWriter(
565 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800566 "_hidl_request",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700567 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800568 true /* isReader */,
569 false /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700570 }
571
572 if (!needsCallback && returnsValue) {
573 const TypedVar *returnArg = method->results()[0];
Yifan Hong10fe0b52016-10-19 14:20:17 -0700574
Yifan Hong4ed13472016-11-02 10:44:11 -0700575 out << returnArg->type().getJavaType()
Yifan Honga47eef32016-12-12 10:38:54 -0800576 << " _hidl_out_"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700577 << returnArg->name()
578 << " = ";
579 }
580
581 out << method->name()
582 << "(";
583
584 bool firstField = true;
585 for (const auto &arg : method->args()) {
586 if (!firstField) {
587 out << ", ";
588 }
589
590 out << arg->name();
591
592 firstField = false;
593 }
594
595 if (needsCallback) {
596 if (!firstField) {
597 out << ", ";
598 }
599
600 out << "new " << method->name() << "Callback() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700601 out.indent();
602
Yifan Hong10fe0b52016-10-19 14:20:17 -0700603 out << "@Override\n"
604 << "public void onValues("
605 << Method::GetJavaArgSignature(method->results())
606 << ") {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700607
Yifan Hong10fe0b52016-10-19 14:20:17 -0700608 out.indent();
Steven Moreland4b39bc12016-11-16 10:42:24 -0800609 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700610
611 for (const auto &arg : method->results()) {
Andreas Huber2831d512016-08-15 09:33:47 -0700612 emitJavaReaderWriter(
613 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800614 "_hidl_reply",
Andreas Huber2831d512016-08-15 09:33:47 -0700615 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800616 false /* isReader */,
617 false /* addPrefixToName */);
618 // no need to add _hidl_out because out vars are are scoped
Andreas Huber2831d512016-08-15 09:33:47 -0700619 }
620
Steven Moreland4b39bc12016-11-16 10:42:24 -0800621 out << "_hidl_reply.send();\n"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700622 << "}}";
Andreas Huber2831d512016-08-15 09:33:47 -0700623
Andreas Huber2831d512016-08-15 09:33:47 -0700624 out.unindent();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700625 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700626 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700627
628 out << ");\n";
629
Martijn Coenen0bb0d412017-02-08 10:21:30 +0100630 if (!needsCallback && !method->isOneway()) {
Steven Moreland4b39bc12016-11-16 10:42:24 -0800631 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700632
633 if (returnsValue) {
634 const TypedVar *returnArg = method->results()[0];
635
636 emitJavaReaderWriter(
637 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800638 "_hidl_reply",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700639 returnArg,
Yifan Honga47eef32016-12-12 10:38:54 -0800640 false /* isReader */,
641 true /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700642 }
643
Steven Moreland4b39bc12016-11-16 10:42:24 -0800644 out << "_hidl_reply.send();\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700645 }
646
647 out << "break;\n";
648 out.unindent();
649 out << "}\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700650 }
651
652 out.unindent();
653 out << "}\n";
654
655 out.unindent();
656 out << "}\n";
657
658 out.unindent();
659 out << "}\n";
660
661 out.unindent();
662 out << "}\n";
663
664 return OK;
665}
666
667status_t AST::emitJavaTypeDeclarations(Formatter &out) const {
Andreas Huber85eabdb2016-08-25 11:24:49 -0700668 return mRootScope->emitJavaTypeDeclarations(out, false /* atTopLevel */);
Andreas Huber2831d512016-08-15 09:33:47 -0700669}
670
671} // namespace android