blob: cb3fcbb29cedd3264d872e2e0082bcb206a2a219 [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"
Neel Mehta291d02e2019-06-06 17:51:07 -070021#include "Location.h"
Andreas Huber2831d512016-08-15 09:33:47 -070022#include "Method.h"
Timur Iskhakov7fa79f62017-08-09 11:04:54 -070023#include "Reference.h"
Andreas Huber2831d512016-08-15 09:33:47 -070024#include "Scope.h"
25
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070026#include <hidl-util/Formatter.h>
Andreas Huber2831d512016-08-15 09:33:47 -070027#include <android-base/logging.h>
28
29namespace android {
30
Timur Iskhakov7fa79f62017-08-09 11:04:54 -070031void AST::emitJavaReaderWriter(Formatter& out, const std::string& parcelObj,
32 const NamedReference<Type>* arg, bool isReader,
33 bool addPrefixToName) const {
Andreas Huber2831d512016-08-15 09:33:47 -070034 if (isReader) {
Yifan Hong4ed13472016-11-02 10:44:11 -070035 out << arg->type().getJavaType()
Andreas Huber2831d512016-08-15 09:33:47 -070036 << " "
Yifan Honga47eef32016-12-12 10:38:54 -080037 << (addPrefixToName ? "_hidl_out_" : "")
Andreas Huber2831d512016-08-15 09:33:47 -070038 << arg->name()
39 << " = ";
40 }
41
Yifan Honga47eef32016-12-12 10:38:54 -080042 arg->type().emitJavaReaderWriter(out, parcelObj,
43 (addPrefixToName ? "_hidl_out_" : "") + arg->name(),
44 isReader);
Andreas Huber2831d512016-08-15 09:33:47 -070045}
46
Steven Moreland368e4602018-02-16 14:21:49 -080047void AST::generateJavaTypes(Formatter& out, const std::string& limitToType) const {
Andreas Huber85eabdb2016-08-25 11:24:49 -070048 // Splits types.hal up into one java file per declared type.
Steven Moreland5abcf012018-02-08 18:50:18 -080049 CHECK(!limitToType.empty()) << getFilename();
Andreas Huber85eabdb2016-08-25 11:24:49 -070050
Timur Iskhakovcb0ba522017-07-17 20:01:37 -070051 for (const auto& type : mRootScope.getSubTypes()) {
Steven Morelandd537ab02016-09-12 10:32:01 -070052 std::string typeName = type->localName();
Andreas Huber85eabdb2016-08-25 11:24:49 -070053
Steven Moreland5abcf012018-02-08 18:50:18 -080054 if (type->isTypeDef()) continue;
55 if (typeName != limitToType) continue;
Andreas Huber85eabdb2016-08-25 11:24:49 -070056
Andreas Huber85eabdb2016-08-25 11:24:49 -070057 std::vector<std::string> packageComponents;
58 getPackageAndVersionComponents(
59 &packageComponents, true /* cpp_compatible */);
60
Steven Moreland5abcf012018-02-08 18:50:18 -080061 out << "package " << mPackage.javaPackage() << ";\n\n\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -070062
Steven Moreland368e4602018-02-16 14:21:49 -080063 type->emitJavaTypeDeclarations(out, true /* atTopLevel */);
64 return;
Andreas Huber85eabdb2016-08-25 11:24:49 -070065 }
66
Steven Moreland5abcf012018-02-08 18:50:18 -080067 CHECK(false) << "generateJavaTypes could not find limitToType type";
Andreas Huber85eabdb2016-08-25 11:24:49 -070068}
69
Steven Moreland9bf5a092017-10-25 04:50:54 +000070void emitGetService(
71 Formatter& out,
72 const std::string& ifaceName,
73 const std::string& fqName,
74 bool isRetry) {
Steven Moreland7645fbd2019-03-12 18:49:28 -070075 if (isRetry) {
76 DocComment(
77 "This will invoke the equivalent of the C++ getService(std::string) if retry is\n"
78 "true or tryGetService(std::string) if retry is false. If the service is\n"
79 "available on the device and retry is true, this will wait for the service to\n"
Neel Mehta291d02e2019-06-06 17:51:07 -070080 "start. Otherwise, it will return immediately even if the service is null.",
81 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -070082 .emit(out);
83 } else {
84 DocComment(
85 "Warning: this will not wait for the interface to come up if it hasn't yet\n"
Neel Mehta291d02e2019-06-06 17:51:07 -070086 "started. See getService(String,boolean) instead.",
87 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -070088 .emit(out);
89 }
Steven Moreland9bf5a092017-10-25 04:50:54 +000090 out << "public static "
91 << ifaceName
92 << " getService(String serviceName";
93 if (isRetry) {
94 out << ", boolean retry";
95 }
96 out << ") throws android.os.RemoteException ";
97 out.block([&] {
98 out << "return "
99 << ifaceName
100 << ".asInterface(android.os.HwBinder.getService(\""
101 << fqName
102 << "\", serviceName";
103 if (isRetry) {
104 out << ", retry";
105 }
106 out << "));\n";
107 }).endl().endl();
108
Steven Moreland7645fbd2019-03-12 18:49:28 -0700109 if (isRetry) {
Neel Mehta291d02e2019-06-06 17:51:07 -0700110 DocComment("Calls getService(\"default\",retry).", HIDL_LOCATION_HERE).emit(out);
Steven Moreland7645fbd2019-03-12 18:49:28 -0700111 } else {
112 DocComment(
113 "Warning: this will not wait for the interface to come up if it hasn't yet "
Neel Mehta291d02e2019-06-06 17:51:07 -0700114 "started. See getService(String,boolean) instead.",
115 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700116 .emit(out);
117 }
Steven Moreland9bf5a092017-10-25 04:50:54 +0000118 out << "public static "
119 << ifaceName
120 << " getService(";
121 if (isRetry) {
122 out << "boolean retry";
123 }
124 out << ") throws android.os.RemoteException ";
125 out.block([&] {
126 out << "return getService(\"default\"";
127 if (isRetry) {
128 out << ", retry";
129 }
130 out <<");\n";
131 }).endl().endl();
132}
133
Steven Moreland368e4602018-02-16 14:21:49 -0800134void AST::generateJava(Formatter& out, const std::string& limitToType) const {
135 CHECK(isJavaCompatible()) << getFilename();
Andreas Huber2831d512016-08-15 09:33:47 -0700136
Steven Moreland19f11b52017-05-12 18:22:21 -0700137 if (!AST::isInterface()) {
Steven Moreland368e4602018-02-16 14:21:49 -0800138 generateJavaTypes(out, limitToType);
139 return;
Andreas Huber0fa9e392016-08-31 09:05:44 -0700140 }
141
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700142 const Interface* iface = mRootScope.getInterface();
Steven Moreland5abcf012018-02-08 18:50:18 -0800143 const std::string ifaceName = iface->localName();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700144 const std::string baseName = iface->getBaseName();
Andreas Huber2831d512016-08-15 09:33:47 -0700145
Andreas Huber2831d512016-08-15 09:33:47 -0700146 out << "package " << mPackage.javaPackage() << ";\n\n";
147
Andreas Huber2831d512016-08-15 09:33:47 -0700148 const Interface *superType = iface->superType();
149
Steven Moreland70cb55e2019-03-12 17:20:54 -0700150 iface->emitDocComment(out);
151
Andreas Huber2831d512016-08-15 09:33:47 -0700152 out << "public interface " << ifaceName << " extends ";
153
Yi Kong56758da2018-07-24 16:21:37 -0700154 if (superType != nullptr) {
Andreas Huber2831d512016-08-15 09:33:47 -0700155 out << superType->fullJavaName();
156 } else {
Yifan Hong1af73532016-11-09 14:32:58 -0800157 out << "android.os.IHwInterface";
Andreas Huber2831d512016-08-15 09:33:47 -0700158 }
159
160 out << " {\n";
161 out.indent();
162
Neel Mehta291d02e2019-06-06 17:51:07 -0700163 DocComment("Fully-qualified interface name for this interface.", HIDL_LOCATION_HERE).emit(out);
Andreas Huber2831d512016-08-15 09:33:47 -0700164 out << "public static final String kInterfaceName = \""
165 << mPackage.string()
166 << "::"
167 << ifaceName
168 << "\";\n\n";
169
Neel Mehta291d02e2019-06-06 17:51:07 -0700170 DocComment("Does a checked conversion from a binder to this class.", HIDL_LOCATION_HERE)
171 .emit(out);
Andreas Hubera2abe982017-04-04 14:42:09 -0700172 out << "/* package private */ static "
Andreas Huber2831d512016-08-15 09:33:47 -0700173 << ifaceName
Yifan Hong1af73532016-11-09 14:32:58 -0800174 << " asInterface(android.os.IHwBinder binder) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700175
176 out.indent();
177
178 out << "if (binder == null) {\n";
179 out.indent();
180 out << "return null;\n";
181 out.unindent();
182 out << "}\n\n";
183
Yifan Hong1af73532016-11-09 14:32:58 -0800184 out << "android.os.IHwInterface iface =\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700185 out.indent();
186 out.indent();
187 out << "binder.queryLocalInterface(kInterfaceName);\n\n";
188 out.unindent();
189 out.unindent();
190
191 out << "if ((iface != null) && (iface instanceof "
192 << ifaceName
193 << ")) {\n";
194
195 out.indent();
196 out << "return (" << ifaceName << ")iface;\n";
197 out.unindent();
198 out << "}\n\n";
199
Andreas Hubera2abe982017-04-04 14:42:09 -0700200 out << ifaceName << " proxy = new " << ifaceName << ".Proxy(binder);\n\n";
201 out << "try {\n";
202 out.indent();
203 out << "for (String descriptor : proxy.interfaceChain()) {\n";
204 out.indent();
205 out << "if (descriptor.equals(kInterfaceName)) {\n";
206 out.indent();
207 out << "return proxy;\n";
208 out.unindent();
209 out << "}\n";
210 out.unindent();
211 out << "}\n";
212 out.unindent();
213 out << "} catch (android.os.RemoteException e) {\n";
214 out.indent();
215 out.unindent();
216 out << "}\n\n";
217
218 out << "return null;\n";
219
220 out.unindent();
221 out << "}\n\n";
222
Neel Mehta291d02e2019-06-06 17:51:07 -0700223 DocComment("Does a checked conversion from any interface to this class.", HIDL_LOCATION_HERE)
224 .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()) {
Andreas Huber2831d512016-08-15 09:33:47 -0700245 const bool needsCallback = method->results().size() > 1;
246
247 if (needsCallback) {
Yifan Hong601cfca2017-05-24 12:20:17 -0700248 out << "\n@java.lang.FunctionalInterface\npublic interface " << method->name()
Andreas Huber2831d512016-08-15 09:33:47 -0700249 << "Callback {\n";
250
251 out.indent();
252
Yifan Hong932464e2017-03-30 15:40:22 -0700253 out << "public void onValues(";
254 method->emitJavaResultSignature(out);
255 out << ");\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700256
257 out.unindent();
258 out << "}\n\n";
259 }
260
Steven Moreland49bad8d2018-05-17 15:45:26 -0700261 method->emitDocComment(out);
262
Neel Mehta5b447c02019-05-23 16:12:24 -0700263 method->emitJavaSignature(out);
Andreas Huber2831d512016-08-15 09:33:47 -0700264
Neel Mehta5b447c02019-05-23 16:12:24 -0700265 out << "\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800266 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700267 out << "throws android.os.RemoteException;\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800268 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700269 }
270
271 out << "\npublic static final class Proxy implements "
272 << ifaceName
273 << " {\n";
274
275 out.indent();
276
Yifan Hong1af73532016-11-09 14:32:58 -0800277 out << "private android.os.IHwBinder mRemote;\n\n";
278 out << "public Proxy(android.os.IHwBinder remote) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700279 out.indent();
Yifan Hong729e7962016-12-21 16:04:27 -0800280 out << "mRemote = java.util.Objects.requireNonNull(remote);\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700281 out.unindent();
282 out << "}\n\n";
283
Yifan Hong084d11f2016-12-21 15:33:43 -0800284 out << "@Override\npublic android.os.IHwBinder asBinder() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700285 out.indent();
286 out << "return mRemote;\n";
287 out.unindent();
288 out << "}\n\n";
289
Yifan Honge45b5302017-02-22 10:49:07 -0800290
291 out << "@Override\npublic String toString() ";
292 out.block([&] {
293 out.sTry([&] {
294 out << "return this.interfaceDescriptor() + \"@Proxy\";\n";
Yifan Hong320a3492017-03-27 10:33:09 -0700295 }).sCatch("android.os.RemoteException ex", [&] {
Yifan Honge45b5302017-02-22 10:49:07 -0800296 out << "/* ignored; handled below. */\n";
297 }).endl();
298 out << "return \"[class or subclass of \" + "
299 << ifaceName << ".kInterfaceName + \"]@Proxy\";\n";
300 }).endl().endl();
301
Yifan Hongf89e1062017-10-31 17:31:08 -0700302 // Equals when internal binder object is equal (even if the interface Proxy object
303 // itself is different). This is similar to interfacesEqual in C++.
304 out << "@Override\npublic final boolean equals(java.lang.Object other) ";
305 out.block([&] {
306 out << "return android.os.HidlSupport.interfacesEqual(this, other);\n";
307 }).endl().endl();
308
309 out << "@Override\npublic final int hashCode() ";
310 out.block([&] {
311 out << "return this.asBinder().hashCode();\n";
312 }).endl().endl();
313
Yifan Hong10fe0b52016-10-19 14:20:17 -0700314 const Interface *prevInterface = nullptr;
315 for (const auto &tuple : iface->allMethodsFromRoot()) {
316 const Method *method = tuple.method();
Andreas Huber37065d62017-02-07 14:36:54 -0800317
Yifan Hong10fe0b52016-10-19 14:20:17 -0700318 const Interface *superInterface = tuple.interface();
319 if (prevInterface != superInterface) {
320 out << "// Methods from "
321 << superInterface->fullName()
322 << " follow.\n";
323 prevInterface = superInterface;
324 }
325 const bool returnsValue = !method->results().empty();
326 const bool needsCallback = method->results().size() > 1;
Andreas Huber2831d512016-08-15 09:33:47 -0700327
Yifan Hong084d11f2016-12-21 15:33:43 -0800328 out << "@Override\npublic ";
Neel Mehta5b447c02019-05-23 16:12:24 -0700329 method->emitJavaSignature(out);
Andreas Huber2831d512016-08-15 09:33:47 -0700330
Neel Mehta5b447c02019-05-23 16:12:24 -0700331 out << "\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700332 out.indent();
Steven Morelanddad1b302016-12-20 15:56:00 -0800333 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700334 out << "throws android.os.RemoteException {\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800335 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700336
Martijn Coenen115d4282016-12-19 05:14:04 +0100337 if (method->isHidlReserved() && method->overridesJavaImpl(IMPL_PROXY)) {
338 method->javaImpl(IMPL_PROXY, out);
339 out.unindent();
340 out << "}\n";
341 continue;
342 }
Steven Moreland4b39bc12016-11-16 10:42:24 -0800343 out << "android.os.HwParcel _hidl_request = new android.os.HwParcel();\n";
344 out << "_hidl_request.writeInterfaceToken("
Yifan Hong10fe0b52016-10-19 14:20:17 -0700345 << superInterface->fullJavaName()
346 << ".kInterfaceName);\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700347
Yifan Hong10fe0b52016-10-19 14:20:17 -0700348 for (const auto &arg : method->args()) {
349 emitJavaReaderWriter(
350 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800351 "_hidl_request",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700352 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800353 false /* isReader */,
354 false /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700355 }
Andreas Huber2831d512016-08-15 09:33:47 -0700356
Martijn Coenen4de083b2017-03-16 18:49:43 +0100357 out << "\nandroid.os.HwParcel _hidl_reply = new android.os.HwParcel();\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700358
Martijn Coenen4de083b2017-03-16 18:49:43 +0100359 out.sTry([&] {
360 out << "mRemote.transact("
361 << method->getSerialId()
362 << " /* "
363 << method->name()
364 << " */, _hidl_request, _hidl_reply, ";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700365
Martijn Coenen4de083b2017-03-16 18:49:43 +0100366 if (method->isOneway()) {
Steven Moreland77943692018-08-09 12:53:42 -0700367 out << Interface::FLAG_ONE_WAY->javaValue();
Martijn Coenen4de083b2017-03-16 18:49:43 +0100368 } else {
369 out << "0 /* flags */";
Andreas Huber2831d512016-08-15 09:33:47 -0700370 }
371
Martijn Coenen4de083b2017-03-16 18:49:43 +0100372 out << ");\n";
Andreas Huber8b5da222016-08-18 14:28:18 -0700373
Martijn Coenen4de083b2017-03-16 18:49:43 +0100374 if (!method->isOneway()) {
375 out << "_hidl_reply.verifySuccess();\n";
376 } else {
377 CHECK(!returnsValue);
378 }
379
380 out << "_hidl_request.releaseTemporaryStorage();\n";
381
382 if (returnsValue) {
383 out << "\n";
384
Andreas Huber2831d512016-08-15 09:33:47 -0700385 for (const auto &arg : method->results()) {
Martijn Coenen4de083b2017-03-16 18:49:43 +0100386 emitJavaReaderWriter(
387 out,
388 "_hidl_reply",
389 arg,
390 true /* isReader */,
391 true /* addPrefixToName */);
Andreas Huber2831d512016-08-15 09:33:47 -0700392 }
Andreas Huber2831d512016-08-15 09:33:47 -0700393
Martijn Coenen4de083b2017-03-16 18:49:43 +0100394 if (needsCallback) {
Steven Moreland4ddd8332017-04-27 19:27:18 -0700395 out << "_hidl_cb.onValues(";
Martijn Coenen4de083b2017-03-16 18:49:43 +0100396
397 bool firstField = true;
398 for (const auto &arg : method->results()) {
399 if (!firstField) {
400 out << ", ";
401 }
402
403 out << "_hidl_out_" << arg->name();
404 firstField = false;
405 }
406
407 out << ");\n";
408 } else {
409 const std::string returnName = method->results()[0]->name();
410 out << "return _hidl_out_" << returnName << ";\n";
411 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700412 }
Martijn Coenen4de083b2017-03-16 18:49:43 +0100413 }).sFinally([&] {
414 out << "_hidl_reply.release();\n";
415 }).endl();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700416
417 out.unindent();
418 out << "}\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700419 }
420
421 out.unindent();
422 out << "}\n";
423
424 ////////////////////////////////////////////////////////////////////////////
425
Yifan Hong1af73532016-11-09 14:32:58 -0800426 out << "\npublic static abstract class Stub extends android.os.HwBinder "
Andreas Huber2831d512016-08-15 09:33:47 -0700427 << "implements "
428 << ifaceName << " {\n";
429
430 out.indent();
431
Yifan Hong084d11f2016-12-21 15:33:43 -0800432 out << "@Override\npublic android.os.IHwBinder asBinder() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700433 out.indent();
Yifan Hongf89e1062017-10-31 17:31:08 -0700434 // If we change this behavior in the future and asBinder does not return "this",
435 // equals and hashCode should also be overridden.
Andreas Huber2831d512016-08-15 09:33:47 -0700436 out << "return this;\n";
437 out.unindent();
438 out << "}\n\n";
439
Yifan Hong10fe0b52016-10-19 14:20:17 -0700440 for (Method *method : iface->hidlReservedMethods()) {
Martijn Coenenaf712c02016-11-16 15:26:27 +0100441 // b/32383557 this is a hack. We need to change this if we have more reserved methods.
442 CHECK_LE(method->results().size(), 1u);
443 std::string resultType = method->results().size() == 0 ? "void" :
444 method->results()[0]->type().getJavaType();
Steven Moreland327fd8b2018-08-10 15:40:41 -0700445
446 bool canBeOverriden = method->name() == "debug";
447
448 out << "@Override\npublic " << (canBeOverriden ? "" : "final ") << resultType << " "
449 << method->name() << "(";
Yifan Hong932464e2017-03-30 15:40:22 -0700450 method->emitJavaArgSignature(out);
451 out << ") {\n";
Martijn Coenen115d4282016-12-19 05:14:04 +0100452
Yifan Hong10fe0b52016-10-19 14:20:17 -0700453 out.indent();
Steven Moreland937408a2017-03-20 09:54:18 -0700454 method->javaImpl(IMPL_INTERFACE, out);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700455 out.unindent();
456 out << "\n}\n\n";
457 }
458
Yifan Hong084d11f2016-12-21 15:33:43 -0800459 out << "@Override\n"
460 << "public android.os.IHwInterface queryLocalInterface(String descriptor) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700461 out.indent();
462 // XXX what about potential superClasses?
463 out << "if (kInterfaceName.equals(descriptor)) {\n";
464 out.indent();
465 out << "return this;\n";
466 out.unindent();
467 out << "}\n";
468 out << "return null;\n";
469 out.unindent();
470 out << "}\n\n";
471
Yifan Hong320a3492017-03-27 10:33:09 -0700472 out << "public void registerAsService(String serviceName) throws android.os.RemoteException {\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700473 out.indent();
474
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100475 out << "registerService(serviceName);\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700476
477 out.unindent();
478 out << "}\n\n";
479
Yifan Honge45b5302017-02-22 10:49:07 -0800480 out << "@Override\npublic String toString() ";
481 out.block([&] {
482 out << "return this.interfaceDescriptor() + \"@Stub\";\n";
483 }).endl().endl();
484
Yifan Hong084d11f2016-12-21 15:33:43 -0800485 out << "@Override\n"
486 << "public void onTransact("
Steven Moreland4b39bc12016-11-16 10:42:24 -0800487 << "int _hidl_code, "
488 << "android.os.HwParcel _hidl_request, "
489 << "final android.os.HwParcel _hidl_reply, "
Steven Morelanddad1b302016-12-20 15:56:00 -0800490 << "int _hidl_flags)\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700491 out.indent();
Steven Morelanddad1b302016-12-20 15:56:00 -0800492 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700493 out << "throws android.os.RemoteException {\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800494 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700495
Steven Moreland4b39bc12016-11-16 10:42:24 -0800496 out << "switch (_hidl_code) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700497
498 out.indent();
499
Yifan Hong10fe0b52016-10-19 14:20:17 -0700500 for (const auto &tuple : iface->allMethodsFromRoot()) {
501 const Method *method = tuple.method();
Andreas Huber37065d62017-02-07 14:36:54 -0800502
Yifan Hong10fe0b52016-10-19 14:20:17 -0700503 const Interface *superInterface = tuple.interface();
504 const bool returnsValue = !method->results().empty();
505 const bool needsCallback = method->results().size() > 1;
Andreas Huber2831d512016-08-15 09:33:47 -0700506
Yifan Hong10fe0b52016-10-19 14:20:17 -0700507 out << "case "
508 << method->getSerialId()
509 << " /* "
510 << method->name()
511 << " */:\n{\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700512
Yifan Hong10fe0b52016-10-19 14:20:17 -0700513 out.indent();
Andreas Huber37065d62017-02-07 14:36:54 -0800514
Martijn Coenen115d4282016-12-19 05:14:04 +0100515 if (method->isHidlReserved() && method->overridesJavaImpl(IMPL_STUB)) {
516 method->javaImpl(IMPL_STUB, out);
517 out.unindent();
518 out << "break;\n";
519 out << "}\n\n";
520 continue;
521 }
Andreas Huber2831d512016-08-15 09:33:47 -0700522
Steven Moreland4b39bc12016-11-16 10:42:24 -0800523 out << "_hidl_request.enforceInterface("
Yifan Hong10fe0b52016-10-19 14:20:17 -0700524 << superInterface->fullJavaName()
525 << ".kInterfaceName);\n\n";
526
527 for (const auto &arg : method->args()) {
528 emitJavaReaderWriter(
529 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800530 "_hidl_request",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700531 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800532 true /* isReader */,
533 false /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700534 }
535
536 if (!needsCallback && returnsValue) {
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700537 const NamedReference<Type>* returnArg = method->results()[0];
Yifan Hong10fe0b52016-10-19 14:20:17 -0700538
Yifan Hong4ed13472016-11-02 10:44:11 -0700539 out << returnArg->type().getJavaType()
Yifan Honga47eef32016-12-12 10:38:54 -0800540 << " _hidl_out_"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700541 << returnArg->name()
542 << " = ";
543 }
544
545 out << method->name()
546 << "(";
547
548 bool firstField = true;
549 for (const auto &arg : method->args()) {
550 if (!firstField) {
551 out << ", ";
552 }
553
554 out << arg->name();
555
556 firstField = false;
557 }
558
559 if (needsCallback) {
560 if (!firstField) {
561 out << ", ";
562 }
563
564 out << "new " << method->name() << "Callback() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700565 out.indent();
566
Yifan Hong10fe0b52016-10-19 14:20:17 -0700567 out << "@Override\n"
Yifan Hong932464e2017-03-30 15:40:22 -0700568 << "public void onValues(";
569 method->emitJavaResultSignature(out);
570 out << ") {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700571
Yifan Hong10fe0b52016-10-19 14:20:17 -0700572 out.indent();
Steven Moreland4b39bc12016-11-16 10:42:24 -0800573 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700574
575 for (const auto &arg : method->results()) {
Andreas Huber2831d512016-08-15 09:33:47 -0700576 emitJavaReaderWriter(
577 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800578 "_hidl_reply",
Andreas Huber2831d512016-08-15 09:33:47 -0700579 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800580 false /* isReader */,
581 false /* addPrefixToName */);
582 // no need to add _hidl_out because out vars are are scoped
Andreas Huber2831d512016-08-15 09:33:47 -0700583 }
584
Steven Moreland4b39bc12016-11-16 10:42:24 -0800585 out << "_hidl_reply.send();\n"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700586 << "}}";
Andreas Huber2831d512016-08-15 09:33:47 -0700587
Andreas Huber2831d512016-08-15 09:33:47 -0700588 out.unindent();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700589 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700590 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700591
592 out << ");\n";
593
Martijn Coenen0bb0d412017-02-08 10:21:30 +0100594 if (!needsCallback && !method->isOneway()) {
Steven Moreland4b39bc12016-11-16 10:42:24 -0800595 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700596
597 if (returnsValue) {
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700598 const NamedReference<Type>* returnArg = method->results()[0];
Yifan Hong10fe0b52016-10-19 14:20:17 -0700599
600 emitJavaReaderWriter(
601 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800602 "_hidl_reply",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700603 returnArg,
Yifan Honga47eef32016-12-12 10:38:54 -0800604 false /* isReader */,
605 true /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700606 }
607
Steven Moreland4b39bc12016-11-16 10:42:24 -0800608 out << "_hidl_reply.send();\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700609 }
610
611 out << "break;\n";
612 out.unindent();
613 out << "}\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700614 }
615
616 out.unindent();
617 out << "}\n";
618
619 out.unindent();
620 out << "}\n";
621
622 out.unindent();
623 out << "}\n";
624
625 out.unindent();
626 out << "}\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700627}
628
Andreas Huber2831d512016-08-15 09:33:47 -0700629} // namespace android