blob: 2e381ecd12585aa3a23901c03a83a5f23ce4d31d [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 Huber881227d2016-08-02 14:20:21 -070017#include "AST.h"
18
19#include "Coordinator.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070020#include "EnumType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070021#include "Interface.h"
22#include "Method.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070023#include "ScalarType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070024#include "Scope.h"
25
Andreas Huberdca261f2016-08-04 13:47:51 -070026#include <algorithm>
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070027#include <hidl-util/Formatter.h>
Andreas Huber881227d2016-08-02 14:20:21 -070028#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070029#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070030#include <vector>
31
32namespace android {
33
Andreas Huberb82318c2016-08-02 14:45:54 -070034status_t AST::generateCpp(const std::string &outputPath) const {
35 status_t err = generateInterfaceHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070036
37 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070038 err = generateStubHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070039 }
40
41 if (err == OK) {
Steven Moreland40786312016-08-16 10:29:40 -070042 err = generateHwBinderHeader(outputPath);
43 }
44
45 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070046 err = generateProxyHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070047 }
48
49 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070050 err = generateAllSource(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070051 }
52
Steven Moreland69e7c702016-09-09 11:16:32 -070053 if (err == OK) {
54 generatePassthroughHeader(outputPath);
55 }
56
Andreas Huber881227d2016-08-02 14:20:21 -070057 return err;
58}
59
Andreas Huber737080b2016-08-02 15:38:04 -070060void AST::getPackageComponents(
61 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070062 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070063}
64
65void AST::getPackageAndVersionComponents(
66 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070067 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070068}
69
Andreas Huber881227d2016-08-02 14:20:21 -070070std::string AST::makeHeaderGuard(const std::string &baseName) const {
Steven Moreland9c387612016-09-07 09:54:26 -070071 std::string guard = "HIDL_GENERATED_";
72 guard += mPackage.tokenName();
Andreas Huber881227d2016-08-02 14:20:21 -070073
74 guard += "_";
75 guard += baseName;
76 guard += "_H_";
77
78 return guard;
79}
80
81void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
82 std::vector<std::string> packageComponents;
83 getPackageAndVersionComponents(
84 &packageComponents, true /* cpp_compatible */);
85
86 if (enter) {
87 for (const auto &component : packageComponents) {
88 out << "namespace " << component << " {\n";
89 }
Andreas Huber0e00de42016-08-03 09:56:02 -070090
Andreas Huber2831d512016-08-15 09:33:47 -070091 out.setNamespace(mPackage.cppNamespace() + "::");
Andreas Huber881227d2016-08-02 14:20:21 -070092 } else {
Andreas Huber0e00de42016-08-03 09:56:02 -070093 out.setNamespace(std::string());
94
Andreas Huber881227d2016-08-02 14:20:21 -070095 for (auto it = packageComponents.rbegin();
96 it != packageComponents.rend();
97 ++it) {
98 out << "} // namespace " << *it << "\n";
99 }
100 }
101}
102
Andreas Huberb82318c2016-08-02 14:45:54 -0700103status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700104
Andreas Huberb82318c2016-08-02 14:45:54 -0700105 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700106 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700107 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700108
109 std::string ifaceName;
110 bool isInterface = true;
111 if (!AST::isInterface(&ifaceName)) {
112 ifaceName = "types";
113 isInterface = false;
114 }
115 path.append(ifaceName);
116 path.append(".h");
117
Andreas Huberd2943e12016-08-05 11:59:31 -0700118 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700119 FILE *file = fopen(path.c_str(), "w");
120
121 if (file == NULL) {
122 return -errno;
123 }
124
125 Formatter out(file);
126
127 const std::string guard = makeHeaderGuard(ifaceName);
128
129 out << "#ifndef " << guard << "\n";
130 out << "#define " << guard << "\n\n";
131
Andreas Huber737080b2016-08-02 15:38:04 -0700132 for (const auto &item : mImportedNames) {
133 out << "#include <";
134
135 std::vector<std::string> components;
Andreas Huber0e00de42016-08-03 09:56:02 -0700136 item.getPackageAndVersionComponents(
137 &components, false /* cpp_compatible */);
Andreas Huber737080b2016-08-02 15:38:04 -0700138
139 for (const auto &component : components) {
140 out << component << "/";
141 }
142
143 out << item.name()
144 << ".h>\n";
145 }
146
147 if (!mImportedNames.empty()) {
148 out << "\n";
149 }
150
Martijn Coenen7473fab2016-08-19 14:05:40 +0200151 out << "#include <hidl/HidlSupport.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700152 out << "#include <hidl/IServiceManager.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700153 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700154
155 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200156 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700157 }
158
159 out << "#include <utils/NativeHandle.h>\n\n";
160
161 enterLeaveNamespace(out, true /* enter */);
162 out << "\n";
163
164 if (isInterface) {
165 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700166 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700167
168 const Interface *iface = mRootScope->getInterface();
169 const Interface *superType = iface->superType();
170
Steven Moreland40786312016-08-16 10:29:40 -0700171 if (superType == NULL) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700172 out << " : virtual public IHidlInterfaceBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700173 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000174 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700175 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700176 }
177
178 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700179
180 out.indent();
181
Andreas Huber881227d2016-08-02 14:20:21 -0700182 }
183
184 status_t err = emitTypeDeclarations(out);
185
186 if (err != OK) {
187 return err;
188 }
189
190 if (isInterface) {
191 const Interface *iface = mRootScope->getInterface();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700192 const Interface *superType = iface->superType();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700193 const std::string baseName = iface->getBaseName();
Martijn Coenena21f1492016-09-08 15:55:14 +0200194 out << "constexpr static hidl_version version = {"
195 << mPackage.getPackageMajorVersion() << ","
196 << mPackage.getPackageMinorVersion() << "};\n";
197 out << "virtual const hidl_version& getInterfaceVersion() const {\n";
198 out.indent();
199 out << "return version;\n";
200 out.unindent();
201 out << "}\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700202 out << "virtual bool isRemote() const override { return false; }\n\n";
Yifan Hong2d7126b2016-10-20 15:12:57 -0700203 out << "virtual ::android::sp<::android::hardware::IBinder> "
204 << "toBinder() override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700205 bool haveCallbacks = false;
206 for (const auto &method : iface->methods()) {
207 const bool returnsValue = !method->results().empty();
208
209 if (!returnsValue) {
210 continue;
211 }
212
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700213 if (method->canElideCallback() != nullptr) {
214 continue;
215 }
216
Andreas Huber881227d2016-08-02 14:20:21 -0700217 haveCallbacks = true;
218
219 out << "using "
220 << method->name()
221 << "_cb = std::function<void("
Steven Moreland979e0992016-09-07 09:18:08 -0700222 << Method::GetArgSignature(method->results(),
223 true /* specify namespaces */)
Andreas Huber881227d2016-08-02 14:20:21 -0700224 << ")>;\n";
225 }
226
227 if (haveCallbacks) {
228 out << "\n";
229 }
230
231 for (const auto &method : iface->methods()) {
232 const bool returnsValue = !method->results().empty();
233
Andreas Huber3599d922016-08-09 10:42:57 -0700234 method->dumpAnnotations(out);
235
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700236 const TypedVar *elidedReturn = method->canElideCallback();
237 if (elidedReturn) {
238 std::string extra;
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700239 out << "virtual ::android::hardware::Return<";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700240 out << elidedReturn->type().getCppResultType(&extra) << "> ";
241 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700242 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700243 }
244
245 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700246 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700247 << Method::GetArgSignature(method->args(),
248 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700249
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700250 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700251 if (!method->args().empty()) {
252 out << ", ";
253 }
254
Steven Moreland67f67b42016-09-29 08:59:02 -0700255 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700256 }
257
Yifan Hong10fe0b52016-10-19 14:20:17 -0700258 out << ")";
259 if (method->isHidlReserved()) {
260 out << " override";
261 out << " {\n";
262 out.indent();
263 method->cppImpl(out);
264 out.unindent();
265 out << "\n}\n";
266 } else {
267 out << " = 0;\n";
268 }
Andreas Huber881227d2016-08-02 14:20:21 -0700269 }
Steven Moreland40786312016-08-16 10:29:40 -0700270
Yifan Hongfe95aa22016-10-19 17:26:45 -0700271 if (!iface->isRootType()) {
272 out << "// cast static functions\n";
273 std::string childTypeExtra;
274 std::string childTypeResult = iface->getCppResultType(&childTypeExtra);
275 childTypeResult += childTypeExtra;
276
277 for (const Interface *superType : iface->superTypeChain()) {
278 std::string superTypeExtra;
279 out << "static "
280 << childTypeResult
281 << " castFrom("
282 << superType->getCppArgumentType(&superTypeExtra)
283 << " parent"
284 << superTypeExtra
285 << ");\n";
286 }
287 }
288
Yifan Hong10fe0b52016-10-19 14:20:17 -0700289 out << "\nstatic const ::android::String16 descriptor;\n\n";
290
Steven Moreland40786312016-08-16 10:29:40 -0700291 out << "DECLARE_REGISTER_AND_GET_SERVICE(" << baseName << ")\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700292 }
293
294 if (isInterface) {
295 out.unindent();
296
Andreas Hubere3f769a2016-10-10 10:54:44 -0700297 out << "};\n\n";
298 }
299
300 err = mRootScope->emitGlobalTypeDeclarations(out);
301
302 if (err != OK) {
303 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700304 }
305
306 out << "\n";
307 enterLeaveNamespace(out, false /* enter */);
308
309 out << "\n#endif // " << guard << "\n";
310
311 return OK;
312}
313
Steven Moreland40786312016-08-16 10:29:40 -0700314status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
315 std::string ifaceName;
316 if(!AST::isInterface(&ifaceName)) {
317 // types.hal does not get an HwBinder header.
318 return OK;
319 }
320
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700321 const Interface *iface = mRootScope->getInterface();
322 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700323
324 const std::string klassName = "IHw" + baseName;
325
326 std::string path = outputPath;
327 path.append(mCoordinator->convertPackageRootToPath(mPackage));
328 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
329 path.append(klassName + ".h");
330
331 FILE* file = fopen(path.c_str(), "w");
332
333 if (file == NULL) {
334 return -errno;
335 }
336
337 Formatter out(file);
338
339 const std::string guard = makeHeaderGuard(klassName);
340
341 out << "#ifndef " << guard << "\n";
342 out << "#define " << guard << "\n\n";
343
344 std::vector<std::string> packageComponents;
345 getPackageAndVersionComponents(
346 &packageComponents, false /* cpp_compatible */);
347
348 out << "#include <";
349 for (const auto &component : packageComponents) {
350 out << component << "/";
351 }
352 out << ifaceName << ".h>\n\n";
353
354 for (const auto &item : mImportedNames) {
355 if (item.name() == "types") {
356 continue;
357 }
358
359 out << "#include <";
360
361 std::vector<std::string> components;
362 item.getPackageAndVersionComponents(
363 &components, false /* cpp_compatible */);
364
365 for (const auto &component : components) {
366 out << component << "/";
367 }
368
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700369 const std::string itemBaseName = item.getInterfaceBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700370
371 out << "Bn"
372 << itemBaseName
373 << ".h>\n";
374 }
375
376 out << "\n";
377
378 out << "#include <hidl/HidlSupport.h>\n";
Martijn Coenen93915102016-09-01 01:35:52 +0200379 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700380 out << "#include <hwbinder/IBinder.h>\n";
381 out << "#include <hwbinder/IInterface.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700382
383 out << "\n";
384
385 enterLeaveNamespace(out, true /* enter */);
386 out << "\n";
387
388 out << "struct "
389 << klassName
390 << " : public "
391 << ifaceName;
392
Steven Moreland40786312016-08-16 10:29:40 -0700393 const Interface *superType = iface->superType();
394
395 out << ", public ::android::hardware::IInterface";
396
397 out << " {\n";
398
399 out.indent();
400
401 out << "DECLARE_HWBINDER_META_INTERFACE(" << baseName << ");\n\n";
402
Steven Moreland40786312016-08-16 10:29:40 -0700403 out.unindent();
404
405 out << "};\n\n";
406
407 enterLeaveNamespace(out, false /* enter */);
408
409 out << "\n#endif // " << guard << "\n";
410
411 return OK;
412}
413
Andreas Huber881227d2016-08-02 14:20:21 -0700414status_t AST::emitTypeDeclarations(Formatter &out) const {
415 return mRootScope->emitTypeDeclarations(out);
416}
417
Steven Morelanda7a421a2016-09-07 08:35:18 -0700418status_t AST::generateStubMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700419 const Method *method) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700420 out << "inline ";
421
Yifan Hong068c5522016-10-31 14:07:25 -0700422 method->generateCppSignature(out);
Steven Morelanda7a421a2016-09-07 08:35:18 -0700423
424 const bool returnsValue = !method->results().empty();
425 const TypedVar *elidedReturn = method->canElideCallback();
426 out << " {\n";
427 out.indent();
428 out << "return mImpl->"
429 << method->name()
430 << "(";
431 bool first = true;
432 for (const auto &arg : method->args()) {
433 if (!first) {
434 out << ", ";
435 }
436 first = false;
437 out << arg->name();
438 }
439 if (returnsValue && elidedReturn == nullptr) {
440 if (!method->args().empty()) {
441 out << ", ";
442 }
443
444 out << "_hidl_cb";
445 }
446 out << ");\n";
447 out.unindent();
448 out << "}";
449
450 out << ";\n";
451
452 return OK;
453}
454
Steven Moreland69e7c702016-09-09 11:16:32 -0700455status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700456 const Method *method) const {
457 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700458
459 out << " {\n";
460 out.indent();
461
462 const bool returnsValue = !method->results().empty();
463 const TypedVar *elidedReturn = method->canElideCallback();
464
Steven Moreland67f67b42016-09-29 08:59:02 -0700465 if (returnsValue && elidedReturn == nullptr) {
466 generateCheckNonNull(out, "_hidl_cb");
467 }
468
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700469 generateCppInstrumentationCall(
470 out,
471 InstrumentationEvent::PASSTHROUGH_ENTRY,
472 method);
473
474 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700475
476 if (method->isOneway()) {
477 out << "addOnewayTask([this";
478 for (const auto &arg : method->args()) {
479 out << ", " << arg->name();
480 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700481 out << "] {\n";
482 out.indent();
483 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700484 }
485
486 out << "mImpl->"
487 << method->name()
488 << "(";
489
490 bool first = true;
491 for (const auto &arg : method->args()) {
492 if (!first) {
493 out << ", ";
494 }
495 first = false;
496 out << arg->name();
497 }
498 if (returnsValue && elidedReturn == nullptr) {
499 if (!method->args().empty()) {
500 out << ", ";
501 }
502
503 out << "_hidl_cb";
504 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700505 out << ");\n\n";
506
507 generateCppInstrumentationCall(
508 out,
509 InstrumentationEvent::PASSTHROUGH_EXIT,
510 method);
Steven Moreland69e7c702016-09-09 11:16:32 -0700511
512 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700513 out.unindent();
514 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700515 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700516
517 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700518
519 out.unindent();
520 out << "}\n";
521
522 return OK;
523}
524
Yifan Hong068c5522016-10-31 14:07:25 -0700525status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700526
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700527 const Interface *iface = mRootScope->getInterface();
528
Yifan Hong10fe0b52016-10-19 14:20:17 -0700529 const Interface *prevIterface = nullptr;
530 for (const auto &tuple : iface->allMethodsFromRoot()) {
531 const Method *method = tuple.method();
532 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700533
Yifan Hong10fe0b52016-10-19 14:20:17 -0700534 if(prevIterface != superInterface) {
535 if (prevIterface != nullptr) {
536 out << "\n";
537 }
538 out << "// Methods from "
539 << superInterface->fullName()
540 << " follow.\n";
541 prevIterface = superInterface;
542 }
Yifan Hong068c5522016-10-31 14:07:25 -0700543 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700544
Yifan Hong10fe0b52016-10-19 14:20:17 -0700545 if (err != OK) {
546 return err;
547 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700548 }
549
Yifan Hong10fe0b52016-10-19 14:20:17 -0700550 out << "\n";
551
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700552 return OK;
553}
554
Andreas Huberb82318c2016-08-02 14:45:54 -0700555status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700556 std::string ifaceName;
557 if (!AST::isInterface(&ifaceName)) {
558 // types.hal does not get a stub header.
559 return OK;
560 }
561
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700562 const Interface *iface = mRootScope->getInterface();
563 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700564 const std::string klassName = "Bn" + baseName;
Andreas Huber881227d2016-08-02 14:20:21 -0700565
Andreas Huberb82318c2016-08-02 14:45:54 -0700566 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700567 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700568 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700569 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700570 path.append(".h");
571
Andreas Huberd2943e12016-08-05 11:59:31 -0700572 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700573 FILE *file = fopen(path.c_str(), "w");
574
575 if (file == NULL) {
576 return -errno;
577 }
578
579 Formatter out(file);
580
Steven Moreland40786312016-08-16 10:29:40 -0700581 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700582
583 out << "#ifndef " << guard << "\n";
584 out << "#define " << guard << "\n\n";
585
586 std::vector<std::string> packageComponents;
587 getPackageAndVersionComponents(
588 &packageComponents, false /* cpp_compatible */);
589
590 out << "#include <";
591 for (const auto &component : packageComponents) {
592 out << component << "/";
593 }
Steven Moreland40786312016-08-16 10:29:40 -0700594 out << "IHw" << baseName << ".h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700595
596 enterLeaveNamespace(out, true /* enter */);
597 out << "\n";
598
599 out << "struct "
600 << "Bn"
601 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700602 << " : public ::android::hardware::BnInterface<I"
603 << baseName << ", IHw" << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700604 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700605
606 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700607 out << "explicit Bn"
608 << baseName
609 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
610 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700611 out << "::android::status_t onTransact(\n";
612 out.indent();
613 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700614 out << "uint32_t _hidl_code,\n";
615 out << "const ::android::hardware::Parcel &_hidl_data,\n";
616 out << "::android::hardware::Parcel *_hidl_reply,\n";
617 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700618 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700619 out.unindent();
620 out.unindent();
621
Yifan Hong068c5522016-10-31 14:07:25 -0700622 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
623 return generateStubMethod(out, method);
624 });
Steven Moreland9c387612016-09-07 09:54:26 -0700625
626 if (err != OK) {
627 return err;
628 }
629
Zhuoyao Zhangde578002016-09-07 18:24:17 -0700630
Andreas Huber881227d2016-08-02 14:20:21 -0700631 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700632 out << "};\n\n";
633
634 enterLeaveNamespace(out, false /* enter */);
635
636 out << "\n#endif // " << guard << "\n";
637
638 return OK;
639}
640
Andreas Huberb82318c2016-08-02 14:45:54 -0700641status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700642 std::string ifaceName;
643 if (!AST::isInterface(&ifaceName)) {
644 // types.hal does not get a proxy header.
645 return OK;
646 }
647
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700648 const Interface *iface = mRootScope->getInterface();
649 const std::string baseName = iface->getBaseName();
Andreas Huber881227d2016-08-02 14:20:21 -0700650
Andreas Huberb82318c2016-08-02 14:45:54 -0700651 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700652 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700653 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700654 path.append("Bp");
655 path.append(baseName);
656 path.append(".h");
657
Andreas Huberd2943e12016-08-05 11:59:31 -0700658 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700659 FILE *file = fopen(path.c_str(), "w");
660
661 if (file == NULL) {
662 return -errno;
663 }
664
665 Formatter out(file);
666
667 const std::string guard = makeHeaderGuard("Bp" + baseName);
668
669 out << "#ifndef " << guard << "\n";
670 out << "#define " << guard << "\n\n";
671
672 std::vector<std::string> packageComponents;
673 getPackageAndVersionComponents(
674 &packageComponents, false /* cpp_compatible */);
675
676 out << "#include <";
677 for (const auto &component : packageComponents) {
678 out << component << "/";
679 }
Steven Moreland40786312016-08-16 10:29:40 -0700680 out << "IHw" << baseName << ".h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700681
682 enterLeaveNamespace(out, true /* enter */);
683 out << "\n";
684
685 out << "struct "
686 << "Bp"
687 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700688 << " : public ::android::hardware::BpInterface<IHw"
689 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700690 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700691
692 out.indent();
693
694 out << "explicit Bp"
695 << baseName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700696 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700697 << "\n\n";
698
Yifan Hong10fe0b52016-10-19 14:20:17 -0700699 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700700
Yifan Hong068c5522016-10-31 14:07:25 -0700701 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
702 method->generateCppSignature(out);
703 out << " override;\n";
704 return OK;
705 });
Steven Moreland9c387612016-09-07 09:54:26 -0700706
707 if (err != OK) {
708 return err;
709 }
Andreas Huber881227d2016-08-02 14:20:21 -0700710
711 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700712 out << "};\n\n";
713
714 enterLeaveNamespace(out, false /* enter */);
715
716 out << "\n#endif // " << guard << "\n";
717
718 return OK;
719}
720
Andreas Huberb82318c2016-08-02 14:45:54 -0700721status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700722
Andreas Huberb82318c2016-08-02 14:45:54 -0700723 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700724 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700725 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700726
727 std::string ifaceName;
728 std::string baseName;
729
Yifan Hongfe95aa22016-10-19 17:26:45 -0700730 const Interface *iface = nullptr;
731 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700732 if (!AST::isInterface(&ifaceName)) {
733 baseName = "types";
734 isInterface = false;
735 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700736 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700737 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700738 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700739 }
740
741 path.append(baseName);
742
743 if (baseName != "types") {
744 path.append("All");
745 }
746
747 path.append(".cpp");
748
Andreas Huberd2943e12016-08-05 11:59:31 -0700749 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700750 FILE *file = fopen(path.c_str(), "w");
751
752 if (file == NULL) {
753 return -errno;
754 }
755
756 Formatter out(file);
757
758 std::vector<std::string> packageComponents;
759 getPackageAndVersionComponents(
760 &packageComponents, false /* cpp_compatible */);
761
762 std::string prefix;
763 for (const auto &component : packageComponents) {
764 prefix += component;
765 prefix += "/";
766 }
767
768 if (isInterface) {
769 out << "#include <" << prefix << "/Bp" << baseName << ".h>\n";
770 out << "#include <" << prefix << "/Bn" << baseName << ".h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700771 out << "#include <" << prefix << "/Bs" << baseName << ".h>\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700772
773 for (const Interface *superType : iface->superTypeChain()) {
774 std::vector<std::string> superPackageComponents;
775 superType->fqName().getPackageAndVersionComponents(&superPackageComponents, false /* cpp_compatible */);
776 std::string superPrefix;
777 for (const auto &component : superPackageComponents) {
778 superPrefix += component;
779 superPrefix += "/";
780 }
781 out << "#include <" << superPrefix << "/Bp" << superType->getBaseName() << ".h>\n";
782 }
Andreas Huber881227d2016-08-02 14:20:21 -0700783 } else {
784 out << "#include <" << prefix << "types.h>\n";
785 }
786
787 out << "\n";
788
789 enterLeaveNamespace(out, true /* enter */);
790 out << "\n";
791
792 status_t err = generateTypeSource(out, ifaceName);
793
794 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700795 const Interface *iface = mRootScope->getInterface();
Martijn Coenena21f1492016-09-08 15:55:14 +0200796 out << "constexpr hidl_version " << ifaceName << "::version;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700797
798 // need to be put here, generateStubSource is using this.
799 out << "const ::android::String16 I"
800 << iface->getBaseName()
801 << "::descriptor(\""
802 << iface->fqName().string()
803 << "\");\n\n";
804
Yifan Hongfe95aa22016-10-19 17:26:45 -0700805 err = generateInterfaceSource(out);
806 }
807
808 if (err == OK && isInterface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700809 err = generateProxySource(out, baseName);
810 }
811
812 if (err == OK && isInterface) {
813 err = generateStubSource(out, baseName);
814 }
815
Steven Moreland40786312016-08-16 10:29:40 -0700816 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -0700817 err = generatePassthroughSource(out);
818 }
819
820 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -0700821 const Interface *iface = mRootScope->getInterface();
822
823 out << "IMPLEMENT_REGISTER_AND_GET_SERVICE("
824 << baseName << ", "
825 << "\"" << iface->fqName().package()
Iliyan Malchev4923f932016-09-09 13:04:59 -0700826 << iface->fqName().version() << "-impl.so\""
Steven Moreland9c387612016-09-07 09:54:26 -0700827 << ")\n";
Steven Moreland40786312016-08-16 10:29:40 -0700828 }
829
Andreas Huber881227d2016-08-02 14:20:21 -0700830 enterLeaveNamespace(out, false /* enter */);
831
832 return err;
833}
834
Steven Moreland67f67b42016-09-29 08:59:02 -0700835// static
836void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
837 out << "if (" << nonNull << " == nullptr) {\n";
838 out.indent();
839 out << "return ::android::hardware::Status::fromExceptionCode(\n";
840 out.indent();
841 out.indent();
842 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
843 out.unindent();
844 out.unindent();
845 out.unindent();
846 out << "}\n\n";
847}
848
Andreas Huber881227d2016-08-02 14:20:21 -0700849status_t AST::generateTypeSource(
850 Formatter &out, const std::string &ifaceName) const {
851 return mRootScope->emitTypeDefinitions(out, ifaceName);
852}
853
Andreas Hubere7ff2282016-08-16 13:50:03 -0700854void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -0700855 Formatter &out,
856 const std::vector<TypedVar *> &args,
857 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700858 if (args.empty()) {
859 return;
860 }
861
862 for (const auto &arg : args) {
863 const Type &type = arg->type();
864
865 std::string extra;
866 out << type.getCppResultType(&extra)
867 << " "
Andreas Huber5e44a292016-09-27 14:52:39 -0700868 << (forResults ? "_hidl_out_" : "")
Andreas Hubere7ff2282016-08-16 13:50:03 -0700869 << arg->name()
870 << extra
871 << ";\n";
872 }
873
874 out << "\n";
875}
876
Andreas Huber881227d2016-08-02 14:20:21 -0700877void AST::emitCppReaderWriter(
878 Formatter &out,
879 const std::string &parcelObj,
880 bool parcelObjIsPointer,
881 const TypedVar *arg,
882 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -0700883 Type::ErrorMode mode,
884 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700885 const Type &type = arg->type();
886
Andreas Huber881227d2016-08-02 14:20:21 -0700887 type.emitReaderWriter(
888 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700889 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700890 parcelObj,
891 parcelObjIsPointer,
892 isReader,
893 mode);
894}
895
Yifan Hongbf459bc2016-08-23 16:50:37 -0700896void AST::emitCppResolveReferences(
897 Formatter &out,
898 const std::string &parcelObj,
899 bool parcelObjIsPointer,
900 const TypedVar *arg,
901 bool isReader,
902 Type::ErrorMode mode,
903 bool addPrefixToName) const {
904 const Type &type = arg->type();
905 if(type.needsResolveReferences()) {
906 type.emitResolveReferences(
907 out,
908 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
909 isReader, // nameIsPointer
910 parcelObj,
911 parcelObjIsPointer,
912 isReader,
913 mode);
914 }
915}
916
Yifan Hong068c5522016-10-31 14:07:25 -0700917status_t AST::generateProxyMethodSource(Formatter &out,
918 const std::string &klassName,
919 const Method *method,
920 const Interface *superInterface) const {
921
922 method->generateCppSignature(out,
923 klassName,
924 true /* specify namespaces */);
925
926 const bool returnsValue = !method->results().empty();
927 const TypedVar *elidedReturn = method->canElideCallback();
928
929 out << "{\n";
930
931 out.indent();
932
933 if (returnsValue && elidedReturn == nullptr) {
934 generateCheckNonNull(out, "_hidl_cb");
935 }
936
937 status_t status = generateCppInstrumentationCall(
938 out,
939 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -0700940 method);
941 if (status != OK) {
942 return status;
943 }
944
945 out << "::android::hardware::Parcel _hidl_data;\n";
946 out << "::android::hardware::Parcel _hidl_reply;\n";
947 out << "::android::status_t _hidl_err;\n";
948 out << "::android::hardware::Status _hidl_status;\n\n";
949
950 declareCppReaderLocals(
951 out, method->results(), true /* forResults */);
952
953 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
954 if (!method->isHidlReserved()) {
955 out << superInterface->fqName().cppNamespace()
956 << "::IHw"
957 << superInterface->getBaseName();
958 } else {
959 out << "::android::hardware::IHidlInterfaceBase";
960 }
961 out << "::descriptor);\n";
962
963 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
964
965 // First DFS: write all buffers and resolve pointers for parent
966 for (const auto &arg : method->args()) {
967 emitCppReaderWriter(
968 out,
969 "_hidl_data",
970 false /* parcelObjIsPointer */,
971 arg,
972 false /* reader */,
973 Type::ErrorMode_Goto,
974 false /* addPrefixToName */);
975 }
976
977 // Second DFS: resolve references.
978 for (const auto &arg : method->args()) {
979 emitCppResolveReferences(
980 out,
981 "_hidl_data",
982 false /* parcelObjIsPointer */,
983 arg,
984 false /* reader */,
985 Type::ErrorMode_Goto,
986 false /* addPrefixToName */);
987 }
988
989 out << "_hidl_err = remote()->transact("
990 << method->getSerialId()
991 << " /* "
992 << method->name()
993 << " */, _hidl_data, &_hidl_reply";
994
995 if (method->isOneway()) {
996 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
997 }
998 out << ");\n";
999
1000 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1001
1002 if (!method->isOneway()) {
1003 out << "_hidl_err = _hidl_status.readFromParcel(_hidl_reply);\n";
1004 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1005 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1006
1007
1008 // First DFS: write all buffers and resolve pointers for parent
1009 for (const auto &arg : method->results()) {
1010 emitCppReaderWriter(
1011 out,
1012 "_hidl_reply",
1013 false /* parcelObjIsPointer */,
1014 arg,
1015 true /* reader */,
1016 Type::ErrorMode_Goto,
1017 true /* addPrefixToName */);
1018 }
1019
1020 // Second DFS: resolve references.
1021 for (const auto &arg : method->results()) {
1022 emitCppResolveReferences(
1023 out,
1024 "_hidl_reply",
1025 false /* parcelObjIsPointer */,
1026 arg,
1027 true /* reader */,
1028 Type::ErrorMode_Goto,
1029 true /* addPrefixToName */);
1030 }
1031
1032 if (returnsValue && elidedReturn == nullptr) {
1033 out << "_hidl_cb(";
1034
1035 bool first = true;
1036 for (const auto &arg : method->results()) {
1037 if (!first) {
1038 out << ", ";
1039 }
1040
1041 if (arg->type().resultNeedsDeref()) {
1042 out << "*";
1043 }
1044 out << "_hidl_out_" << arg->name();
1045
1046 first = false;
1047 }
1048
1049 out << ");\n\n";
1050 }
1051 status_t status = generateCppInstrumentationCall(
1052 out,
1053 InstrumentationEvent::CLIENT_API_EXIT,
Yifan Hong068c5522016-10-31 14:07:25 -07001054 method);
1055 if (status != OK) {
1056 return status;
1057 }
1058 }
1059
1060 if (elidedReturn != nullptr) {
1061 std::string extra;
1062 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1063 out << "return ::android::hardware::Return<";
1064 out << elidedReturn->type().getCppResultType(&extra)
1065 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1066 } else {
1067 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1068 out << "return ::android::hardware::Return<void>();\n\n";
1069 }
1070
1071 out.unindent();
1072 out << "_hidl_error:\n";
1073 out.indent();
1074 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1075 out << "return ::android::hardware::Return<";
1076 if (elidedReturn != nullptr) {
1077 std::string extra;
1078 out << method->results().at(0)->type().getCppResultType(&extra);
1079 } else {
1080 out << "void";
1081 }
1082 out << ">(_hidl_status);\n";
1083
1084 out.unindent();
1085 out << "}\n\n";
1086 return OK;
1087}
1088
Andreas Huber881227d2016-08-02 14:20:21 -07001089status_t AST::generateProxySource(
1090 Formatter &out, const std::string &baseName) const {
1091 const std::string klassName = "Bp" + baseName;
1092
1093 out << klassName
1094 << "::"
1095 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001096 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001097
1098 out.indent();
1099 out.indent();
1100
1101 out << ": BpInterface"
Steven Moreland40786312016-08-16 10:29:40 -07001102 << "<IHw"
Andreas Huber881227d2016-08-02 14:20:21 -07001103 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001104 << ">(_hidl_impl),\n"
1105 << " HidlInstrumentor(\""
1106 << mPackage.string()
1107 << "::I"
1108 << baseName
1109 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001110
Andreas Huber881227d2016-08-02 14:20:21 -07001111 out.unindent();
1112 out.unindent();
1113 out << "}\n\n";
1114
Yifan Hong068c5522016-10-31 14:07:25 -07001115 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1116 return generateProxyMethodSource(out, klassName, method, superInterface);
1117 });
Andreas Huber881227d2016-08-02 14:20:21 -07001118
Yifan Hong068c5522016-10-31 14:07:25 -07001119 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001120}
1121
1122status_t AST::generateStubSource(
1123 Formatter &out, const std::string &baseName) const {
1124 out << "IMPLEMENT_HWBINDER_META_INTERFACE("
1125 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001126 << ", "
1127 << mPackage.cppNamespace()
Andreas Huber881227d2016-08-02 14:20:21 -07001128 << "::I"
1129 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001130 << "::descriptor);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001131
1132 const std::string klassName = "Bn" + baseName;
1133
Steven Moreland40786312016-08-16 10:29:40 -07001134 out << klassName
1135 << "::"
1136 << klassName
1137 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl)\n";
1138
1139 out.indent();
1140 out.indent();
1141
1142 out << ": BnInterface"
1143 << "<I"
1144 << baseName
1145 << ", IHw"
1146 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001147 << ">(_hidl_impl),\n"
1148 << " HidlInstrumentor(\""
1149 << mPackage.string()
1150 << "::I"
1151 << baseName
1152 << "\") {\n";
Steven Moreland40786312016-08-16 10:29:40 -07001153
1154 out.unindent();
1155 out.unindent();
1156 out << "}\n\n";
1157
Andreas Huber881227d2016-08-02 14:20:21 -07001158 out << "::android::status_t " << klassName << "::onTransact(\n";
1159
1160 out.indent();
1161 out.indent();
1162
Iliyan Malchev549e2592016-08-10 08:59:12 -07001163 out << "uint32_t _hidl_code,\n"
1164 << "const ::android::hardware::Parcel &_hidl_data,\n"
1165 << "::android::hardware::Parcel *_hidl_reply,\n"
1166 << "uint32_t _hidl_flags,\n"
1167 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001168
1169 out.unindent();
1170
Iliyan Malchev549e2592016-08-10 08:59:12 -07001171 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001172 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001173 out.indent();
1174
1175 const Interface *iface = mRootScope->getInterface();
1176
Yifan Hong10fe0b52016-10-19 14:20:17 -07001177 for (const auto &tuple : iface->allMethodsFromRoot()) {
1178 const Method *method = tuple.method();
1179 const Interface *superInterface = tuple.interface();
1180 out << "case "
1181 << method->getSerialId()
1182 << " /* "
1183 << method->name()
1184 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001185
Yifan Hong10fe0b52016-10-19 14:20:17 -07001186 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001187
Yifan Hong10fe0b52016-10-19 14:20:17 -07001188 status_t err =
1189 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001190
Yifan Hong10fe0b52016-10-19 14:20:17 -07001191 if (err != OK) {
1192 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001193 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001194
1195 out.unindent();
1196 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001197 }
1198
1199 out << "default:\n{\n";
1200 out.indent();
1201
Andreas Huber8a82ff72016-08-04 10:29:39 -07001202 out << "return ::android::hardware::BnInterface<I"
Steven Moreland40786312016-08-16 10:29:40 -07001203 << baseName << ", IHw" << baseName
Andreas Huber881227d2016-08-02 14:20:21 -07001204 << ">::onTransact(\n";
1205
1206 out.indent();
1207 out.indent();
1208
Iliyan Malchev549e2592016-08-10 08:59:12 -07001209 out << "_hidl_code, _hidl_data, _hidl_reply, "
1210 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001211
1212 out.unindent();
1213 out.unindent();
1214
1215 out.unindent();
1216 out << "}\n";
1217
1218 out.unindent();
1219 out << "}\n\n";
1220
Iliyan Malchev549e2592016-08-10 08:59:12 -07001221 out << "if (_hidl_err == ::android::UNEXPECTED_NULL) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001222 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001223 out << "_hidl_err = ::android::hardware::Status::fromExceptionCode(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001224 out.indent();
1225 out.indent();
Andreas Huber8a82ff72016-08-04 10:29:39 -07001226 out << "::android::hardware::Status::EX_NULL_POINTER)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001227 out.indent();
1228 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001229 out << ".writeToParcel(_hidl_reply);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001230 out.unindent();
1231 out.unindent();
1232 out.unindent();
1233 out.unindent();
1234
1235 out.unindent();
1236 out << "}\n\n";
1237
Iliyan Malchev549e2592016-08-10 08:59:12 -07001238 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001239
1240 out.unindent();
1241 out << "}\n\n";
1242
1243 return OK;
1244}
1245
1246status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001247 Formatter &out, const Interface *iface, const Method *method) const {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001248 out << "if (!_hidl_data.enforceInterface(";
1249
1250 if (!method->isHidlReserved()) {
1251 out << iface->fqName().cppNamespace()
1252 << "::IHw"
1253 << iface->getBaseName();
1254 } else {
1255 out << "::android::hardware::IHidlInterfaceBase";
1256 }
1257
1258 out << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001259
Andreas Huber881227d2016-08-02 14:20:21 -07001260 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001261 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001262 out << "break;\n";
1263 out.unindent();
1264 out << "}\n\n";
1265
Andreas Huber5e44a292016-09-27 14:52:39 -07001266 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001267
Yifan Hongbf459bc2016-08-23 16:50:37 -07001268 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001269 for (const auto &arg : method->args()) {
1270 emitCppReaderWriter(
1271 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001272 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001273 false /* parcelObjIsPointer */,
1274 arg,
1275 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001276 Type::ErrorMode_Break,
1277 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001278 }
1279
Yifan Hongbf459bc2016-08-23 16:50:37 -07001280 // Second DFS: resolve references
1281 for (const auto &arg : method->args()) {
1282 emitCppResolveReferences(
1283 out,
1284 "_hidl_data",
1285 false /* parcelObjIsPointer */,
1286 arg,
1287 true /* reader */,
1288 Type::ErrorMode_Break,
1289 false /* addPrefixToName */);
1290 }
1291
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001292 status_t status = generateCppInstrumentationCall(
1293 out,
1294 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001295 method);
1296 if (status != OK) {
1297 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001298 }
1299
Andreas Huber881227d2016-08-02 14:20:21 -07001300 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001301 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001302
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001303 if (elidedReturn != nullptr) {
1304 std::string extra;
Andreas Huber881227d2016-08-02 14:20:21 -07001305
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001306 out << elidedReturn->type().getCppResultType(&extra) << " ";
1307 out << elidedReturn->name() << " = ";
1308 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001309
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001310 bool first = true;
1311 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001312 if (!first) {
1313 out << ", ";
1314 }
1315
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001316 if (arg->type().resultNeedsDeref()) {
1317 out << "*";
1318 }
1319
1320 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001321
1322 first = false;
1323 }
1324
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001325 out << ");\n\n";
Andreas Huber8a82ff72016-08-04 10:29:39 -07001326 out << "::android::hardware::Status::ok()"
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001327 << ".writeToParcel(_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001328
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001329 elidedReturn->type().emitReaderWriter(
1330 out,
1331 elidedReturn->name(),
1332 "_hidl_reply",
1333 true, /* parcelObjIsPointer */
1334 false, /* isReader */
1335 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001336
Yifan Hongbf459bc2016-08-23 16:50:37 -07001337 emitCppResolveReferences(
1338 out,
1339 "_hidl_reply",
1340 true /* parcelObjIsPointer */,
1341 elidedReturn,
1342 false /* reader */,
1343 Type::ErrorMode_Ignore,
1344 false /* addPrefixToName */);
1345
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001346 status_t status = generateCppInstrumentationCall(
1347 out,
1348 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001349 method);
1350 if (status != OK) {
1351 return status;
1352 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001353
Iliyan Malchev549e2592016-08-10 08:59:12 -07001354 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001355 } else {
1356 if (returnsValue) {
1357 out << "bool _hidl_callbackCalled = false;\n\n";
1358 }
Andreas Huber881227d2016-08-02 14:20:21 -07001359
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001360 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001361
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001362 bool first = true;
1363 for (const auto &arg : method->args()) {
1364 if (!first) {
1365 out << ", ";
1366 }
Andreas Huber881227d2016-08-02 14:20:21 -07001367
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001368 if (arg->type().resultNeedsDeref()) {
1369 out << "*";
1370 }
1371
1372 out << arg->name();
1373
1374 first = false;
1375 }
1376
1377 if (returnsValue) {
1378 if (!first) {
1379 out << ", ";
1380 }
1381
1382 out << "[&](";
1383
1384 first = true;
1385 for (const auto &arg : method->results()) {
1386 if (!first) {
1387 out << ", ";
1388 }
1389
1390 out << "const auto &" << arg->name();
1391
1392 first = false;
1393 }
1394
1395 out << ") {\n";
1396 out.indent();
1397 out << "_hidl_callbackCalled = true;\n\n";
1398
1399 out << "::android::hardware::Status::ok()"
1400 << ".writeToParcel(_hidl_reply);\n\n";
1401
Yifan Hongbf459bc2016-08-23 16:50:37 -07001402 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001403 for (const auto &arg : method->results()) {
1404 emitCppReaderWriter(
1405 out,
1406 "_hidl_reply",
1407 true /* parcelObjIsPointer */,
1408 arg,
1409 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001410 Type::ErrorMode_Ignore,
1411 false /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001412 }
1413
Yifan Hongbf459bc2016-08-23 16:50:37 -07001414 // Second DFS: resolve references
1415 for (const auto &arg : method->results()) {
1416 emitCppResolveReferences(
1417 out,
1418 "_hidl_reply",
1419 true /* parcelObjIsPointer */,
1420 arg,
1421 false /* reader */,
1422 Type::ErrorMode_Ignore,
1423 false /* addPrefixToName */);
1424 }
1425
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001426 status_t status = generateCppInstrumentationCall(
1427 out,
1428 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001429 method);
1430 if (status != OK) {
1431 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001432 }
1433
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001434 out << "_hidl_cb(*_hidl_reply);\n";
1435
1436 out.unindent();
1437 out << "}\n";
1438 }
1439
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001440 out << ");\n\n";
1441
1442 // What to do if the stub implementation has a synchronous callback
1443 // which does not get invoked? This is not a transport error but a
1444 // service error of sorts. For now, return OK to the caller, as this is
1445 // not a transport error.
1446 //
1447 // TODO(b/31365311) Figure out how to deal with this later.
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001448
1449 if (returnsValue) {
1450 out << "if (!_hidl_callbackCalled) {\n";
1451 out.indent();
1452 }
1453
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001454 out << "::android::hardware::Status::ok()"
1455 << ".writeToParcel(_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001456
1457 if (returnsValue) {
1458 out.unindent();
1459 out << "}\n\n";
1460 }
Andreas Huber881227d2016-08-02 14:20:21 -07001461 }
1462
1463 out << "break;\n";
1464
1465 return OK;
1466}
1467
Steven Moreland69e7c702016-09-09 11:16:32 -07001468status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1469 std::string ifaceName;
1470 if (!AST::isInterface(&ifaceName)) {
1471 // types.hal does not get a stub header.
1472 return OK;
1473 }
1474
1475 const Interface *iface = mRootScope->getInterface();
1476
1477 const std::string baseName = iface->getBaseName();
1478 const std::string klassName = "Bs" + baseName;
1479
1480 bool supportOneway = iface->hasOnewayMethods();
1481
1482 std::string path = outputPath;
1483 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1484 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1485 path.append(klassName);
1486 path.append(".h");
1487
1488 CHECK(Coordinator::MakeParentHierarchy(path));
1489 FILE *file = fopen(path.c_str(), "w");
1490
1491 if (file == NULL) {
1492 return -errno;
1493 }
1494
1495 Formatter out(file);
1496
1497 const std::string guard = makeHeaderGuard(klassName);
1498
1499 out << "#ifndef " << guard << "\n";
1500 out << "#define " << guard << "\n\n";
1501
1502 std::vector<std::string> packageComponents;
1503 getPackageAndVersionComponents(
1504 &packageComponents, false /* cpp_compatible */);
1505
1506 out << "#include <future>\n";
1507 out << "#include <";
1508 for (const auto &component : packageComponents) {
1509 out << component << "/";
1510 }
1511 out << ifaceName << ".h>\n\n";
1512
1513 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001514 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001515 }
1516
1517 enterLeaveNamespace(out, true /* enter */);
1518 out << "\n";
1519
1520 out << "struct "
1521 << klassName
1522 << " : " << ifaceName
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001523 << ", HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001524
1525 out.indent();
1526 out << "explicit "
1527 << klassName
1528 << "(const sp<"
1529 << ifaceName
1530 << "> impl);\n";
1531
Yifan Hong068c5522016-10-31 14:07:25 -07001532 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1533 return generatePassthroughMethod(out, method);
1534 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001535
1536 if (err != OK) {
1537 return err;
1538 }
1539
1540 out.unindent();
1541 out << "private:\n";
1542 out.indent();
1543 out << "const sp<" << ifaceName << "> mImpl;\n";
1544
1545 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001546 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001547
1548 out << "\n";
1549
1550 out << "::android::hardware::Return<void> addOnewayTask("
1551 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001552 }
1553
1554 out.unindent();
1555
1556 out << "};\n\n";
1557
1558 enterLeaveNamespace(out, false /* enter */);
1559
1560 out << "\n#endif // " << guard << "\n";
1561
1562 return OK;
1563}
1564
Yifan Hongfe95aa22016-10-19 17:26:45 -07001565status_t AST::generateInterfaceSource(Formatter &out) const {
1566 const Interface *iface = mRootScope->getInterface();
1567
Yifan Hong2d7126b2016-10-20 15:12:57 -07001568
1569 // generate toBinder functions
1570 out << "::android::sp<::android::hardware::IBinder> I"
1571 << iface->getBaseName()
1572 << "::toBinder() {\n";
1573 out.indent();
1574 out << "if (isRemote()) {\n";
1575 out.indent();
1576 out << "return ::android::hardware::IInterface::asBinder("
1577 << "static_cast<IHw"
1578 << iface->getBaseName()
1579 << " *>(this));\n";
1580 out.unindent();
1581 out << "} else {\n";
1582 out.indent();
1583 out << "return new Bn" << iface->getBaseName() << "(this);\n";
1584 out.unindent();
1585 out << "}\n";
1586 out.unindent();
1587 out << "}\n\n";
1588
1589 // generate castFrom functions
Yifan Hongfe95aa22016-10-19 17:26:45 -07001590 if (!iface->isRootType()) {
1591 std::string childTypeExtra;
1592 std::string childTypeResult = iface->getCppResultType(&childTypeExtra);
1593 childTypeResult += childTypeExtra;
1594
1595 for (const Interface *superType : iface->superTypeChain()) {
1596 std::string superTypeExtra;
1597 out << "// static \n"
1598 << childTypeResult
1599 << " I"
1600 << iface->getBaseName()
1601 << "::castFrom("
1602 << superType->getCppArgumentType(&superTypeExtra)
1603 << " parent"
1604 << superTypeExtra
1605 << ")";
1606 out << " {\n";
1607 out.indent();
1608 out << "return ::android::hardware::castInterface<";
1609 out << "I" << iface->getBaseName() << ", "
1610 << superType->fqName().cppName() << ", "
1611 << "Bp" << iface->getBaseName()
1612 << ">(\n";
1613 out.indent();
1614 out.indent();
1615 out << "parent, \""
1616 << iface->fqName().string()
1617 << "\");\n";
1618 out.unindent();
1619 out.unindent();
1620 out.unindent();
1621 out << "}\n\n";
1622 }
1623 }
1624
1625 return OK;
1626}
1627
Steven Moreland69e7c702016-09-09 11:16:32 -07001628status_t AST::generatePassthroughSource(Formatter &out) const {
1629 const Interface *iface = mRootScope->getInterface();
1630
1631 const std::string baseName = iface->getBaseName();
1632 const std::string klassName = "Bs" + baseName;
1633
1634 out << klassName
1635 << "::"
1636 << klassName
1637 << "(const sp<"
1638 << iface->fullName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001639 << "> impl) : HidlInstrumentor(\""
1640 << iface->fqName().string()
1641 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001642 if (iface->hasOnewayMethods()) {
1643 out << "\n";
1644 out.indentBlock([&] {
1645 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1646 });
1647 }
1648 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001649
1650 if (iface->hasOnewayMethods()) {
1651 out << "::android::hardware::Return<void> "
1652 << klassName
1653 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1654 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001655 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001656 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001657 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1658 out.indent();
1659 out.indent();
1660 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1661 out.unindent();
1662 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001663 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001664 out << "}\n";
1665
Steven Morelandd366c262016-10-11 15:29:10 -07001666 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001667
1668 out.unindent();
1669 out << "}\n\n";
1670
1671
1672 }
1673
1674 return OK;
1675}
1676
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001677status_t AST::generateCppInstrumentationCall(
1678 Formatter &out,
1679 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001680 const Method *method) const {
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001681 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1682 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001683 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001684 std::string event_str = "";
1685 switch (event) {
1686 case SERVER_API_ENTRY:
1687 {
1688 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1689 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001690 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001691 << (arg->type().resultNeedsDeref() ? "" : "&")
1692 << arg->name()
1693 << ");\n";
1694 }
1695 break;
1696 }
1697 case SERVER_API_EXIT:
1698 {
1699 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001700 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001701 out << "_hidl_args.push_back((void *)&"
Steven Moreland031ccf12016-10-31 15:54:38 -07001702 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001703 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001704 }
1705 break;
1706 }
1707 case CLIENT_API_ENTRY:
1708 {
1709 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1710 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001711 out << "_hidl_args.push_back((void *)&"
1712 << arg->name()
1713 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001714 }
1715 break;
1716 }
1717 case CLIENT_API_EXIT:
1718 {
1719 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1720 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001721 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001722 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001723 << "_hidl_out_"
1724 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001725 << ");\n";
1726 }
1727 break;
1728 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001729 case PASSTHROUGH_ENTRY:
1730 {
1731 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1732 for (const auto &arg : method->args()) {
1733 out << "_hidl_args.push_back((void *)&"
1734 << arg->name()
1735 << ");\n";
1736 }
1737 break;
1738 }
1739 case PASSTHROUGH_EXIT:
1740 {
1741 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
1742 // TODO(b/32576620): passthrough return values
1743 break;
1744 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001745 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001746 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001747 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001748 return UNKNOWN_ERROR;
1749 }
1750 }
1751
Steven Moreland031ccf12016-10-31 15:54:38 -07001752 const Interface *iface = mRootScope->getInterface();
1753
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001754 out << "for (auto callback: mInstrumentationCallbacks) {\n";
1755 out.indent();
1756 out << "callback("
1757 << event_str
1758 << ", \""
1759 << mPackage.package()
1760 << "\", \""
1761 << mPackage.getPackageFullVersion()
1762 << "\", \""
1763 << iface->localName()
1764 << "\", \""
1765 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001766 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001767 out.unindent();
1768 out << "}\n";
1769 out.unindent();
1770 out << "}\n\n";
1771
1772 return OK;
1773}
1774
Andreas Huber881227d2016-08-02 14:20:21 -07001775} // namespace android
1776