blob: 9eb1232c0488bd56e6660e86aed129cc57b8df62 [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()) {
Neel Mehta9200af02019-07-19 13:24:57 -070052 std::string typeName = type->definedName();
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
Steven Moreland5abcf012018-02-08 18:50:18 -080057 out << "package " << mPackage.javaPackage() << ";\n\n\n";
Andreas Huber85eabdb2016-08-25 11:24:49 -070058
Steven Moreland368e4602018-02-16 14:21:49 -080059 type->emitJavaTypeDeclarations(out, true /* atTopLevel */);
60 return;
Andreas Huber85eabdb2016-08-25 11:24:49 -070061 }
62
Steven Moreland5abcf012018-02-08 18:50:18 -080063 CHECK(false) << "generateJavaTypes could not find limitToType type";
Andreas Huber85eabdb2016-08-25 11:24:49 -070064}
65
Steven Moreland9bf5a092017-10-25 04:50:54 +000066void emitGetService(
67 Formatter& out,
68 const std::string& ifaceName,
69 const std::string& fqName,
70 bool isRetry) {
Steven Moreland7645fbd2019-03-12 18:49:28 -070071 if (isRetry) {
72 DocComment(
73 "This will invoke the equivalent of the C++ getService(std::string) if retry is\n"
74 "true or tryGetService(std::string) if retry is false. If the service is\n"
75 "available on the device and retry is true, this will wait for the service to\n"
Neel Mehta291d02e2019-06-06 17:51:07 -070076 "start. Otherwise, it will return immediately even if the service is null.",
77 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -070078 .emit(out);
79 } else {
80 DocComment(
81 "Warning: this will not wait for the interface to come up if it hasn't yet\n"
Neel Mehta291d02e2019-06-06 17:51:07 -070082 "started. See getService(String,boolean) instead.",
83 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -070084 .emit(out);
85 }
Steven Moreland9bf5a092017-10-25 04:50:54 +000086 out << "public static "
87 << ifaceName
88 << " getService(String serviceName";
89 if (isRetry) {
90 out << ", boolean retry";
91 }
92 out << ") throws android.os.RemoteException ";
93 out.block([&] {
94 out << "return "
95 << ifaceName
96 << ".asInterface(android.os.HwBinder.getService(\""
97 << fqName
98 << "\", serviceName";
99 if (isRetry) {
100 out << ", retry";
101 }
102 out << "));\n";
103 }).endl().endl();
104
Steven Moreland7645fbd2019-03-12 18:49:28 -0700105 if (isRetry) {
Neel Mehta291d02e2019-06-06 17:51:07 -0700106 DocComment("Calls getService(\"default\",retry).", HIDL_LOCATION_HERE).emit(out);
Steven Moreland7645fbd2019-03-12 18:49:28 -0700107 } else {
108 DocComment(
109 "Warning: this will not wait for the interface to come up if it hasn't yet "
Neel Mehta291d02e2019-06-06 17:51:07 -0700110 "started. See getService(String,boolean) instead.",
111 HIDL_LOCATION_HERE)
Steven Moreland7645fbd2019-03-12 18:49:28 -0700112 .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();
Neel Mehta9200af02019-07-19 13:24:57 -0700139 const std::string ifaceName = iface->definedName();
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 const Interface *superType = iface->superType();
145
Steven Moreland70cb55e2019-03-12 17:20:54 -0700146 iface->emitDocComment(out);
147
Andreas Huber2831d512016-08-15 09:33:47 -0700148 out << "public interface " << ifaceName << " extends ";
149
Yi Kong56758da2018-07-24 16:21:37 -0700150 if (superType != nullptr) {
Andreas Huber2831d512016-08-15 09:33:47 -0700151 out << superType->fullJavaName();
152 } else {
Yifan Hong1af73532016-11-09 14:32:58 -0800153 out << "android.os.IHwInterface";
Andreas Huber2831d512016-08-15 09:33:47 -0700154 }
155
156 out << " {\n";
157 out.indent();
158
Neel Mehta291d02e2019-06-06 17:51:07 -0700159 DocComment("Fully-qualified interface name for this interface.", HIDL_LOCATION_HERE).emit(out);
Andreas Huber2831d512016-08-15 09:33:47 -0700160 out << "public static final String kInterfaceName = \""
161 << mPackage.string()
162 << "::"
163 << ifaceName
164 << "\";\n\n";
165
Neel Mehta291d02e2019-06-06 17:51:07 -0700166 DocComment("Does a checked conversion from a binder to this class.", HIDL_LOCATION_HERE)
167 .emit(out);
Andreas Hubera2abe982017-04-04 14:42:09 -0700168 out << "/* package private */ static "
Andreas Huber2831d512016-08-15 09:33:47 -0700169 << ifaceName
Yifan Hong1af73532016-11-09 14:32:58 -0800170 << " asInterface(android.os.IHwBinder binder) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700171
172 out.indent();
173
174 out << "if (binder == null) {\n";
175 out.indent();
176 out << "return null;\n";
177 out.unindent();
178 out << "}\n\n";
179
Yifan Hong1af73532016-11-09 14:32:58 -0800180 out << "android.os.IHwInterface iface =\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700181 out.indent();
182 out.indent();
183 out << "binder.queryLocalInterface(kInterfaceName);\n\n";
184 out.unindent();
185 out.unindent();
186
187 out << "if ((iface != null) && (iface instanceof "
188 << ifaceName
189 << ")) {\n";
190
191 out.indent();
192 out << "return (" << ifaceName << ")iface;\n";
193 out.unindent();
194 out << "}\n\n";
195
Andreas Hubera2abe982017-04-04 14:42:09 -0700196 out << ifaceName << " proxy = new " << ifaceName << ".Proxy(binder);\n\n";
197 out << "try {\n";
198 out.indent();
199 out << "for (String descriptor : proxy.interfaceChain()) {\n";
200 out.indent();
201 out << "if (descriptor.equals(kInterfaceName)) {\n";
202 out.indent();
203 out << "return proxy;\n";
204 out.unindent();
205 out << "}\n";
206 out.unindent();
207 out << "}\n";
208 out.unindent();
209 out << "} catch (android.os.RemoteException e) {\n";
210 out.indent();
211 out.unindent();
212 out << "}\n\n";
213
214 out << "return null;\n";
215
216 out.unindent();
217 out << "}\n\n";
218
Neel Mehta291d02e2019-06-06 17:51:07 -0700219 DocComment("Does a checked conversion from any interface to this class.", HIDL_LOCATION_HERE)
220 .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()) {
Andreas Huber2831d512016-08-15 09:33:47 -0700241 const bool needsCallback = method->results().size() > 1;
242
243 if (needsCallback) {
Yifan Hong601cfca2017-05-24 12:20:17 -0700244 out << "\n@java.lang.FunctionalInterface\npublic interface " << method->name()
Andreas Huber2831d512016-08-15 09:33:47 -0700245 << "Callback {\n";
246
247 out.indent();
248
Yifan Hong932464e2017-03-30 15:40:22 -0700249 out << "public void onValues(";
250 method->emitJavaResultSignature(out);
251 out << ");\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700252
253 out.unindent();
254 out << "}\n\n";
255 }
256
Steven Moreland49bad8d2018-05-17 15:45:26 -0700257 method->emitDocComment(out);
258
Neel Mehta5b447c02019-05-23 16:12:24 -0700259 method->emitJavaSignature(out);
Andreas Huber2831d512016-08-15 09:33:47 -0700260
Neel Mehta5b447c02019-05-23 16:12:24 -0700261 out << "\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800262 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700263 out << "throws android.os.RemoteException;\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800264 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700265 }
266
267 out << "\npublic static final class Proxy implements "
268 << ifaceName
269 << " {\n";
270
271 out.indent();
272
Yifan Hong1af73532016-11-09 14:32:58 -0800273 out << "private android.os.IHwBinder mRemote;\n\n";
274 out << "public Proxy(android.os.IHwBinder remote) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700275 out.indent();
Yifan Hong729e7962016-12-21 16:04:27 -0800276 out << "mRemote = java.util.Objects.requireNonNull(remote);\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700277 out.unindent();
278 out << "}\n\n";
279
Yifan Hong084d11f2016-12-21 15:33:43 -0800280 out << "@Override\npublic android.os.IHwBinder asBinder() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700281 out.indent();
282 out << "return mRemote;\n";
283 out.unindent();
284 out << "}\n\n";
285
Yifan Honge45b5302017-02-22 10:49:07 -0800286
287 out << "@Override\npublic String toString() ";
288 out.block([&] {
289 out.sTry([&] {
290 out << "return this.interfaceDescriptor() + \"@Proxy\";\n";
Yifan Hong320a3492017-03-27 10:33:09 -0700291 }).sCatch("android.os.RemoteException ex", [&] {
Yifan Honge45b5302017-02-22 10:49:07 -0800292 out << "/* ignored; handled below. */\n";
293 }).endl();
294 out << "return \"[class or subclass of \" + "
295 << ifaceName << ".kInterfaceName + \"]@Proxy\";\n";
296 }).endl().endl();
297
Yifan Hongf89e1062017-10-31 17:31:08 -0700298 // Equals when internal binder object is equal (even if the interface Proxy object
299 // itself is different). This is similar to interfacesEqual in C++.
300 out << "@Override\npublic final boolean equals(java.lang.Object other) ";
301 out.block([&] {
302 out << "return android.os.HidlSupport.interfacesEqual(this, other);\n";
303 }).endl().endl();
304
305 out << "@Override\npublic final int hashCode() ";
306 out.block([&] {
307 out << "return this.asBinder().hashCode();\n";
308 }).endl().endl();
309
Yifan Hong10fe0b52016-10-19 14:20:17 -0700310 const Interface *prevInterface = nullptr;
311 for (const auto &tuple : iface->allMethodsFromRoot()) {
312 const Method *method = tuple.method();
Andreas Huber37065d62017-02-07 14:36:54 -0800313
Yifan Hong10fe0b52016-10-19 14:20:17 -0700314 const Interface *superInterface = tuple.interface();
315 if (prevInterface != superInterface) {
316 out << "// Methods from "
317 << superInterface->fullName()
318 << " follow.\n";
319 prevInterface = superInterface;
320 }
321 const bool returnsValue = !method->results().empty();
322 const bool needsCallback = method->results().size() > 1;
Andreas Huber2831d512016-08-15 09:33:47 -0700323
Yifan Hong084d11f2016-12-21 15:33:43 -0800324 out << "@Override\npublic ";
Neel Mehta5b447c02019-05-23 16:12:24 -0700325 method->emitJavaSignature(out);
Andreas Huber2831d512016-08-15 09:33:47 -0700326
Neel Mehta5b447c02019-05-23 16:12:24 -0700327 out << "\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700328 out.indent();
Steven Morelanddad1b302016-12-20 15:56:00 -0800329 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700330 out << "throws android.os.RemoteException {\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800331 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700332
Martijn Coenen115d4282016-12-19 05:14:04 +0100333 if (method->isHidlReserved() && method->overridesJavaImpl(IMPL_PROXY)) {
334 method->javaImpl(IMPL_PROXY, out);
335 out.unindent();
336 out << "}\n";
337 continue;
338 }
Steven Moreland4b39bc12016-11-16 10:42:24 -0800339 out << "android.os.HwParcel _hidl_request = new android.os.HwParcel();\n";
340 out << "_hidl_request.writeInterfaceToken("
Yifan Hong10fe0b52016-10-19 14:20:17 -0700341 << superInterface->fullJavaName()
342 << ".kInterfaceName);\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700343
Yifan Hong10fe0b52016-10-19 14:20:17 -0700344 for (const auto &arg : method->args()) {
345 emitJavaReaderWriter(
346 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800347 "_hidl_request",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700348 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800349 false /* isReader */,
350 false /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700351 }
Andreas Huber2831d512016-08-15 09:33:47 -0700352
Martijn Coenen4de083b2017-03-16 18:49:43 +0100353 out << "\nandroid.os.HwParcel _hidl_reply = new android.os.HwParcel();\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700354
Martijn Coenen4de083b2017-03-16 18:49:43 +0100355 out.sTry([&] {
356 out << "mRemote.transact("
357 << method->getSerialId()
358 << " /* "
359 << method->name()
360 << " */, _hidl_request, _hidl_reply, ";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700361
Martijn Coenen4de083b2017-03-16 18:49:43 +0100362 if (method->isOneway()) {
Steven Moreland77943692018-08-09 12:53:42 -0700363 out << Interface::FLAG_ONE_WAY->javaValue();
Martijn Coenen4de083b2017-03-16 18:49:43 +0100364 } else {
365 out << "0 /* flags */";
Andreas Huber2831d512016-08-15 09:33:47 -0700366 }
367
Martijn Coenen4de083b2017-03-16 18:49:43 +0100368 out << ");\n";
Andreas Huber8b5da222016-08-18 14:28:18 -0700369
Martijn Coenen4de083b2017-03-16 18:49:43 +0100370 if (!method->isOneway()) {
371 out << "_hidl_reply.verifySuccess();\n";
372 } else {
373 CHECK(!returnsValue);
374 }
375
376 out << "_hidl_request.releaseTemporaryStorage();\n";
377
378 if (returnsValue) {
379 out << "\n";
380
Andreas Huber2831d512016-08-15 09:33:47 -0700381 for (const auto &arg : method->results()) {
Martijn Coenen4de083b2017-03-16 18:49:43 +0100382 emitJavaReaderWriter(
383 out,
384 "_hidl_reply",
385 arg,
386 true /* isReader */,
387 true /* addPrefixToName */);
Andreas Huber2831d512016-08-15 09:33:47 -0700388 }
Andreas Huber2831d512016-08-15 09:33:47 -0700389
Martijn Coenen4de083b2017-03-16 18:49:43 +0100390 if (needsCallback) {
Steven Moreland4ddd8332017-04-27 19:27:18 -0700391 out << "_hidl_cb.onValues(";
Martijn Coenen4de083b2017-03-16 18:49:43 +0100392
393 bool firstField = true;
394 for (const auto &arg : method->results()) {
395 if (!firstField) {
396 out << ", ";
397 }
398
399 out << "_hidl_out_" << arg->name();
400 firstField = false;
401 }
402
403 out << ");\n";
404 } else {
405 const std::string returnName = method->results()[0]->name();
406 out << "return _hidl_out_" << returnName << ";\n";
407 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700408 }
Martijn Coenen4de083b2017-03-16 18:49:43 +0100409 }).sFinally([&] {
410 out << "_hidl_reply.release();\n";
411 }).endl();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700412
413 out.unindent();
414 out << "}\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700415 }
416
417 out.unindent();
418 out << "}\n";
419
420 ////////////////////////////////////////////////////////////////////////////
421
Yifan Hong1af73532016-11-09 14:32:58 -0800422 out << "\npublic static abstract class Stub extends android.os.HwBinder "
Andreas Huber2831d512016-08-15 09:33:47 -0700423 << "implements "
424 << ifaceName << " {\n";
425
426 out.indent();
427
Yifan Hong084d11f2016-12-21 15:33:43 -0800428 out << "@Override\npublic android.os.IHwBinder asBinder() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700429 out.indent();
Yifan Hongf89e1062017-10-31 17:31:08 -0700430 // If we change this behavior in the future and asBinder does not return "this",
431 // equals and hashCode should also be overridden.
Andreas Huber2831d512016-08-15 09:33:47 -0700432 out << "return this;\n";
433 out.unindent();
434 out << "}\n\n";
435
Yifan Hong10fe0b52016-10-19 14:20:17 -0700436 for (Method *method : iface->hidlReservedMethods()) {
Martijn Coenenaf712c02016-11-16 15:26:27 +0100437 // b/32383557 this is a hack. We need to change this if we have more reserved methods.
438 CHECK_LE(method->results().size(), 1u);
439 std::string resultType = method->results().size() == 0 ? "void" :
440 method->results()[0]->type().getJavaType();
Steven Moreland327fd8b2018-08-10 15:40:41 -0700441
442 bool canBeOverriden = method->name() == "debug";
443
444 out << "@Override\npublic " << (canBeOverriden ? "" : "final ") << resultType << " "
445 << method->name() << "(";
Yifan Hong932464e2017-03-30 15:40:22 -0700446 method->emitJavaArgSignature(out);
447 out << ") {\n";
Martijn Coenen115d4282016-12-19 05:14:04 +0100448
Yifan Hong10fe0b52016-10-19 14:20:17 -0700449 out.indent();
Steven Moreland937408a2017-03-20 09:54:18 -0700450 method->javaImpl(IMPL_INTERFACE, out);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700451 out.unindent();
452 out << "\n}\n\n";
453 }
454
Yifan Hong084d11f2016-12-21 15:33:43 -0800455 out << "@Override\n"
456 << "public android.os.IHwInterface queryLocalInterface(String descriptor) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700457 out.indent();
458 // XXX what about potential superClasses?
459 out << "if (kInterfaceName.equals(descriptor)) {\n";
460 out.indent();
461 out << "return this;\n";
462 out.unindent();
463 out << "}\n";
464 out << "return null;\n";
465 out.unindent();
466 out << "}\n\n";
467
Yifan Hong320a3492017-03-27 10:33:09 -0700468 out << "public void registerAsService(String serviceName) throws android.os.RemoteException {\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700469 out.indent();
470
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100471 out << "registerService(serviceName);\n";
Andreas Huber2bb6e1e2016-10-25 13:26:43 -0700472
473 out.unindent();
474 out << "}\n\n";
475
Yifan Honge45b5302017-02-22 10:49:07 -0800476 out << "@Override\npublic String toString() ";
477 out.block([&] {
478 out << "return this.interfaceDescriptor() + \"@Stub\";\n";
479 }).endl().endl();
480
Yifan Hong084d11f2016-12-21 15:33:43 -0800481 out << "@Override\n"
482 << "public void onTransact("
Steven Moreland4b39bc12016-11-16 10:42:24 -0800483 << "int _hidl_code, "
484 << "android.os.HwParcel _hidl_request, "
485 << "final android.os.HwParcel _hidl_reply, "
Steven Morelanddad1b302016-12-20 15:56:00 -0800486 << "int _hidl_flags)\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700487 out.indent();
Steven Morelanddad1b302016-12-20 15:56:00 -0800488 out.indent();
Yifan Hong320a3492017-03-27 10:33:09 -0700489 out << "throws android.os.RemoteException {\n";
Steven Morelanddad1b302016-12-20 15:56:00 -0800490 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700491
Steven Moreland4b39bc12016-11-16 10:42:24 -0800492 out << "switch (_hidl_code) {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700493
494 out.indent();
495
Yifan Hong10fe0b52016-10-19 14:20:17 -0700496 for (const auto &tuple : iface->allMethodsFromRoot()) {
497 const Method *method = tuple.method();
Andreas Huber37065d62017-02-07 14:36:54 -0800498
Yifan Hong10fe0b52016-10-19 14:20:17 -0700499 const Interface *superInterface = tuple.interface();
500 const bool returnsValue = !method->results().empty();
501 const bool needsCallback = method->results().size() > 1;
Andreas Huber2831d512016-08-15 09:33:47 -0700502
Yifan Hong10fe0b52016-10-19 14:20:17 -0700503 out << "case "
504 << method->getSerialId()
505 << " /* "
506 << method->name()
507 << " */:\n{\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700508
Yifan Hong10fe0b52016-10-19 14:20:17 -0700509 out.indent();
Andreas Huber37065d62017-02-07 14:36:54 -0800510
Martijn Coenen115d4282016-12-19 05:14:04 +0100511 if (method->isHidlReserved() && method->overridesJavaImpl(IMPL_STUB)) {
512 method->javaImpl(IMPL_STUB, out);
513 out.unindent();
514 out << "break;\n";
515 out << "}\n\n";
516 continue;
517 }
Andreas Huber2831d512016-08-15 09:33:47 -0700518
Steven Moreland4b39bc12016-11-16 10:42:24 -0800519 out << "_hidl_request.enforceInterface("
Yifan Hong10fe0b52016-10-19 14:20:17 -0700520 << superInterface->fullJavaName()
521 << ".kInterfaceName);\n\n";
522
523 for (const auto &arg : method->args()) {
524 emitJavaReaderWriter(
525 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800526 "_hidl_request",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700527 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800528 true /* isReader */,
529 false /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700530 }
531
532 if (!needsCallback && returnsValue) {
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700533 const NamedReference<Type>* returnArg = method->results()[0];
Yifan Hong10fe0b52016-10-19 14:20:17 -0700534
Yifan Hong4ed13472016-11-02 10:44:11 -0700535 out << returnArg->type().getJavaType()
Yifan Honga47eef32016-12-12 10:38:54 -0800536 << " _hidl_out_"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700537 << returnArg->name()
538 << " = ";
539 }
540
541 out << method->name()
542 << "(";
543
544 bool firstField = true;
545 for (const auto &arg : method->args()) {
546 if (!firstField) {
547 out << ", ";
548 }
549
550 out << arg->name();
551
552 firstField = false;
553 }
554
555 if (needsCallback) {
556 if (!firstField) {
557 out << ", ";
558 }
559
560 out << "new " << method->name() << "Callback() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700561 out.indent();
562
Yifan Hong10fe0b52016-10-19 14:20:17 -0700563 out << "@Override\n"
Yifan Hong932464e2017-03-30 15:40:22 -0700564 << "public void onValues(";
565 method->emitJavaResultSignature(out);
566 out << ") {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700567
Yifan Hong10fe0b52016-10-19 14:20:17 -0700568 out.indent();
Steven Moreland4b39bc12016-11-16 10:42:24 -0800569 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700570
571 for (const auto &arg : method->results()) {
Andreas Huber2831d512016-08-15 09:33:47 -0700572 emitJavaReaderWriter(
573 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800574 "_hidl_reply",
Andreas Huber2831d512016-08-15 09:33:47 -0700575 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800576 false /* isReader */,
577 false /* addPrefixToName */);
578 // no need to add _hidl_out because out vars are are scoped
Andreas Huber2831d512016-08-15 09:33:47 -0700579 }
580
Steven Moreland4b39bc12016-11-16 10:42:24 -0800581 out << "_hidl_reply.send();\n"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700582 << "}}";
Andreas Huber2831d512016-08-15 09:33:47 -0700583
Andreas Huber2831d512016-08-15 09:33:47 -0700584 out.unindent();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700585 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700586 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700587
588 out << ");\n";
589
Martijn Coenen0bb0d412017-02-08 10:21:30 +0100590 if (!needsCallback && !method->isOneway()) {
Steven Moreland4b39bc12016-11-16 10:42:24 -0800591 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700592
593 if (returnsValue) {
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700594 const NamedReference<Type>* returnArg = method->results()[0];
Yifan Hong10fe0b52016-10-19 14:20:17 -0700595
596 emitJavaReaderWriter(
597 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800598 "_hidl_reply",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700599 returnArg,
Yifan Honga47eef32016-12-12 10:38:54 -0800600 false /* isReader */,
601 true /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700602 }
603
Steven Moreland4b39bc12016-11-16 10:42:24 -0800604 out << "_hidl_reply.send();\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700605 }
606
607 out << "break;\n";
608 out.unindent();
609 out << "}\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700610 }
611
612 out.unindent();
613 out << "}\n";
614
615 out.unindent();
616 out << "}\n";
617
618 out.unindent();
619 out << "}\n";
620
621 out.unindent();
622 out << "}\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700623}
624
Andreas Huber2831d512016-08-15 09:33:47 -0700625} // namespace android