blob: b746cc3fbec7c4d84c9b3e9bcc4bda774970b049 [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 std::vector<std::string> packageComponents;
143 getPackageAndVersionComponents(
144 &packageComponents, true /* cpp_compatible */);
145
146 out << "package " << mPackage.javaPackage() << ";\n\n";
147
Andreas Huber2831d512016-08-15 09:33:47 -0700148 out.setNamespace(mPackage.javaPackage() + ".");
149
Andreas Huber2831d512016-08-15 09:33:47 -0700150 const Interface *superType = iface->superType();
151
Steven Moreland70cb55e2019-03-12 17:20:54 -0700152 iface->emitDocComment(out);
153
Andreas Huber2831d512016-08-15 09:33:47 -0700154 out << "public interface " << ifaceName << " extends ";
155
Yi Kong56758da2018-07-24 16:21:37 -0700156 if (superType != nullptr) {
Andreas Huber2831d512016-08-15 09:33:47 -0700157 out << superType->fullJavaName();
158 } else {
Yifan Hong1af73532016-11-09 14:32:58 -0800159 out << "android.os.IHwInterface";
Andreas Huber2831d512016-08-15 09:33:47 -0700160 }
161
162 out << " {\n";
163 out.indent();
164
Steven Moreland7645fbd2019-03-12 18:49:28 -0700165 DocComment("Fully-qualified interface name for this interface.").emit(out);
Andreas Huber2831d512016-08-15 09:33:47 -0700166 out << "public static final String kInterfaceName = \""
167 << mPackage.string()
168 << "::"
169 << ifaceName
170 << "\";\n\n";
171
Steven Moreland7645fbd2019-03-12 18:49:28 -0700172 DocComment("Does a checked conversion from a binder to this class.").emit(out);
Andreas Hubera2abe982017-04-04 14:42:09 -0700173 out << "/* package private */ static "
Andreas Huber2831d512016-08-15 09:33:47 -0700174 << ifaceName
Yifan Hong1af73532016-11-09 14:32:58 -0800175 << " asInterface(android.os.IHwBinder binder) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700176
177 out.indent();
178
179 out << "if (binder == null) {\n";
180 out.indent();
181 out << "return null;\n";
182 out.unindent();
183 out << "}\n\n";
184
Yifan Hong1af73532016-11-09 14:32:58 -0800185 out << "android.os.IHwInterface iface =\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700186 out.indent();
187 out.indent();
188 out << "binder.queryLocalInterface(kInterfaceName);\n\n";
189 out.unindent();
190 out.unindent();
191
192 out << "if ((iface != null) && (iface instanceof "
193 << ifaceName
194 << ")) {\n";
195
196 out.indent();
197 out << "return (" << ifaceName << ")iface;\n";
198 out.unindent();
199 out << "}\n\n";
200
Andreas Hubera2abe982017-04-04 14:42:09 -0700201 out << ifaceName << " proxy = new " << ifaceName << ".Proxy(binder);\n\n";
202 out << "try {\n";
203 out.indent();
204 out << "for (String descriptor : proxy.interfaceChain()) {\n";
205 out.indent();
206 out << "if (descriptor.equals(kInterfaceName)) {\n";
207 out.indent();
208 out << "return proxy;\n";
209 out.unindent();
210 out << "}\n";
211 out.unindent();
212 out << "}\n";
213 out.unindent();
214 out << "} catch (android.os.RemoteException e) {\n";
215 out.indent();
216 out.unindent();
217 out << "}\n\n";
218
219 out << "return null;\n";
220
221 out.unindent();
222 out << "}\n\n";
223
Steven Moreland7645fbd2019-03-12 18:49:28 -0700224 DocComment("Does a checked conversion from any interface to this class.").emit(out);
Andreas Hubera2abe982017-04-04 14:42:09 -0700225 out << "public static "
226 << ifaceName
227 << " castFrom(android.os.IHwInterface iface) {\n";
228 out.indent();
229
230 out << "return (iface == null) ? null : "
231 << ifaceName
232 << ".asInterface(iface.asBinder());\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700233
234 out.unindent();
235 out << "}\n\n";
236
Yifan Hong084d11f2016-12-21 15:33:43 -0800237 out << "@Override\npublic android.os.IHwBinder asBinder();\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700238
Steven Moreland9bf5a092017-10-25 04:50:54 +0000239 emitGetService(out, ifaceName, iface->fqName().string(), true /* isRetry */);
240 emitGetService(out, ifaceName, iface->fqName().string(), false /* isRetry */);
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800241
Steven Moreland70cb55e2019-03-12 17:20:54 -0700242 iface->emitJavaTypeDeclarations(out, false /* atTopLevel */);
Andreas Huber2831d512016-08-15 09:33:47 -0700243
Andreas Huber2831d512016-08-15 09:33:47 -0700244 for (const auto &method : iface->methods()) {
245 const bool returnsValue = !method->results().empty();
246 const bool needsCallback = method->results().size() > 1;
247
248 if (needsCallback) {
Yifan Hong601cfca2017-05-24 12:20:17 -0700249 out << "\n@java.lang.FunctionalInterface\npublic interface " << method->name()
Andreas Huber2831d512016-08-15 09:33:47 -0700250 << "Callback {\n";
251
252 out.indent();
253
Yifan Hong932464e2017-03-30 15:40:22 -0700254 out << "public void onValues(";
255 method->emitJavaResultSignature(out);
256 out << ");\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700257
258 out.unindent();
259 out << "}\n\n";
260 }
261
Steven Moreland49bad8d2018-05-17 15:45:26 -0700262 method->emitDocComment(out);
263
Andreas Huber2831d512016-08-15 09:33:47 -0700264 if (returnsValue && !needsCallback) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700265 out << method->results()[0]->type().getJavaType();
Andreas Huber2831d512016-08-15 09:33:47 -0700266 } else {
267 out << "void";
268 }
269
270 out << " "
271 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700272 << "(";
273 method->emitJavaArgSignature(out);
Andreas Huber2831d512016-08-15 09:33:47 -0700274
275 if (needsCallback) {
276 if (!method->args().empty()) {
277 out << ", ";
278 }
279
280 out << method->name()
Steven Moreland4ddd8332017-04-27 19:27:18 -0700281 << "Callback _hidl_cb";
Andreas Huber2831d512016-08-15 09:33:47 -0700282 }
283
Steven Morelanddad1b302016-12-20 15:56:00 -0800284 out << ")\n";
285 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700286 out << "throws android.os.RemoteException;\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800287 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700288 }
289
290 out << "\npublic static final class Proxy implements "
291 << ifaceName
292 << " {\n";
293
294 out.indent();
295
Yifan Hong1af73532016-11-09 14:32:58 -0800296 out << "private android.os.IHwBinder mRemote;\n\n";
297 out << "public Proxy(android.os.IHwBinder remote) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700298 out.indent();
Yifan Hong729e7962016-12-21 16:04:27 -0800299 out << "mRemote = java.util.Objects.requireNonNull(remote);\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700300 out.unindent();
301 out << "}\n\n";
302
Yifan Hong084d11f2016-12-21 15:33:43 -0800303 out << "@Override\npublic android.os.IHwBinder asBinder() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700304 out.indent();
305 out << "return mRemote;\n";
306 out.unindent();
307 out << "}\n\n";
308
Yifan Honge45b5302017-02-22 10:49:07 -0800309
310 out << "@Override\npublic String toString() ";
311 out.block([&] {
312 out.sTry([&] {
313 out << "return this.interfaceDescriptor() + \"@Proxy\";\n";
Yifan Hong320a3492017-03-27 10:33:09 -0700314 }).sCatch("android.os.RemoteException ex", [&] {
Yifan Honge45b5302017-02-22 10:49:07 -0800315 out << "/* ignored; handled below. */\n";
316 }).endl();
317 out << "return \"[class or subclass of \" + "
318 << ifaceName << ".kInterfaceName + \"]@Proxy\";\n";
319 }).endl().endl();
320
Yifan Hongf89e1062017-10-31 17:31:08 -0700321 // Equals when internal binder object is equal (even if the interface Proxy object
322 // itself is different). This is similar to interfacesEqual in C++.
323 out << "@Override\npublic final boolean equals(java.lang.Object other) ";
324 out.block([&] {
325 out << "return android.os.HidlSupport.interfacesEqual(this, other);\n";
326 }).endl().endl();
327
328 out << "@Override\npublic final int hashCode() ";
329 out.block([&] {
330 out << "return this.asBinder().hashCode();\n";
331 }).endl().endl();
332
Yifan Hong10fe0b52016-10-19 14:20:17 -0700333 const Interface *prevInterface = nullptr;
334 for (const auto &tuple : iface->allMethodsFromRoot()) {
335 const Method *method = tuple.method();
Andreas Huber37065d62017-02-07 14:36:54 -0800336
Yifan Hong10fe0b52016-10-19 14:20:17 -0700337 const Interface *superInterface = tuple.interface();
338 if (prevInterface != superInterface) {
339 out << "// Methods from "
340 << superInterface->fullName()
341 << " follow.\n";
342 prevInterface = superInterface;
343 }
344 const bool returnsValue = !method->results().empty();
345 const bool needsCallback = method->results().size() > 1;
Andreas Huber2831d512016-08-15 09:33:47 -0700346
Yifan Hong084d11f2016-12-21 15:33:43 -0800347 out << "@Override\npublic ";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700348 if (returnsValue && !needsCallback) {
Yifan Hong4ed13472016-11-02 10:44:11 -0700349 out << method->results()[0]->type().getJavaType();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700350 } else {
351 out << "void";
352 }
Andreas Huber2831d512016-08-15 09:33:47 -0700353
Yifan Hong10fe0b52016-10-19 14:20:17 -0700354 out << " "
355 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700356 << "(";
357 method->emitJavaArgSignature(out);
Andreas Huber2831d512016-08-15 09:33:47 -0700358
Yifan Hong10fe0b52016-10-19 14:20:17 -0700359 if (needsCallback) {
360 if (!method->args().empty()) {
361 out << ", ";
Andreas Huber2831d512016-08-15 09:33:47 -0700362 }
363
Yifan Hong10fe0b52016-10-19 14:20:17 -0700364 out << method->name()
Steven Moreland4ddd8332017-04-27 19:27:18 -0700365 << "Callback _hidl_cb";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700366 }
Andreas Huber2831d512016-08-15 09:33:47 -0700367
Steven Morelanddad1b302016-12-20 15:56:00 -0800368 out << ")\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700369 out.indent();
Steven Morelanddad1b302016-12-20 15:56:00 -0800370 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700371 out << "throws android.os.RemoteException {\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800372 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700373
Martijn Coenen115d4282016-12-19 05:14:04 +0100374 if (method->isHidlReserved() && method->overridesJavaImpl(IMPL_PROXY)) {
375 method->javaImpl(IMPL_PROXY, out);
376 out.unindent();
377 out << "}\n";
378 continue;
379 }
Steven Moreland4b39bc12016-11-16 10:42:24 -0800380 out << "android.os.HwParcel _hidl_request = new android.os.HwParcel();\n";
381 out << "_hidl_request.writeInterfaceToken("
Yifan Hong10fe0b52016-10-19 14:20:17 -0700382 << superInterface->fullJavaName()
383 << ".kInterfaceName);\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700384
Yifan Hong10fe0b52016-10-19 14:20:17 -0700385 for (const auto &arg : method->args()) {
386 emitJavaReaderWriter(
387 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800388 "_hidl_request",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700389 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800390 false /* isReader */,
391 false /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700392 }
Andreas Huber2831d512016-08-15 09:33:47 -0700393
Martijn Coenen4de083b2017-03-16 18:49:43 +0100394 out << "\nandroid.os.HwParcel _hidl_reply = new android.os.HwParcel();\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700395
Martijn Coenen4de083b2017-03-16 18:49:43 +0100396 out.sTry([&] {
397 out << "mRemote.transact("
398 << method->getSerialId()
399 << " /* "
400 << method->name()
401 << " */, _hidl_request, _hidl_reply, ";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700402
Martijn Coenen4de083b2017-03-16 18:49:43 +0100403 if (method->isOneway()) {
Steven Moreland77943692018-08-09 12:53:42 -0700404 out << Interface::FLAG_ONE_WAY->javaValue();
Martijn Coenen4de083b2017-03-16 18:49:43 +0100405 } else {
406 out << "0 /* flags */";
Andreas Huber2831d512016-08-15 09:33:47 -0700407 }
408
Martijn Coenen4de083b2017-03-16 18:49:43 +0100409 out << ");\n";
Andreas Huber8b5da222016-08-18 14:28:18 -0700410
Martijn Coenen4de083b2017-03-16 18:49:43 +0100411 if (!method->isOneway()) {
412 out << "_hidl_reply.verifySuccess();\n";
413 } else {
414 CHECK(!returnsValue);
415 }
416
417 out << "_hidl_request.releaseTemporaryStorage();\n";
418
419 if (returnsValue) {
420 out << "\n";
421
Andreas Huber2831d512016-08-15 09:33:47 -0700422 for (const auto &arg : method->results()) {
Martijn Coenen4de083b2017-03-16 18:49:43 +0100423 emitJavaReaderWriter(
424 out,
425 "_hidl_reply",
426 arg,
427 true /* isReader */,
428 true /* addPrefixToName */);
Andreas Huber2831d512016-08-15 09:33:47 -0700429 }
Andreas Huber2831d512016-08-15 09:33:47 -0700430
Martijn Coenen4de083b2017-03-16 18:49:43 +0100431 if (needsCallback) {
Steven Moreland4ddd8332017-04-27 19:27:18 -0700432 out << "_hidl_cb.onValues(";
Martijn Coenen4de083b2017-03-16 18:49:43 +0100433
434 bool firstField = true;
435 for (const auto &arg : method->results()) {
436 if (!firstField) {
437 out << ", ";
438 }
439
440 out << "_hidl_out_" << arg->name();
441 firstField = false;
442 }
443
444 out << ");\n";
445 } else {
446 const std::string returnName = method->results()[0]->name();
447 out << "return _hidl_out_" << returnName << ";\n";
448 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700449 }
Martijn Coenen4de083b2017-03-16 18:49:43 +0100450 }).sFinally([&] {
451 out << "_hidl_reply.release();\n";
452 }).endl();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700453
454 out.unindent();
455 out << "}\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700456 }
457
458 out.unindent();
459 out << "}\n";
460
461 ////////////////////////////////////////////////////////////////////////////
462
Yifan Hong1af73532016-11-09 14:32:58 -0800463 out << "\npublic static abstract class Stub extends android.os.HwBinder "
Andreas Huber2831d512016-08-15 09:33:47 -0700464 << "implements "
465 << ifaceName << " {\n";
466
467 out.indent();
468
Yifan Hong084d11f2016-12-21 15:33:43 -0800469 out << "@Override\npublic android.os.IHwBinder asBinder() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700470 out.indent();
Yifan Hongf89e1062017-10-31 17:31:08 -0700471 // If we change this behavior in the future and asBinder does not return "this",
472 // equals and hashCode should also be overridden.
Andreas Huber2831d512016-08-15 09:33:47 -0700473 out << "return this;\n";
474 out.unindent();
475 out << "}\n\n";
476
Yifan Hong10fe0b52016-10-19 14:20:17 -0700477 for (Method *method : iface->hidlReservedMethods()) {
Martijn Coenenaf712c02016-11-16 15:26:27 +0100478 // b/32383557 this is a hack. We need to change this if we have more reserved methods.
479 CHECK_LE(method->results().size(), 1u);
480 std::string resultType = method->results().size() == 0 ? "void" :
481 method->results()[0]->type().getJavaType();
Steven Moreland327fd8b2018-08-10 15:40:41 -0700482
483 bool canBeOverriden = method->name() == "debug";
484
485 out << "@Override\npublic " << (canBeOverriden ? "" : "final ") << resultType << " "
486 << method->name() << "(";
Yifan Hong932464e2017-03-30 15:40:22 -0700487 method->emitJavaArgSignature(out);
488 out << ") {\n";
Martijn Coenen115d4282016-12-19 05:14:04 +0100489
Yifan Hong10fe0b52016-10-19 14:20:17 -0700490 out.indent();
Steven Moreland937408a2017-03-20 09:54:18 -0700491 method->javaImpl(IMPL_INTERFACE, out);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700492 out.unindent();
493 out << "\n}\n\n";
494 }
495
Yifan Hong084d11f2016-12-21 15:33:43 -0800496 out << "@Override\n"
497 << "public android.os.IHwInterface queryLocalInterface(String descriptor) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700498 out.indent();
499 // XXX what about potential superClasses?
500 out << "if (kInterfaceName.equals(descriptor)) {\n";
501 out.indent();
502 out << "return this;\n";
503 out.unindent();
504 out << "}\n";
505 out << "return null;\n";
506 out.unindent();
507 out << "}\n\n";
508
Yifan Hong320a3492017-03-27 10:33:09 -0700509 out << "public void registerAsService(String serviceName) throws android.os.RemoteException {\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700510 out.indent();
511
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100512 out << "registerService(serviceName);\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700513
514 out.unindent();
515 out << "}\n\n";
516
Yifan Honge45b5302017-02-22 10:49:07 -0800517 out << "@Override\npublic String toString() ";
518 out.block([&] {
519 out << "return this.interfaceDescriptor() + \"@Stub\";\n";
520 }).endl().endl();
521
Yifan Hong084d11f2016-12-21 15:33:43 -0800522 out << "@Override\n"
523 << "public void onTransact("
Steven Moreland4b39bc12016-11-16 10:42:24 -0800524 << "int _hidl_code, "
525 << "android.os.HwParcel _hidl_request, "
526 << "final android.os.HwParcel _hidl_reply, "
Steven Morelanddad1b302016-12-20 15:56:00 -0800527 << "int _hidl_flags)\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700528 out.indent();
Steven Morelanddad1b302016-12-20 15:56:00 -0800529 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700530 out << "throws android.os.RemoteException {\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800531 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700532
Steven Moreland4b39bc12016-11-16 10:42:24 -0800533 out << "switch (_hidl_code) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700534
535 out.indent();
536
Yifan Hong10fe0b52016-10-19 14:20:17 -0700537 for (const auto &tuple : iface->allMethodsFromRoot()) {
538 const Method *method = tuple.method();
Andreas Huber37065d62017-02-07 14:36:54 -0800539
Yifan Hong10fe0b52016-10-19 14:20:17 -0700540 const Interface *superInterface = tuple.interface();
541 const bool returnsValue = !method->results().empty();
542 const bool needsCallback = method->results().size() > 1;
Andreas Huber2831d512016-08-15 09:33:47 -0700543
Yifan Hong10fe0b52016-10-19 14:20:17 -0700544 out << "case "
545 << method->getSerialId()
546 << " /* "
547 << method->name()
548 << " */:\n{\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700549
Yifan Hong10fe0b52016-10-19 14:20:17 -0700550 out.indent();
Andreas Huber37065d62017-02-07 14:36:54 -0800551
Steven Moreland77943692018-08-09 12:53:42 -0700552 out << "boolean _hidl_is_oneway = (_hidl_flags & " << Interface::FLAG_ONE_WAY->javaValue()
553 << ") != 0;\n";
Steven Moreland7dfba102018-03-19 14:37:53 -0700554 out << "if (_hidl_is_oneway != " << (method->isOneway() ? "true" : "false") << ") ";
555 out.block([&] {
556 out << "_hidl_reply.writeStatus(" << UNKNOWN_ERROR << ");\n";
557 out << "_hidl_reply.send();\n";
558 out << "break;\n";
559 });
560
Martijn Coenen115d4282016-12-19 05:14:04 +0100561 if (method->isHidlReserved() && method->overridesJavaImpl(IMPL_STUB)) {
562 method->javaImpl(IMPL_STUB, out);
563 out.unindent();
564 out << "break;\n";
565 out << "}\n\n";
566 continue;
567 }
Andreas Huber2831d512016-08-15 09:33:47 -0700568
Steven Moreland4b39bc12016-11-16 10:42:24 -0800569 out << "_hidl_request.enforceInterface("
Yifan Hong10fe0b52016-10-19 14:20:17 -0700570 << superInterface->fullJavaName()
571 << ".kInterfaceName);\n\n";
572
573 for (const auto &arg : method->args()) {
574 emitJavaReaderWriter(
575 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800576 "_hidl_request",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700577 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800578 true /* isReader */,
579 false /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700580 }
581
582 if (!needsCallback && returnsValue) {
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700583 const NamedReference<Type>* returnArg = method->results()[0];
Yifan Hong10fe0b52016-10-19 14:20:17 -0700584
Yifan Hong4ed13472016-11-02 10:44:11 -0700585 out << returnArg->type().getJavaType()
Yifan Honga47eef32016-12-12 10:38:54 -0800586 << " _hidl_out_"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700587 << returnArg->name()
588 << " = ";
589 }
590
591 out << method->name()
592 << "(";
593
594 bool firstField = true;
595 for (const auto &arg : method->args()) {
596 if (!firstField) {
597 out << ", ";
598 }
599
600 out << arg->name();
601
602 firstField = false;
603 }
604
605 if (needsCallback) {
606 if (!firstField) {
607 out << ", ";
608 }
609
610 out << "new " << method->name() << "Callback() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700611 out.indent();
612
Yifan Hong10fe0b52016-10-19 14:20:17 -0700613 out << "@Override\n"
Yifan Hong932464e2017-03-30 15:40:22 -0700614 << "public void onValues(";
615 method->emitJavaResultSignature(out);
616 out << ") {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700617
Yifan Hong10fe0b52016-10-19 14:20:17 -0700618 out.indent();
Steven Moreland4b39bc12016-11-16 10:42:24 -0800619 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700620
621 for (const auto &arg : method->results()) {
Andreas Huber2831d512016-08-15 09:33:47 -0700622 emitJavaReaderWriter(
623 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800624 "_hidl_reply",
Andreas Huber2831d512016-08-15 09:33:47 -0700625 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800626 false /* isReader */,
627 false /* addPrefixToName */);
628 // no need to add _hidl_out because out vars are are scoped
Andreas Huber2831d512016-08-15 09:33:47 -0700629 }
630
Steven Moreland4b39bc12016-11-16 10:42:24 -0800631 out << "_hidl_reply.send();\n"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700632 << "}}";
Andreas Huber2831d512016-08-15 09:33:47 -0700633
Andreas Huber2831d512016-08-15 09:33:47 -0700634 out.unindent();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700635 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700636 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700637
638 out << ");\n";
639
Martijn Coenen0bb0d412017-02-08 10:21:30 +0100640 if (!needsCallback && !method->isOneway()) {
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 if (returnsValue) {
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700644 const NamedReference<Type>* returnArg = method->results()[0];
Yifan Hong10fe0b52016-10-19 14:20:17 -0700645
646 emitJavaReaderWriter(
647 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800648 "_hidl_reply",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700649 returnArg,
Yifan Honga47eef32016-12-12 10:38:54 -0800650 false /* isReader */,
651 true /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700652 }
653
Steven Moreland4b39bc12016-11-16 10:42:24 -0800654 out << "_hidl_reply.send();\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700655 }
656
657 out << "break;\n";
658 out.unindent();
659 out << "}\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700660 }
661
662 out.unindent();
663 out << "}\n";
664
665 out.unindent();
666 out << "}\n";
667
668 out.unindent();
669 out << "}\n";
670
671 out.unindent();
672 out << "}\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700673}
674
Andreas Huber2831d512016-08-15 09:33:47 -0700675} // namespace android