blob: 1fe0634b2cef59b9e510deda927a0378fcd0912b [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
Steven Moreland368e4602018-02-16 14:21:49 -080046void AST::generateJavaTypes(Formatter& out, const std::string& limitToType) const {
Andreas Huber85eabdb2016-08-25 11:24:49 -070047 // Splits types.hal up into one java file per declared type.
Steven Moreland5abcf012018-02-08 18:50:18 -080048 CHECK(!limitToType.empty()) << getFilename();
Andreas Huber85eabdb2016-08-25 11:24:49 -070049
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
Steven Moreland5abcf012018-02-08 18:50:18 -080053 if (type->isTypeDef()) continue;
54 if (typeName != limitToType) continue;
Andreas Huber85eabdb2016-08-25 11:24:49 -070055
Andreas Huber85eabdb2016-08-25 11:24:49 -070056 std::vector<std::string> packageComponents;
57 getPackageAndVersionComponents(
58 &packageComponents, true /* cpp_compatible */);
59
Steven Moreland5abcf012018-02-08 18:50:18 -080060 out << "package " << mPackage.javaPackage() << ";\n\n\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -070061
Steven Moreland368e4602018-02-16 14:21:49 -080062 type->emitJavaTypeDeclarations(out, true /* atTopLevel */);
63 return;
Andreas Huber85eabdb2016-08-25 11:24:49 -070064 }
65
Steven Moreland5abcf012018-02-08 18:50:18 -080066 CHECK(false) << "generateJavaTypes could not find limitToType type";
Andreas Huber85eabdb2016-08-25 11:24:49 -070067}
68
Steven Moreland9bf5a092017-10-25 04:50:54 +000069void emitGetService(
70 Formatter& out,
71 const std::string& ifaceName,
72 const std::string& fqName,
73 bool isRetry) {
Steven Moreland7645fbd2019-03-12 18:49:28 -070074 if (isRetry) {
75 DocComment(
76 "This will invoke the equivalent of the C++ getService(std::string) if retry is\n"
77 "true or tryGetService(std::string) if retry is false. If the service is\n"
78 "available on the device and retry is true, this will wait for the service to\n"
79 "start. Otherwise, it will return immediately even if the service is null.")
80 .emit(out);
81 } else {
82 DocComment(
83 "Warning: this will not wait for the interface to come up if it hasn't yet\n"
84 "started. See getService(String,boolean) instead.")
85 .emit(out);
86 }
Steven Moreland9bf5a092017-10-25 04:50:54 +000087 out << "public static "
88 << ifaceName
89 << " getService(String serviceName";
90 if (isRetry) {
91 out << ", boolean retry";
92 }
93 out << ") throws android.os.RemoteException ";
94 out.block([&] {
95 out << "return "
96 << ifaceName
97 << ".asInterface(android.os.HwBinder.getService(\""
98 << fqName
99 << "\", serviceName";
100 if (isRetry) {
101 out << ", retry";
102 }
103 out << "));\n";
104 }).endl().endl();
105
Steven Moreland7645fbd2019-03-12 18:49:28 -0700106 if (isRetry) {
107 DocComment("Calls getService(\"default\",retry).").emit(out);
108 } else {
109 DocComment(
110 "Warning: this will not wait for the interface to come up if it hasn't yet "
111 "started. See getService(String,boolean) instead.")
112 .emit(out);
113 }
Steven Moreland9bf5a092017-10-25 04:50:54 +0000114 out << "public static "
115 << ifaceName
116 << " getService(";
117 if (isRetry) {
118 out << "boolean retry";
119 }
120 out << ") throws android.os.RemoteException ";
121 out.block([&] {
122 out << "return getService(\"default\"";
123 if (isRetry) {
124 out << ", retry";
125 }
126 out <<");\n";
127 }).endl().endl();
128}
129
Steven Moreland368e4602018-02-16 14:21:49 -0800130void AST::generateJava(Formatter& out, const std::string& limitToType) const {
131 CHECK(isJavaCompatible()) << getFilename();
Andreas Huber2831d512016-08-15 09:33:47 -0700132
Steven Moreland19f11b52017-05-12 18:22:21 -0700133 if (!AST::isInterface()) {
Steven Moreland368e4602018-02-16 14:21:49 -0800134 generateJavaTypes(out, limitToType);
135 return;
Andreas Huber0fa9e392016-08-31 09:05:44 -0700136 }
137
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700138 const Interface* iface = mRootScope.getInterface();
Steven Moreland5abcf012018-02-08 18:50:18 -0800139 const std::string ifaceName = iface->localName();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700140 const std::string baseName = iface->getBaseName();
Andreas Huber2831d512016-08-15 09:33:47 -0700141
Andreas Huber2831d512016-08-15 09:33:47 -0700142 out << "package " << mPackage.javaPackage() << ";\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
Steven Moreland70cb55e2019-03-12 17:20:54 -0700148 iface->emitDocComment(out);
149
Andreas Huber2831d512016-08-15 09:33:47 -0700150 out << "public interface " << ifaceName << " extends ";
151
Yi Kong56758da2018-07-24 16:21:37 -0700152 if (superType != nullptr) {
Andreas Huber2831d512016-08-15 09:33:47 -0700153 out << superType->fullJavaName();
154 } else {
Yifan Hong1af73532016-11-09 14:32:58 -0800155 out << "android.os.IHwInterface";
Andreas Huber2831d512016-08-15 09:33:47 -0700156 }
157
158 out << " {\n";
159 out.indent();
160
Steven Moreland7645fbd2019-03-12 18:49:28 -0700161 DocComment("Fully-qualified interface name for this interface.").emit(out);
Andreas Huber2831d512016-08-15 09:33:47 -0700162 out << "public static final String kInterfaceName = \""
163 << mPackage.string()
164 << "::"
165 << ifaceName
166 << "\";\n\n";
167
Steven Moreland7645fbd2019-03-12 18:49:28 -0700168 DocComment("Does a checked conversion from a binder to this class.").emit(out);
Andreas Hubera2abe982017-04-04 14:42:09 -0700169 out << "/* package private */ static "
Andreas Huber2831d512016-08-15 09:33:47 -0700170 << ifaceName
Yifan Hong1af73532016-11-09 14:32:58 -0800171 << " asInterface(android.os.IHwBinder binder) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700172
173 out.indent();
174
175 out << "if (binder == null) {\n";
176 out.indent();
177 out << "return null;\n";
178 out.unindent();
179 out << "}\n\n";
180
Yifan Hong1af73532016-11-09 14:32:58 -0800181 out << "android.os.IHwInterface iface =\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700182 out.indent();
183 out.indent();
184 out << "binder.queryLocalInterface(kInterfaceName);\n\n";
185 out.unindent();
186 out.unindent();
187
188 out << "if ((iface != null) && (iface instanceof "
189 << ifaceName
190 << ")) {\n";
191
192 out.indent();
193 out << "return (" << ifaceName << ")iface;\n";
194 out.unindent();
195 out << "}\n\n";
196
Andreas Hubera2abe982017-04-04 14:42:09 -0700197 out << ifaceName << " proxy = new " << ifaceName << ".Proxy(binder);\n\n";
198 out << "try {\n";
199 out.indent();
200 out << "for (String descriptor : proxy.interfaceChain()) {\n";
201 out.indent();
202 out << "if (descriptor.equals(kInterfaceName)) {\n";
203 out.indent();
204 out << "return proxy;\n";
205 out.unindent();
206 out << "}\n";
207 out.unindent();
208 out << "}\n";
209 out.unindent();
210 out << "} catch (android.os.RemoteException e) {\n";
211 out.indent();
212 out.unindent();
213 out << "}\n\n";
214
215 out << "return null;\n";
216
217 out.unindent();
218 out << "}\n\n";
219
Steven Moreland7645fbd2019-03-12 18:49:28 -0700220 DocComment("Does a checked conversion from any interface to this class.").emit(out);
Andreas Hubera2abe982017-04-04 14:42:09 -0700221 out << "public static "
222 << ifaceName
223 << " castFrom(android.os.IHwInterface iface) {\n";
224 out.indent();
225
226 out << "return (iface == null) ? null : "
227 << ifaceName
228 << ".asInterface(iface.asBinder());\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700229
230 out.unindent();
231 out << "}\n\n";
232
Yifan Hong084d11f2016-12-21 15:33:43 -0800233 out << "@Override\npublic android.os.IHwBinder asBinder();\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700234
Steven Moreland9bf5a092017-10-25 04:50:54 +0000235 emitGetService(out, ifaceName, iface->fqName().string(), true /* isRetry */);
236 emitGetService(out, ifaceName, iface->fqName().string(), false /* isRetry */);
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800237
Steven Moreland70cb55e2019-03-12 17:20:54 -0700238 iface->emitJavaTypeDeclarations(out, false /* atTopLevel */);
Andreas Huber2831d512016-08-15 09:33:47 -0700239
Andreas Huber2831d512016-08-15 09:33:47 -0700240 for (const auto &method : iface->methods()) {
241 const bool returnsValue = !method->results().empty();
242 const bool needsCallback = method->results().size() > 1;
243
244 if (needsCallback) {
Yifan Hong601cfca2017-05-24 12:20:17 -0700245 out << "\n@java.lang.FunctionalInterface\npublic interface " << method->name()
Andreas Huber2831d512016-08-15 09:33:47 -0700246 << "Callback {\n";
247
248 out.indent();
249
Yifan Hong932464e2017-03-30 15:40:22 -0700250 out << "public void onValues(";
251 method->emitJavaResultSignature(out);
252 out << ");\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700253
254 out.unindent();
255 out << "}\n\n";
256 }
257
Steven Moreland49bad8d2018-05-17 15:45:26 -0700258 method->emitDocComment(out);
259
Andreas Huber2831d512016-08-15 09:33:47 -0700260 if (returnsValue && !needsCallback) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700261 out << method->results()[0]->type().getJavaType();
Andreas Huber2831d512016-08-15 09:33:47 -0700262 } else {
263 out << "void";
264 }
265
266 out << " "
267 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700268 << "(";
269 method->emitJavaArgSignature(out);
Andreas Huber2831d512016-08-15 09:33:47 -0700270
271 if (needsCallback) {
272 if (!method->args().empty()) {
273 out << ", ";
274 }
275
276 out << method->name()
Steven Moreland4ddd8332017-04-27 19:27:18 -0700277 << "Callback _hidl_cb";
Andreas Huber2831d512016-08-15 09:33:47 -0700278 }
279
Steven Morelanddad1b302016-12-20 15:56:00 -0800280 out << ")\n";
281 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700282 out << "throws android.os.RemoteException;\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800283 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700284 }
285
286 out << "\npublic static final class Proxy implements "
287 << ifaceName
288 << " {\n";
289
290 out.indent();
291
Yifan Hong1af73532016-11-09 14:32:58 -0800292 out << "private android.os.IHwBinder mRemote;\n\n";
293 out << "public Proxy(android.os.IHwBinder remote) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700294 out.indent();
Yifan Hong729e7962016-12-21 16:04:27 -0800295 out << "mRemote = java.util.Objects.requireNonNull(remote);\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700296 out.unindent();
297 out << "}\n\n";
298
Yifan Hong084d11f2016-12-21 15:33:43 -0800299 out << "@Override\npublic android.os.IHwBinder asBinder() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700300 out.indent();
301 out << "return mRemote;\n";
302 out.unindent();
303 out << "}\n\n";
304
Yifan Honge45b5302017-02-22 10:49:07 -0800305
306 out << "@Override\npublic String toString() ";
307 out.block([&] {
308 out.sTry([&] {
309 out << "return this.interfaceDescriptor() + \"@Proxy\";\n";
Yifan Hong320a3492017-03-27 10:33:09 -0700310 }).sCatch("android.os.RemoteException ex", [&] {
Yifan Honge45b5302017-02-22 10:49:07 -0800311 out << "/* ignored; handled below. */\n";
312 }).endl();
313 out << "return \"[class or subclass of \" + "
314 << ifaceName << ".kInterfaceName + \"]@Proxy\";\n";
315 }).endl().endl();
316
Yifan Hongf89e1062017-10-31 17:31:08 -0700317 // Equals when internal binder object is equal (even if the interface Proxy object
318 // itself is different). This is similar to interfacesEqual in C++.
319 out << "@Override\npublic final boolean equals(java.lang.Object other) ";
320 out.block([&] {
321 out << "return android.os.HidlSupport.interfacesEqual(this, other);\n";
322 }).endl().endl();
323
324 out << "@Override\npublic final int hashCode() ";
325 out.block([&] {
326 out << "return this.asBinder().hashCode();\n";
327 }).endl().endl();
328
Yifan Hong10fe0b52016-10-19 14:20:17 -0700329 const Interface *prevInterface = nullptr;
330 for (const auto &tuple : iface->allMethodsFromRoot()) {
331 const Method *method = tuple.method();
Andreas Huber37065d62017-02-07 14:36:54 -0800332
Yifan Hong10fe0b52016-10-19 14:20:17 -0700333 const Interface *superInterface = tuple.interface();
334 if (prevInterface != superInterface) {
335 out << "// Methods from "
336 << superInterface->fullName()
337 << " follow.\n";
338 prevInterface = superInterface;
339 }
340 const bool returnsValue = !method->results().empty();
341 const bool needsCallback = method->results().size() > 1;
Andreas Huber2831d512016-08-15 09:33:47 -0700342
Yifan Hong084d11f2016-12-21 15:33:43 -0800343 out << "@Override\npublic ";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700344 if (returnsValue && !needsCallback) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700345 out << method->results()[0]->type().getJavaType();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700346 } else {
347 out << "void";
348 }
Andreas Huber2831d512016-08-15 09:33:47 -0700349
Yifan Hong10fe0b52016-10-19 14:20:17 -0700350 out << " "
351 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700352 << "(";
353 method->emitJavaArgSignature(out);
Andreas Huber2831d512016-08-15 09:33:47 -0700354
Yifan Hong10fe0b52016-10-19 14:20:17 -0700355 if (needsCallback) {
356 if (!method->args().empty()) {
357 out << ", ";
Andreas Huber2831d512016-08-15 09:33:47 -0700358 }
359
Yifan Hong10fe0b52016-10-19 14:20:17 -0700360 out << method->name()
Steven Moreland4ddd8332017-04-27 19:27:18 -0700361 << "Callback _hidl_cb";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700362 }
Andreas Huber2831d512016-08-15 09:33:47 -0700363
Steven Morelanddad1b302016-12-20 15:56:00 -0800364 out << ")\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700365 out.indent();
Steven Morelanddad1b302016-12-20 15:56:00 -0800366 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700367 out << "throws android.os.RemoteException {\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800368 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700369
Martijn Coenen115d4282016-12-19 05:14:04 +0100370 if (method->isHidlReserved() && method->overridesJavaImpl(IMPL_PROXY)) {
371 method->javaImpl(IMPL_PROXY, out);
372 out.unindent();
373 out << "}\n";
374 continue;
375 }
Steven Moreland4b39bc12016-11-16 10:42:24 -0800376 out << "android.os.HwParcel _hidl_request = new android.os.HwParcel();\n";
377 out << "_hidl_request.writeInterfaceToken("
Yifan Hong10fe0b52016-10-19 14:20:17 -0700378 << superInterface->fullJavaName()
379 << ".kInterfaceName);\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700380
Yifan Hong10fe0b52016-10-19 14:20:17 -0700381 for (const auto &arg : method->args()) {
382 emitJavaReaderWriter(
383 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800384 "_hidl_request",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700385 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800386 false /* isReader */,
387 false /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700388 }
Andreas Huber2831d512016-08-15 09:33:47 -0700389
Martijn Coenen4de083b2017-03-16 18:49:43 +0100390 out << "\nandroid.os.HwParcel _hidl_reply = new android.os.HwParcel();\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700391
Martijn Coenen4de083b2017-03-16 18:49:43 +0100392 out.sTry([&] {
393 out << "mRemote.transact("
394 << method->getSerialId()
395 << " /* "
396 << method->name()
397 << " */, _hidl_request, _hidl_reply, ";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700398
Martijn Coenen4de083b2017-03-16 18:49:43 +0100399 if (method->isOneway()) {
Steven Moreland77943692018-08-09 12:53:42 -0700400 out << Interface::FLAG_ONE_WAY->javaValue();
Martijn Coenen4de083b2017-03-16 18:49:43 +0100401 } else {
402 out << "0 /* flags */";
Andreas Huber2831d512016-08-15 09:33:47 -0700403 }
404
Martijn Coenen4de083b2017-03-16 18:49:43 +0100405 out << ");\n";
Andreas Huber8b5da222016-08-18 14:28:18 -0700406
Martijn Coenen4de083b2017-03-16 18:49:43 +0100407 if (!method->isOneway()) {
408 out << "_hidl_reply.verifySuccess();\n";
409 } else {
410 CHECK(!returnsValue);
411 }
412
413 out << "_hidl_request.releaseTemporaryStorage();\n";
414
415 if (returnsValue) {
416 out << "\n";
417
Andreas Huber2831d512016-08-15 09:33:47 -0700418 for (const auto &arg : method->results()) {
Martijn Coenen4de083b2017-03-16 18:49:43 +0100419 emitJavaReaderWriter(
420 out,
421 "_hidl_reply",
422 arg,
423 true /* isReader */,
424 true /* addPrefixToName */);
Andreas Huber2831d512016-08-15 09:33:47 -0700425 }
Andreas Huber2831d512016-08-15 09:33:47 -0700426
Martijn Coenen4de083b2017-03-16 18:49:43 +0100427 if (needsCallback) {
Steven Moreland4ddd8332017-04-27 19:27:18 -0700428 out << "_hidl_cb.onValues(";
Martijn Coenen4de083b2017-03-16 18:49:43 +0100429
430 bool firstField = true;
431 for (const auto &arg : method->results()) {
432 if (!firstField) {
433 out << ", ";
434 }
435
436 out << "_hidl_out_" << arg->name();
437 firstField = false;
438 }
439
440 out << ");\n";
441 } else {
442 const std::string returnName = method->results()[0]->name();
443 out << "return _hidl_out_" << returnName << ";\n";
444 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700445 }
Martijn Coenen4de083b2017-03-16 18:49:43 +0100446 }).sFinally([&] {
447 out << "_hidl_reply.release();\n";
448 }).endl();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700449
450 out.unindent();
451 out << "}\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700452 }
453
454 out.unindent();
455 out << "}\n";
456
457 ////////////////////////////////////////////////////////////////////////////
458
Yifan Hong1af73532016-11-09 14:32:58 -0800459 out << "\npublic static abstract class Stub extends android.os.HwBinder "
Andreas Huber2831d512016-08-15 09:33:47 -0700460 << "implements "
461 << ifaceName << " {\n";
462
463 out.indent();
464
Yifan Hong084d11f2016-12-21 15:33:43 -0800465 out << "@Override\npublic android.os.IHwBinder asBinder() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700466 out.indent();
Yifan Hongf89e1062017-10-31 17:31:08 -0700467 // If we change this behavior in the future and asBinder does not return "this",
468 // equals and hashCode should also be overridden.
Andreas Huber2831d512016-08-15 09:33:47 -0700469 out << "return this;\n";
470 out.unindent();
471 out << "}\n\n";
472
Yifan Hong10fe0b52016-10-19 14:20:17 -0700473 for (Method *method : iface->hidlReservedMethods()) {
Martijn Coenenaf712c02016-11-16 15:26:27 +0100474 // b/32383557 this is a hack. We need to change this if we have more reserved methods.
475 CHECK_LE(method->results().size(), 1u);
476 std::string resultType = method->results().size() == 0 ? "void" :
477 method->results()[0]->type().getJavaType();
Steven Moreland327fd8b2018-08-10 15:40:41 -0700478
479 bool canBeOverriden = method->name() == "debug";
480
481 out << "@Override\npublic " << (canBeOverriden ? "" : "final ") << resultType << " "
482 << method->name() << "(";
Yifan Hong932464e2017-03-30 15:40:22 -0700483 method->emitJavaArgSignature(out);
484 out << ") {\n";
Martijn Coenen115d4282016-12-19 05:14:04 +0100485
Yifan Hong10fe0b52016-10-19 14:20:17 -0700486 out.indent();
Steven Moreland937408a2017-03-20 09:54:18 -0700487 method->javaImpl(IMPL_INTERFACE, out);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700488 out.unindent();
489 out << "\n}\n\n";
490 }
491
Yifan Hong084d11f2016-12-21 15:33:43 -0800492 out << "@Override\n"
493 << "public android.os.IHwInterface queryLocalInterface(String descriptor) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700494 out.indent();
495 // XXX what about potential superClasses?
496 out << "if (kInterfaceName.equals(descriptor)) {\n";
497 out.indent();
498 out << "return this;\n";
499 out.unindent();
500 out << "}\n";
501 out << "return null;\n";
502 out.unindent();
503 out << "}\n\n";
504
Yifan Hong320a3492017-03-27 10:33:09 -0700505 out << "public void registerAsService(String serviceName) throws android.os.RemoteException {\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700506 out.indent();
507
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100508 out << "registerService(serviceName);\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700509
510 out.unindent();
511 out << "}\n\n";
512
Yifan Honge45b5302017-02-22 10:49:07 -0800513 out << "@Override\npublic String toString() ";
514 out.block([&] {
515 out << "return this.interfaceDescriptor() + \"@Stub\";\n";
516 }).endl().endl();
517
Yifan Hong084d11f2016-12-21 15:33:43 -0800518 out << "@Override\n"
519 << "public void onTransact("
Steven Moreland4b39bc12016-11-16 10:42:24 -0800520 << "int _hidl_code, "
521 << "android.os.HwParcel _hidl_request, "
522 << "final android.os.HwParcel _hidl_reply, "
Steven Morelanddad1b302016-12-20 15:56:00 -0800523 << "int _hidl_flags)\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700524 out.indent();
Steven Morelanddad1b302016-12-20 15:56:00 -0800525 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700526 out << "throws android.os.RemoteException {\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800527 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700528
Steven Moreland4b39bc12016-11-16 10:42:24 -0800529 out << "switch (_hidl_code) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700530
531 out.indent();
532
Yifan Hong10fe0b52016-10-19 14:20:17 -0700533 for (const auto &tuple : iface->allMethodsFromRoot()) {
534 const Method *method = tuple.method();
Andreas Huber37065d62017-02-07 14:36:54 -0800535
Yifan Hong10fe0b52016-10-19 14:20:17 -0700536 const Interface *superInterface = tuple.interface();
537 const bool returnsValue = !method->results().empty();
538 const bool needsCallback = method->results().size() > 1;
Andreas Huber2831d512016-08-15 09:33:47 -0700539
Yifan Hong10fe0b52016-10-19 14:20:17 -0700540 out << "case "
541 << method->getSerialId()
542 << " /* "
543 << method->name()
544 << " */:\n{\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700545
Yifan Hong10fe0b52016-10-19 14:20:17 -0700546 out.indent();
Andreas Huber37065d62017-02-07 14:36:54 -0800547
Steven Moreland77943692018-08-09 12:53:42 -0700548 out << "boolean _hidl_is_oneway = (_hidl_flags & " << Interface::FLAG_ONE_WAY->javaValue()
549 << ") != 0;\n";
Steven Moreland7dfba102018-03-19 14:37:53 -0700550 out << "if (_hidl_is_oneway != " << (method->isOneway() ? "true" : "false") << ") ";
551 out.block([&] {
552 out << "_hidl_reply.writeStatus(" << UNKNOWN_ERROR << ");\n";
553 out << "_hidl_reply.send();\n";
554 out << "break;\n";
555 });
556
Martijn Coenen115d4282016-12-19 05:14:04 +0100557 if (method->isHidlReserved() && method->overridesJavaImpl(IMPL_STUB)) {
558 method->javaImpl(IMPL_STUB, out);
559 out.unindent();
560 out << "break;\n";
561 out << "}\n\n";
562 continue;
563 }
Andreas Huber2831d512016-08-15 09:33:47 -0700564
Steven Moreland4b39bc12016-11-16 10:42:24 -0800565 out << "_hidl_request.enforceInterface("
Yifan Hong10fe0b52016-10-19 14:20:17 -0700566 << superInterface->fullJavaName()
567 << ".kInterfaceName);\n\n";
568
569 for (const auto &arg : method->args()) {
570 emitJavaReaderWriter(
571 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800572 "_hidl_request",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700573 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800574 true /* isReader */,
575 false /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700576 }
577
578 if (!needsCallback && returnsValue) {
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700579 const NamedReference<Type>* returnArg = method->results()[0];
Yifan Hong10fe0b52016-10-19 14:20:17 -0700580
Yifan Hong4ed13472016-11-02 10:44:11 -0700581 out << returnArg->type().getJavaType()
Yifan Honga47eef32016-12-12 10:38:54 -0800582 << " _hidl_out_"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700583 << returnArg->name()
584 << " = ";
585 }
586
587 out << method->name()
588 << "(";
589
590 bool firstField = true;
591 for (const auto &arg : method->args()) {
592 if (!firstField) {
593 out << ", ";
594 }
595
596 out << arg->name();
597
598 firstField = false;
599 }
600
601 if (needsCallback) {
602 if (!firstField) {
603 out << ", ";
604 }
605
606 out << "new " << method->name() << "Callback() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700607 out.indent();
608
Yifan Hong10fe0b52016-10-19 14:20:17 -0700609 out << "@Override\n"
Yifan Hong932464e2017-03-30 15:40:22 -0700610 << "public void onValues(";
611 method->emitJavaResultSignature(out);
612 out << ") {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700613
Yifan Hong10fe0b52016-10-19 14:20:17 -0700614 out.indent();
Steven Moreland4b39bc12016-11-16 10:42:24 -0800615 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700616
617 for (const auto &arg : method->results()) {
Andreas Huber2831d512016-08-15 09:33:47 -0700618 emitJavaReaderWriter(
619 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800620 "_hidl_reply",
Andreas Huber2831d512016-08-15 09:33:47 -0700621 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800622 false /* isReader */,
623 false /* addPrefixToName */);
624 // no need to add _hidl_out because out vars are are scoped
Andreas Huber2831d512016-08-15 09:33:47 -0700625 }
626
Steven Moreland4b39bc12016-11-16 10:42:24 -0800627 out << "_hidl_reply.send();\n"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700628 << "}}";
Andreas Huber2831d512016-08-15 09:33:47 -0700629
Andreas Huber2831d512016-08-15 09:33:47 -0700630 out.unindent();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700631 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700632 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700633
634 out << ");\n";
635
Martijn Coenen0bb0d412017-02-08 10:21:30 +0100636 if (!needsCallback && !method->isOneway()) {
Steven Moreland4b39bc12016-11-16 10:42:24 -0800637 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700638
639 if (returnsValue) {
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700640 const NamedReference<Type>* returnArg = method->results()[0];
Yifan Hong10fe0b52016-10-19 14:20:17 -0700641
642 emitJavaReaderWriter(
643 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800644 "_hidl_reply",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700645 returnArg,
Yifan Honga47eef32016-12-12 10:38:54 -0800646 false /* isReader */,
647 true /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700648 }
649
Steven Moreland4b39bc12016-11-16 10:42:24 -0800650 out << "_hidl_reply.send();\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700651 }
652
653 out << "break;\n";
654 out.unindent();
655 out << "}\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700656 }
657
658 out.unindent();
659 out << "}\n";
660
661 out.unindent();
662 out << "}\n";
663
664 out.unindent();
665 out << "}\n";
666
667 out.unindent();
668 out << "}\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700669}
670
Andreas Huber2831d512016-08-15 09:33:47 -0700671} // namespace android