blob: 577caf9ed97c89386a2df811d02ad77e92a97b49 [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()) {
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
Steven Moreland77943692018-08-09 12:53:42 -0700511 out << "boolean _hidl_is_oneway = (_hidl_flags & " << Interface::FLAG_ONE_WAY->javaValue()
512 << ") != 0;\n";
Steven Moreland7dfba102018-03-19 14:37:53 -0700513 out << "if (_hidl_is_oneway != " << (method->isOneway() ? "true" : "false") << ") ";
514 out.block([&] {
515 out << "_hidl_reply.writeStatus(" << UNKNOWN_ERROR << ");\n";
516 out << "_hidl_reply.send();\n";
517 out << "break;\n";
518 });
519
Martijn Coenen115d4282016-12-19 05:14:04 +0100520 if (method->isHidlReserved() && method->overridesJavaImpl(IMPL_STUB)) {
521 method->javaImpl(IMPL_STUB, out);
522 out.unindent();
523 out << "break;\n";
524 out << "}\n\n";
525 continue;
526 }
Andreas Huber2831d512016-08-15 09:33:47 -0700527
Steven Moreland4b39bc12016-11-16 10:42:24 -0800528 out << "_hidl_request.enforceInterface("
Yifan Hong10fe0b52016-10-19 14:20:17 -0700529 << superInterface->fullJavaName()
530 << ".kInterfaceName);\n\n";
531
532 for (const auto &arg : method->args()) {
533 emitJavaReaderWriter(
534 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800535 "_hidl_request",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700536 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800537 true /* isReader */,
538 false /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700539 }
540
541 if (!needsCallback && returnsValue) {
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700542 const NamedReference<Type>* returnArg = method->results()[0];
Yifan Hong10fe0b52016-10-19 14:20:17 -0700543
Yifan Hong4ed13472016-11-02 10:44:11 -0700544 out << returnArg->type().getJavaType()
Yifan Honga47eef32016-12-12 10:38:54 -0800545 << " _hidl_out_"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700546 << returnArg->name()
547 << " = ";
548 }
549
550 out << method->name()
551 << "(";
552
553 bool firstField = true;
554 for (const auto &arg : method->args()) {
555 if (!firstField) {
556 out << ", ";
557 }
558
559 out << arg->name();
560
561 firstField = false;
562 }
563
564 if (needsCallback) {
565 if (!firstField) {
566 out << ", ";
567 }
568
569 out << "new " << method->name() << "Callback() {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700570 out.indent();
571
Yifan Hong10fe0b52016-10-19 14:20:17 -0700572 out << "@Override\n"
Yifan Hong932464e2017-03-30 15:40:22 -0700573 << "public void onValues(";
574 method->emitJavaResultSignature(out);
575 out << ") {\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700576
Yifan Hong10fe0b52016-10-19 14:20:17 -0700577 out.indent();
Steven Moreland4b39bc12016-11-16 10:42:24 -0800578 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700579
580 for (const auto &arg : method->results()) {
Andreas Huber2831d512016-08-15 09:33:47 -0700581 emitJavaReaderWriter(
582 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800583 "_hidl_reply",
Andreas Huber2831d512016-08-15 09:33:47 -0700584 arg,
Yifan Honga47eef32016-12-12 10:38:54 -0800585 false /* isReader */,
586 false /* addPrefixToName */);
587 // no need to add _hidl_out because out vars are are scoped
Andreas Huber2831d512016-08-15 09:33:47 -0700588 }
589
Steven Moreland4b39bc12016-11-16 10:42:24 -0800590 out << "_hidl_reply.send();\n"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700591 << "}}";
Andreas Huber2831d512016-08-15 09:33:47 -0700592
Andreas Huber2831d512016-08-15 09:33:47 -0700593 out.unindent();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700594 out.unindent();
Andreas Huber2831d512016-08-15 09:33:47 -0700595 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700596
597 out << ");\n";
598
Martijn Coenen0bb0d412017-02-08 10:21:30 +0100599 if (!needsCallback && !method->isOneway()) {
Steven Moreland4b39bc12016-11-16 10:42:24 -0800600 out << "_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700601
602 if (returnsValue) {
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700603 const NamedReference<Type>* returnArg = method->results()[0];
Yifan Hong10fe0b52016-10-19 14:20:17 -0700604
605 emitJavaReaderWriter(
606 out,
Steven Moreland4b39bc12016-11-16 10:42:24 -0800607 "_hidl_reply",
Yifan Hong10fe0b52016-10-19 14:20:17 -0700608 returnArg,
Yifan Honga47eef32016-12-12 10:38:54 -0800609 false /* isReader */,
610 true /* addPrefixToName */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700611 }
612
Steven Moreland4b39bc12016-11-16 10:42:24 -0800613 out << "_hidl_reply.send();\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700614 }
615
616 out << "break;\n";
617 out.unindent();
618 out << "}\n\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700619 }
620
621 out.unindent();
622 out << "}\n";
623
624 out.unindent();
625 out << "}\n";
626
627 out.unindent();
628 out << "}\n";
629
630 out.unindent();
631 out << "}\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700632}
633
Andreas Huber2831d512016-08-15 09:33:47 -0700634} // namespace android