blob: 7b2d23cb866cef2afd850ae0bfa5981189f149bd [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
Steven Morelanda885d252017-09-25 18:44:43 -070061 Formatter out = mCoordinator->getFormatter(
62 outputPath, mPackage, Coordinator::Location::GEN_SANITIZED, typeName + ".java");
Andreas Huber85eabdb2016-08-25 11:24:49 -070063
Steven Morelanda885d252017-09-25 18:44:43 -070064 if (!out.isValid()) {
65 return UNKNOWN_ERROR;
Andreas Huber85eabdb2016-08-25 11:24:49 -070066 }
67
Andreas Huber85eabdb2016-08-25 11:24:49 -070068 std::vector<std::string> packageComponents;
69 getPackageAndVersionComponents(
70 &packageComponents, true /* cpp_compatible */);
71
72 out << "package " << mPackage.javaPackage() << ";\n\n";
73
Iliyan Malchev800273d2016-09-02 15:25:07 -070074 out << "\n";
75
Andreas Huber85eabdb2016-08-25 11:24:49 -070076 status_t err =
77 type->emitJavaTypeDeclarations(out, true /* atTopLevel */);
78
79 if (err != OK) {
80 return err;
81 }
82 }
83
84 return OK;
85}
86
Steven Moreland9bf5a092017-10-25 04:50:54 +000087void emitGetService(
88 Formatter& out,
89 const std::string& ifaceName,
90 const std::string& fqName,
91 bool isRetry) {
92 out << "public static "
93 << ifaceName
94 << " getService(String serviceName";
95 if (isRetry) {
96 out << ", boolean retry";
97 }
98 out << ") throws android.os.RemoteException ";
99 out.block([&] {
100 out << "return "
101 << ifaceName
102 << ".asInterface(android.os.HwBinder.getService(\""
103 << fqName
104 << "\", serviceName";
105 if (isRetry) {
106 out << ", retry";
107 }
108 out << "));\n";
109 }).endl().endl();
110
111 out << "public static "
112 << ifaceName
113 << " getService(";
114 if (isRetry) {
115 out << "boolean retry";
116 }
117 out << ") throws android.os.RemoteException ";
118 out.block([&] {
119 out << "return getService(\"default\"";
120 if (isRetry) {
121 out << ", retry";
122 }
123 out <<");\n";
124 }).endl().endl();
125}
126
Andreas Huber0fa9e392016-08-31 09:05:44 -0700127status_t AST::generateJava(
Andreas Huberd29724f2016-09-14 09:33:13 -0700128 const std::string &outputPath, const std::string &limitToType) const {
Andreas Huber0fa9e392016-08-31 09:05:44 -0700129 if (!isJavaCompatible()) {
Andreas Huber70a59e12016-08-16 12:57:01 -0700130 fprintf(stderr,
131 "ERROR: This interface is not Java compatible. The Java backend"
Andreas Huberf03332a2016-09-22 15:35:43 -0700132 " does NOT support union types nor native handles. "
133 "In addition, vectors of arrays are limited to at most "
Andreas Huber86a112b2016-10-19 14:25:16 -0700134 "one-dimensional arrays and vectors of {vectors,interfaces} are"
135 " not supported.\n");
Andreas Huber70a59e12016-08-16 12:57:01 -0700136
Andreas Huber2831d512016-08-15 09:33:47 -0700137 return UNKNOWN_ERROR;
138 }
139
Steven Moreland19f11b52017-05-12 18:22:21 -0700140 if (!AST::isInterface()) {
Andreas Huber0fa9e392016-08-31 09:05:44 -0700141 return generateJavaTypes(outputPath, limitToType);
142 }
143
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700144 const Interface* iface = mRootScope.getInterface();
Steven Moreland19f11b52017-05-12 18:22:21 -0700145 std::string ifaceName = iface->localName();
Andreas Huber0fa9e392016-08-31 09:05:44 -0700146
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700147 const std::string baseName = iface->getBaseName();
Andreas Huber2831d512016-08-15 09:33:47 -0700148
Steven Morelanda885d252017-09-25 18:44:43 -0700149 Formatter out = mCoordinator->getFormatter(
150 outputPath, mPackage, Coordinator::Location::GEN_SANITIZED, ifaceName + ".java");
Andreas Huber2831d512016-08-15 09:33:47 -0700151
Steven Morelanda885d252017-09-25 18:44:43 -0700152 if (!out.isValid()) {
153 return UNKNOWN_ERROR;
Andreas Huber2831d512016-08-15 09:33:47 -0700154 }
155
Andreas Huber2831d512016-08-15 09:33:47 -0700156 std::vector<std::string> packageComponents;
157 getPackageAndVersionComponents(
158 &packageComponents, true /* cpp_compatible */);
159
160 out << "package " << mPackage.javaPackage() << ";\n\n";
161
Andreas Huber2831d512016-08-15 09:33:47 -0700162 out.setNamespace(mPackage.javaPackage() + ".");
163
Andreas Huber2831d512016-08-15 09:33:47 -0700164 const Interface *superType = iface->superType();
165
166 out << "public interface " << ifaceName << " extends ";
167
168 if (superType != NULL) {
169 out << superType->fullJavaName();
170 } else {
Yifan Hong1af73532016-11-09 14:32:58 -0800171 out << "android.os.IHwInterface";
Andreas Huber2831d512016-08-15 09:33:47 -0700172 }
173
174 out << " {\n";
175 out.indent();
176
177 out << "public static final String kInterfaceName = \""
178 << mPackage.string()
179 << "::"
180 << ifaceName
181 << "\";\n\n";
182
Andreas Hubera2abe982017-04-04 14:42:09 -0700183 out << "/* package private */ static "
Andreas Huber2831d512016-08-15 09:33:47 -0700184 << ifaceName
Yifan Hong1af73532016-11-09 14:32:58 -0800185 << " asInterface(android.os.IHwBinder binder) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700186
187 out.indent();
188
189 out << "if (binder == null) {\n";
190 out.indent();
191 out << "return null;\n";
192 out.unindent();
193 out << "}\n\n";
194
Yifan Hong1af73532016-11-09 14:32:58 -0800195 out << "android.os.IHwInterface iface =\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700196 out.indent();
197 out.indent();
198 out << "binder.queryLocalInterface(kInterfaceName);\n\n";
199 out.unindent();
200 out.unindent();
201
202 out << "if ((iface != null) && (iface instanceof "
203 << ifaceName
204 << ")) {\n";
205
206 out.indent();
207 out << "return (" << ifaceName << ")iface;\n";
208 out.unindent();
209 out << "}\n\n";
210
Andreas Hubera2abe982017-04-04 14:42:09 -0700211 out << ifaceName << " proxy = new " << ifaceName << ".Proxy(binder);\n\n";
212 out << "try {\n";
213 out.indent();
214 out << "for (String descriptor : proxy.interfaceChain()) {\n";
215 out.indent();
216 out << "if (descriptor.equals(kInterfaceName)) {\n";
217 out.indent();
218 out << "return proxy;\n";
219 out.unindent();
220 out << "}\n";
221 out.unindent();
222 out << "}\n";
223 out.unindent();
224 out << "} catch (android.os.RemoteException e) {\n";
225 out.indent();
226 out.unindent();
227 out << "}\n\n";
228
229 out << "return null;\n";
230
231 out.unindent();
232 out << "}\n\n";
233
234 out << "public static "
235 << ifaceName
236 << " castFrom(android.os.IHwInterface iface) {\n";
237 out.indent();
238
239 out << "return (iface == null) ? null : "
240 << ifaceName
241 << ".asInterface(iface.asBinder());\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700242
243 out.unindent();
244 out << "}\n\n";
245
Yifan Hong084d11f2016-12-21 15:33:43 -0800246 out << "@Override\npublic android.os.IHwBinder asBinder();\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700247
Steven Moreland9bf5a092017-10-25 04:50:54 +0000248 emitGetService(out, ifaceName, iface->fqName().string(), true /* isRetry */);
249 emitGetService(out, ifaceName, iface->fqName().string(), false /* isRetry */);
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800250
Andreas Huber2831d512016-08-15 09:33:47 -0700251 status_t err = emitJavaTypeDeclarations(out);
252
253 if (err != OK) {
254 return err;
255 }
256
Andreas Huber2831d512016-08-15 09:33:47 -0700257 for (const auto &method : iface->methods()) {
Andreas Huber37065d62017-02-07 14:36:54 -0800258 if (method->isHiddenFromJava()) {
259 continue;
260 }
261
Andreas Huber2831d512016-08-15 09:33:47 -0700262 const bool returnsValue = !method->results().empty();
263 const bool needsCallback = method->results().size() > 1;
264
265 if (needsCallback) {
Yifan Hong601cfca2017-05-24 12:20:17 -0700266 out << "\n@java.lang.FunctionalInterface\npublic interface " << method->name()
Andreas Huber2831d512016-08-15 09:33:47 -0700267 << "Callback {\n";
268
269 out.indent();
270
Yifan Hong932464e2017-03-30 15:40:22 -0700271 out << "public void onValues(";
272 method->emitJavaResultSignature(out);
273 out << ");\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700274
275 out.unindent();
276 out << "}\n\n";
277 }
278
279 if (returnsValue && !needsCallback) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700280 out << method->results()[0]->type().getJavaType();
Andreas Huber2831d512016-08-15 09:33:47 -0700281 } else {
282 out << "void";
283 }
284
285 out << " "
286 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700287 << "(";
288 method->emitJavaArgSignature(out);
Andreas Huber2831d512016-08-15 09:33:47 -0700289
290 if (needsCallback) {
291 if (!method->args().empty()) {
292 out << ", ";
293 }
294
295 out << method->name()
Steven Moreland4ddd8332017-04-27 19:27:18 -0700296 << "Callback _hidl_cb";
Andreas Huber2831d512016-08-15 09:33:47 -0700297 }
298
Steven Morelanddad1b302016-12-20 15:56:00 -0800299 out << ")\n";
300 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700301 out << "throws android.os.RemoteException;\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800302 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700303 }
304
305 out << "\npublic static final class Proxy implements "
306 << ifaceName
307 << " {\n";
308
309 out.indent();
310
Yifan Hong1af73532016-11-09 14:32:58 -0800311 out << "private android.os.IHwBinder mRemote;\n\n";
312 out << "public Proxy(android.os.IHwBinder remote) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700313 out.indent();
Yifan Hong729e7962016-12-21 16:04:27 -0800314 out << "mRemote = java.util.Objects.requireNonNull(remote);\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700315 out.unindent();
316 out << "}\n\n";
317
Yifan Hong084d11f2016-12-21 15:33:43 -0800318 out << "@Override\npublic android.os.IHwBinder asBinder() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700319 out.indent();
320 out << "return mRemote;\n";
321 out.unindent();
322 out << "}\n\n";
323
Yifan Honge45b5302017-02-22 10:49:07 -0800324
325 out << "@Override\npublic String toString() ";
326 out.block([&] {
327 out.sTry([&] {
328 out << "return this.interfaceDescriptor() + \"@Proxy\";\n";
Yifan Hong320a3492017-03-27 10:33:09 -0700329 }).sCatch("android.os.RemoteException ex", [&] {
Yifan Honge45b5302017-02-22 10:49:07 -0800330 out << "/* ignored; handled below. */\n";
331 }).endl();
332 out << "return \"[class or subclass of \" + "
333 << ifaceName << ".kInterfaceName + \"]@Proxy\";\n";
334 }).endl().endl();
335
Yifan Hongf89e1062017-10-31 17:31:08 -0700336 // Equals when internal binder object is equal (even if the interface Proxy object
337 // itself is different). This is similar to interfacesEqual in C++.
338 out << "@Override\npublic final boolean equals(java.lang.Object other) ";
339 out.block([&] {
340 out << "return android.os.HidlSupport.interfacesEqual(this, other);\n";
341 }).endl().endl();
342
343 out << "@Override\npublic final int hashCode() ";
344 out.block([&] {
345 out << "return this.asBinder().hashCode();\n";
346 }).endl().endl();
347
Yifan Hong10fe0b52016-10-19 14:20:17 -0700348 const Interface *prevInterface = nullptr;
349 for (const auto &tuple : iface->allMethodsFromRoot()) {
350 const Method *method = tuple.method();
Andreas Huber37065d62017-02-07 14:36:54 -0800351
352 if (method->isHiddenFromJava()) {
353 continue;
354 }
355
Yifan Hong10fe0b52016-10-19 14:20:17 -0700356 const Interface *superInterface = tuple.interface();
357 if (prevInterface != superInterface) {
358 out << "// Methods from "
359 << superInterface->fullName()
360 << " follow.\n";
361 prevInterface = superInterface;
362 }
363 const bool returnsValue = !method->results().empty();
364 const bool needsCallback = method->results().size() > 1;
Andreas Huber2831d512016-08-15 09:33:47 -0700365
Yifan Hong084d11f2016-12-21 15:33:43 -0800366 out << "@Override\npublic ";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700367 if (returnsValue && !needsCallback) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700368 out << method->results()[0]->type().getJavaType();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700369 } else {
370 out << "void";
371 }
Andreas Huber2831d512016-08-15 09:33:47 -0700372
Yifan Hong10fe0b52016-10-19 14:20:17 -0700373 out << " "
374 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700375 << "(";
376 method->emitJavaArgSignature(out);
Andreas Huber2831d512016-08-15 09:33:47 -0700377
Yifan Hong10fe0b52016-10-19 14:20:17 -0700378 if (needsCallback) {
379 if (!method->args().empty()) {
380 out << ", ";
Andreas Huber2831d512016-08-15 09:33:47 -0700381 }
382
Yifan Hong10fe0b52016-10-19 14:20:17 -0700383 out << method->name()
Steven Moreland4ddd8332017-04-27 19:27:18 -0700384 << "Callback _hidl_cb";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700385 }
Andreas Huber2831d512016-08-15 09:33:47 -0700386
Steven Morelanddad1b302016-12-20 15:56:00 -0800387 out << ")\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700388 out.indent();
Steven Morelanddad1b302016-12-20 15:56:00 -0800389 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700390 out << "throws android.os.RemoteException {\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800391 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700392
Martijn Coenen115d4282016-12-19 05:14:04 +0100393 if (method->isHidlReserved() && method->overridesJavaImpl(IMPL_PROXY)) {
394 method->javaImpl(IMPL_PROXY, out);
395 out.unindent();
396 out << "}\n";
397 continue;
398 }
Steven Moreland4b39bc12016-11-16 10:42:24 -0800399 out << "android.os.HwParcel _hidl_request = new android.os.HwParcel();\n";
400 out << "_hidl_request.writeInterfaceToken("
Yifan Hong10fe0b52016-10-19 14:20:17 -0700401 << superInterface->fullJavaName()
402 << ".kInterfaceName);\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700403
Yifan Hong10fe0b52016-10-19 14:20:17 -0700404 for (const auto &arg : method->args()) {
405 emitJavaReaderWriter(
406 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800407 "_hidl_request",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700408 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800409 false /* isReader */,
410 false /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700411 }
Andreas Huber2831d512016-08-15 09:33:47 -0700412
Martijn Coenen4de083b2017-03-16 18:49:43 +0100413 out << "\nandroid.os.HwParcel _hidl_reply = new android.os.HwParcel();\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700414
Martijn Coenen4de083b2017-03-16 18:49:43 +0100415 out.sTry([&] {
416 out << "mRemote.transact("
417 << method->getSerialId()
418 << " /* "
419 << method->name()
420 << " */, _hidl_request, _hidl_reply, ";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700421
Martijn Coenen4de083b2017-03-16 18:49:43 +0100422 if (method->isOneway()) {
423 out << "android.os.IHwBinder.FLAG_ONEWAY";
424 } else {
425 out << "0 /* flags */";
Andreas Huber2831d512016-08-15 09:33:47 -0700426 }
427
Martijn Coenen4de083b2017-03-16 18:49:43 +0100428 out << ");\n";
Andreas Huber8b5da222016-08-18 14:28:18 -0700429
Martijn Coenen4de083b2017-03-16 18:49:43 +0100430 if (!method->isOneway()) {
431 out << "_hidl_reply.verifySuccess();\n";
432 } else {
433 CHECK(!returnsValue);
434 }
435
436 out << "_hidl_request.releaseTemporaryStorage();\n";
437
438 if (returnsValue) {
439 out << "\n";
440
Andreas Huber2831d512016-08-15 09:33:47 -0700441 for (const auto &arg : method->results()) {
Martijn Coenen4de083b2017-03-16 18:49:43 +0100442 emitJavaReaderWriter(
443 out,
444 "_hidl_reply",
445 arg,
446 true /* isReader */,
447 true /* addPrefixToName */);
Andreas Huber2831d512016-08-15 09:33:47 -0700448 }
Andreas Huber2831d512016-08-15 09:33:47 -0700449
Martijn Coenen4de083b2017-03-16 18:49:43 +0100450 if (needsCallback) {
Steven Moreland4ddd8332017-04-27 19:27:18 -0700451 out << "_hidl_cb.onValues(";
Martijn Coenen4de083b2017-03-16 18:49:43 +0100452
453 bool firstField = true;
454 for (const auto &arg : method->results()) {
455 if (!firstField) {
456 out << ", ";
457 }
458
459 out << "_hidl_out_" << arg->name();
460 firstField = false;
461 }
462
463 out << ");\n";
464 } else {
465 const std::string returnName = method->results()[0]->name();
466 out << "return _hidl_out_" << returnName << ";\n";
467 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700468 }
Martijn Coenen4de083b2017-03-16 18:49:43 +0100469 }).sFinally([&] {
470 out << "_hidl_reply.release();\n";
471 }).endl();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700472
473 out.unindent();
474 out << "}\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700475 }
476
477 out.unindent();
478 out << "}\n";
479
480 ////////////////////////////////////////////////////////////////////////////
481
Yifan Hong1af73532016-11-09 14:32:58 -0800482 out << "\npublic static abstract class Stub extends android.os.HwBinder "
Andreas Huber2831d512016-08-15 09:33:47 -0700483 << "implements "
484 << ifaceName << " {\n";
485
486 out.indent();
487
Yifan Hong084d11f2016-12-21 15:33:43 -0800488 out << "@Override\npublic android.os.IHwBinder asBinder() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700489 out.indent();
Yifan Hongf89e1062017-10-31 17:31:08 -0700490 // If we change this behavior in the future and asBinder does not return "this",
491 // equals and hashCode should also be overridden.
Andreas Huber2831d512016-08-15 09:33:47 -0700492 out << "return this;\n";
493 out.unindent();
494 out << "}\n\n";
495
Yifan Hong10fe0b52016-10-19 14:20:17 -0700496 for (Method *method : iface->hidlReservedMethods()) {
Andreas Huber37065d62017-02-07 14:36:54 -0800497 if (method->isHiddenFromJava()) {
498 continue;
499 }
500
Martijn Coenenaf712c02016-11-16 15:26:27 +0100501 // b/32383557 this is a hack. We need to change this if we have more reserved methods.
502 CHECK_LE(method->results().size(), 1u);
503 std::string resultType = method->results().size() == 0 ? "void" :
504 method->results()[0]->type().getJavaType();
Yifan Hong084d11f2016-12-21 15:33:43 -0800505 out << "@Override\npublic final "
Martijn Coenenaf712c02016-11-16 15:26:27 +0100506 << resultType
Yifan Hong10fe0b52016-10-19 14:20:17 -0700507 << " "
508 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700509 << "(";
510 method->emitJavaArgSignature(out);
511 out << ") {\n";
Martijn Coenen115d4282016-12-19 05:14:04 +0100512
Yifan Hong10fe0b52016-10-19 14:20:17 -0700513 out.indent();
Steven Moreland937408a2017-03-20 09:54:18 -0700514 method->javaImpl(IMPL_INTERFACE, out);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700515 out.unindent();
516 out << "\n}\n\n";
517 }
518
Yifan Hong084d11f2016-12-21 15:33:43 -0800519 out << "@Override\n"
520 << "public android.os.IHwInterface queryLocalInterface(String descriptor) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700521 out.indent();
522 // XXX what about potential superClasses?
523 out << "if (kInterfaceName.equals(descriptor)) {\n";
524 out.indent();
525 out << "return this;\n";
526 out.unindent();
527 out << "}\n";
528 out << "return null;\n";
529 out.unindent();
530 out << "}\n\n";
531
Yifan Hong320a3492017-03-27 10:33:09 -0700532 out << "public void registerAsService(String serviceName) throws android.os.RemoteException {\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700533 out.indent();
534
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100535 out << "registerService(serviceName);\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700536
537 out.unindent();
538 out << "}\n\n";
539
Yifan Honge45b5302017-02-22 10:49:07 -0800540 out << "@Override\npublic String toString() ";
541 out.block([&] {
542 out << "return this.interfaceDescriptor() + \"@Stub\";\n";
543 }).endl().endl();
544
Yifan Hong084d11f2016-12-21 15:33:43 -0800545 out << "@Override\n"
546 << "public void onTransact("
Steven Moreland4b39bc12016-11-16 10:42:24 -0800547 << "int _hidl_code, "
548 << "android.os.HwParcel _hidl_request, "
549 << "final android.os.HwParcel _hidl_reply, "
Steven Morelanddad1b302016-12-20 15:56:00 -0800550 << "int _hidl_flags)\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700551 out.indent();
Steven Morelanddad1b302016-12-20 15:56:00 -0800552 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700553 out << "throws android.os.RemoteException {\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800554 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700555
Steven Moreland4b39bc12016-11-16 10:42:24 -0800556 out << "switch (_hidl_code) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700557
558 out.indent();
559
Yifan Hong10fe0b52016-10-19 14:20:17 -0700560 for (const auto &tuple : iface->allMethodsFromRoot()) {
561 const Method *method = tuple.method();
Andreas Huber37065d62017-02-07 14:36:54 -0800562
Yifan Hong10fe0b52016-10-19 14:20:17 -0700563 const Interface *superInterface = tuple.interface();
564 const bool returnsValue = !method->results().empty();
565 const bool needsCallback = method->results().size() > 1;
Andreas Huber2831d512016-08-15 09:33:47 -0700566
Yifan Hong10fe0b52016-10-19 14:20:17 -0700567 out << "case "
568 << method->getSerialId()
569 << " /* "
570 << method->name()
571 << " */:\n{\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700572
Yifan Hong10fe0b52016-10-19 14:20:17 -0700573 out.indent();
Andreas Huber37065d62017-02-07 14:36:54 -0800574
Martijn Coenen115d4282016-12-19 05:14:04 +0100575 if (method->isHidlReserved() && method->overridesJavaImpl(IMPL_STUB)) {
576 method->javaImpl(IMPL_STUB, out);
577 out.unindent();
578 out << "break;\n";
579 out << "}\n\n";
580 continue;
581 }
Andreas Huber2831d512016-08-15 09:33:47 -0700582
Steven Moreland4b39bc12016-11-16 10:42:24 -0800583 out << "_hidl_request.enforceInterface("
Yifan Hong10fe0b52016-10-19 14:20:17 -0700584 << superInterface->fullJavaName()
585 << ".kInterfaceName);\n\n";
586
Andreas Huber37065d62017-02-07 14:36:54 -0800587 if (method->isHiddenFromJava()) {
588 // This is a method hidden from the Java side of things, it must not
589 // return any value and will simply signal success.
590 CHECK(!returnsValue);
591
592 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
593 out << "_hidl_reply.send();\n";
594 out << "break;\n";
595 out.unindent();
596 out << "}\n\n";
597 continue;
598 }
599
Yifan Hong10fe0b52016-10-19 14:20:17 -0700600 for (const auto &arg : method->args()) {
601 emitJavaReaderWriter(
602 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800603 "_hidl_request",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700604 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800605 true /* isReader */,
606 false /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700607 }
608
609 if (!needsCallback && returnsValue) {
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700610 const NamedReference<Type>* returnArg = method->results()[0];
Yifan Hong10fe0b52016-10-19 14:20:17 -0700611
Yifan Hong4ed13472016-11-02 10:44:11 -0700612 out << returnArg->type().getJavaType()
Yifan Honga47eef32016-12-12 10:38:54 -0800613 << " _hidl_out_"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700614 << returnArg->name()
615 << " = ";
616 }
617
618 out << method->name()
619 << "(";
620
621 bool firstField = true;
622 for (const auto &arg : method->args()) {
623 if (!firstField) {
624 out << ", ";
625 }
626
627 out << arg->name();
628
629 firstField = false;
630 }
631
632 if (needsCallback) {
633 if (!firstField) {
634 out << ", ";
635 }
636
637 out << "new " << method->name() << "Callback() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700638 out.indent();
639
Yifan Hong10fe0b52016-10-19 14:20:17 -0700640 out << "@Override\n"
Yifan Hong932464e2017-03-30 15:40:22 -0700641 << "public void onValues(";
642 method->emitJavaResultSignature(out);
643 out << ") {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700644
Yifan Hong10fe0b52016-10-19 14:20:17 -0700645 out.indent();
Steven Moreland4b39bc12016-11-16 10:42:24 -0800646 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700647
648 for (const auto &arg : method->results()) {
Andreas Huber2831d512016-08-15 09:33:47 -0700649 emitJavaReaderWriter(
650 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800651 "_hidl_reply",
Andreas Huber2831d512016-08-15 09:33:47 -0700652 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800653 false /* isReader */,
654 false /* addPrefixToName */);
655 // no need to add _hidl_out because out vars are are scoped
Andreas Huber2831d512016-08-15 09:33:47 -0700656 }
657
Steven Moreland4b39bc12016-11-16 10:42:24 -0800658 out << "_hidl_reply.send();\n"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700659 << "}}";
Andreas Huber2831d512016-08-15 09:33:47 -0700660
Andreas Huber2831d512016-08-15 09:33:47 -0700661 out.unindent();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700662 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700663 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700664
665 out << ");\n";
666
Martijn Coenen0bb0d412017-02-08 10:21:30 +0100667 if (!needsCallback && !method->isOneway()) {
Steven Moreland4b39bc12016-11-16 10:42:24 -0800668 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700669
670 if (returnsValue) {
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700671 const NamedReference<Type>* returnArg = method->results()[0];
Yifan Hong10fe0b52016-10-19 14:20:17 -0700672
673 emitJavaReaderWriter(
674 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800675 "_hidl_reply",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700676 returnArg,
Yifan Honga47eef32016-12-12 10:38:54 -0800677 false /* isReader */,
678 true /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700679 }
680
Steven Moreland4b39bc12016-11-16 10:42:24 -0800681 out << "_hidl_reply.send();\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700682 }
683
684 out << "break;\n";
685 out.unindent();
686 out << "}\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700687 }
688
689 out.unindent();
690 out << "}\n";
691
692 out.unindent();
693 out << "}\n";
694
695 out.unindent();
696 out << "}\n";
697
698 out.unindent();
699 out << "}\n";
700
701 return OK;
702}
703
704status_t AST::emitJavaTypeDeclarations(Formatter &out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700705 return mRootScope.emitJavaTypeDeclarations(out, false /* atTopLevel */);
Andreas Huber2831d512016-08-15 09:33:47 -0700706}
707
708} // namespace android