blob: 7f136a0b08c56e03ffb3c4ddc31ce410da8b7e77 [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";
Andreas Huber881227d2016-08-02 14:20:21 -0700203 bool haveCallbacks = false;
204 for (const auto &method : iface->methods()) {
205 const bool returnsValue = !method->results().empty();
206
207 if (!returnsValue) {
208 continue;
209 }
210
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700211 if (method->canElideCallback() != nullptr) {
212 continue;
213 }
214
Andreas Huber881227d2016-08-02 14:20:21 -0700215 haveCallbacks = true;
216
217 out << "using "
218 << method->name()
219 << "_cb = std::function<void("
Steven Moreland979e0992016-09-07 09:18:08 -0700220 << Method::GetArgSignature(method->results(),
221 true /* specify namespaces */)
Andreas Huber881227d2016-08-02 14:20:21 -0700222 << ")>;\n";
223 }
224
225 if (haveCallbacks) {
226 out << "\n";
227 }
228
229 for (const auto &method : iface->methods()) {
230 const bool returnsValue = !method->results().empty();
231
Andreas Huber3599d922016-08-09 10:42:57 -0700232 method->dumpAnnotations(out);
233
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700234 const TypedVar *elidedReturn = method->canElideCallback();
235 if (elidedReturn) {
236 std::string extra;
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700237 out << "virtual ::android::hardware::Return<";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700238 out << elidedReturn->type().getCppResultType(&extra) << "> ";
239 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700240 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700241 }
242
243 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700244 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700245 << Method::GetArgSignature(method->args(),
246 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700247
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700248 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700249 if (!method->args().empty()) {
250 out << ", ";
251 }
252
Steven Moreland67f67b42016-09-29 08:59:02 -0700253 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700254 }
255
Yifan Hong10fe0b52016-10-19 14:20:17 -0700256 out << ")";
257 if (method->isHidlReserved()) {
258 out << " override";
259 out << " {\n";
260 out.indent();
261 method->cppImpl(out);
262 out.unindent();
263 out << "\n}\n";
264 } else {
265 out << " = 0;\n";
266 }
Andreas Huber881227d2016-08-02 14:20:21 -0700267 }
Steven Moreland40786312016-08-16 10:29:40 -0700268
Yifan Hongfe95aa22016-10-19 17:26:45 -0700269 if (!iface->isRootType()) {
270 out << "// cast static functions\n";
271 std::string childTypeExtra;
272 std::string childTypeResult = iface->getCppResultType(&childTypeExtra);
273 childTypeResult += childTypeExtra;
274
275 for (const Interface *superType : iface->superTypeChain()) {
276 std::string superTypeExtra;
277 out << "static "
278 << childTypeResult
279 << " castFrom("
280 << superType->getCppArgumentType(&superTypeExtra)
281 << " parent"
282 << superTypeExtra
283 << ");\n";
284 }
285 }
286
Yifan Hong10fe0b52016-10-19 14:20:17 -0700287 out << "\nstatic const ::android::String16 descriptor;\n\n";
288
Steven Moreland40786312016-08-16 10:29:40 -0700289 out << "DECLARE_REGISTER_AND_GET_SERVICE(" << baseName << ")\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700290 }
291
292 if (isInterface) {
293 out.unindent();
294
Andreas Hubere3f769a2016-10-10 10:54:44 -0700295 out << "};\n\n";
296 }
297
298 err = mRootScope->emitGlobalTypeDeclarations(out);
299
300 if (err != OK) {
301 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700302 }
303
304 out << "\n";
305 enterLeaveNamespace(out, false /* enter */);
306
307 out << "\n#endif // " << guard << "\n";
308
309 return OK;
310}
311
Steven Moreland40786312016-08-16 10:29:40 -0700312status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
313 std::string ifaceName;
314 if(!AST::isInterface(&ifaceName)) {
315 // types.hal does not get an HwBinder header.
316 return OK;
317 }
318
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700319 const Interface *iface = mRootScope->getInterface();
320 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700321
322 const std::string klassName = "IHw" + baseName;
323
324 std::string path = outputPath;
325 path.append(mCoordinator->convertPackageRootToPath(mPackage));
326 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
327 path.append(klassName + ".h");
328
329 FILE* file = fopen(path.c_str(), "w");
330
331 if (file == NULL) {
332 return -errno;
333 }
334
335 Formatter out(file);
336
337 const std::string guard = makeHeaderGuard(klassName);
338
339 out << "#ifndef " << guard << "\n";
340 out << "#define " << guard << "\n\n";
341
342 std::vector<std::string> packageComponents;
343 getPackageAndVersionComponents(
344 &packageComponents, false /* cpp_compatible */);
345
346 out << "#include <";
347 for (const auto &component : packageComponents) {
348 out << component << "/";
349 }
350 out << ifaceName << ".h>\n\n";
351
352 for (const auto &item : mImportedNames) {
353 if (item.name() == "types") {
354 continue;
355 }
356
357 out << "#include <";
358
359 std::vector<std::string> components;
360 item.getPackageAndVersionComponents(
361 &components, false /* cpp_compatible */);
362
363 for (const auto &component : components) {
364 out << component << "/";
365 }
366
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700367 const std::string itemBaseName = item.getInterfaceBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700368
369 out << "Bn"
370 << itemBaseName
371 << ".h>\n";
372 }
373
374 out << "\n";
375
376 out << "#include <hidl/HidlSupport.h>\n";
Martijn Coenen93915102016-09-01 01:35:52 +0200377 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700378 out << "#include <hwbinder/IBinder.h>\n";
379 out << "#include <hwbinder/IInterface.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700380
381 out << "\n";
382
383 enterLeaveNamespace(out, true /* enter */);
384 out << "\n";
385
386 out << "struct "
387 << klassName
388 << " : public "
389 << ifaceName;
390
Steven Moreland40786312016-08-16 10:29:40 -0700391 const Interface *superType = iface->superType();
392
393 out << ", public ::android::hardware::IInterface";
394
395 out << " {\n";
396
397 out.indent();
398
399 out << "DECLARE_HWBINDER_META_INTERFACE(" << baseName << ");\n\n";
400
Steven Moreland40786312016-08-16 10:29:40 -0700401 out.unindent();
402
403 out << "};\n\n";
404
405 enterLeaveNamespace(out, false /* enter */);
406
407 out << "\n#endif // " << guard << "\n";
408
409 return OK;
410}
411
Andreas Huber881227d2016-08-02 14:20:21 -0700412status_t AST::emitTypeDeclarations(Formatter &out) const {
413 return mRootScope->emitTypeDeclarations(out);
414}
415
Steven Morelanda7a421a2016-09-07 08:35:18 -0700416status_t AST::generateStubMethod(Formatter &out,
417 const std::string &className,
Steven Moreland979e0992016-09-07 09:18:08 -0700418 const Method *method,
419 bool specifyNamespaces) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700420 out << "inline ";
421
Steven Moreland979e0992016-09-07 09:18:08 -0700422 method->generateCppSignature(out,
423 className,
424 specifyNamespaces);
Steven Morelanda7a421a2016-09-07 08:35:18 -0700425
426 const bool returnsValue = !method->results().empty();
427 const TypedVar *elidedReturn = method->canElideCallback();
428 out << " {\n";
429 out.indent();
430 out << "return mImpl->"
431 << method->name()
432 << "(";
433 bool first = true;
434 for (const auto &arg : method->args()) {
435 if (!first) {
436 out << ", ";
437 }
438 first = false;
439 out << arg->name();
440 }
441 if (returnsValue && elidedReturn == nullptr) {
442 if (!method->args().empty()) {
443 out << ", ";
444 }
445
446 out << "_hidl_cb";
447 }
448 out << ");\n";
449 out.unindent();
450 out << "}";
451
452 out << ";\n";
453
454 return OK;
455}
456
Steven Moreland9c387612016-09-07 09:54:26 -0700457status_t AST::generateProxyDeclaration(Formatter &out,
458 const std::string &className,
459 const Method *method,
460 bool specifyNamespaces) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700461
Steven Moreland979e0992016-09-07 09:18:08 -0700462 method->generateCppSignature(out,
463 className,
464 specifyNamespaces);
Steven Morelanda7a421a2016-09-07 08:35:18 -0700465 out << " override;\n";
466
467 return OK;
468}
469
Steven Moreland69e7c702016-09-09 11:16:32 -0700470
471status_t AST::generatePassthroughMethod(Formatter &out,
472 const std::string &className,
473 const Method *method,
474 bool specifyNamespaces) const {
475 method->generateCppSignature(out, className, specifyNamespaces);
476
477 out << " {\n";
478 out.indent();
479
480 const bool returnsValue = !method->results().empty();
481 const TypedVar *elidedReturn = method->canElideCallback();
482
Steven Moreland67f67b42016-09-29 08:59:02 -0700483 if (returnsValue && elidedReturn == nullptr) {
484 generateCheckNonNull(out, "_hidl_cb");
485 }
486
Steven Moreland69e7c702016-09-09 11:16:32 -0700487 out << "return ";
488
489 if (method->isOneway()) {
490 out << "addOnewayTask([this";
491 for (const auto &arg : method->args()) {
492 out << ", " << arg->name();
493 }
494 out << "] {this->";
495 }
496
497 out << "mImpl->"
498 << method->name()
499 << "(";
500
501 bool first = true;
502 for (const auto &arg : method->args()) {
503 if (!first) {
504 out << ", ";
505 }
506 first = false;
507 out << arg->name();
508 }
509 if (returnsValue && elidedReturn == nullptr) {
510 if (!method->args().empty()) {
511 out << ", ";
512 }
513
514 out << "_hidl_cb";
515 }
516 out << ")";
517
518 if (method->isOneway()) {
519 out << ";})";
520 }
521 out << ";\n";
522
523 out.unindent();
524 out << "}\n";
525
526 return OK;
527}
528
Steven Morelanda7a421a2016-09-07 08:35:18 -0700529status_t AST::generateMethods(
530 Formatter &out,
531 const std::string &className,
Steven Moreland979e0992016-09-07 09:18:08 -0700532 MethodLocation type,
533 bool specifyNamespaces) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700534
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700535 const Interface *iface = mRootScope->getInterface();
536
Yifan Hong10fe0b52016-10-19 14:20:17 -0700537 const Interface *prevIterface = nullptr;
538 for (const auto &tuple : iface->allMethodsFromRoot()) {
539 const Method *method = tuple.method();
540 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700541
Yifan Hong10fe0b52016-10-19 14:20:17 -0700542 if(prevIterface != superInterface) {
543 if (prevIterface != nullptr) {
544 out << "\n";
545 }
546 out << "// Methods from "
547 << superInterface->fullName()
548 << " follow.\n";
549 prevIterface = superInterface;
550 }
551 status_t err;
552 switch(type) {
553 case STUB_HEADER:
554 err = generateStubMethod(out,
555 className,
556 method,
557 specifyNamespaces);
558 break;
559 case PROXY_HEADER:
560 err = generateProxyDeclaration(out,
561 className,
562 method,
563 specifyNamespaces);
564 break;
565 case IMPL_HEADER:
566 err = generateStubImplDeclaration(out,
567 className,
568 method,
569 specifyNamespaces);
570 break;
571 case IMPL_SOURCE:
572 err = generateStubImplMethod(out,
Steven Morelanda7a421a2016-09-07 08:35:18 -0700573 className,
Steven Moreland979e0992016-09-07 09:18:08 -0700574 method,
575 specifyNamespaces);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700576 break;
577 case PASSTHROUGH_HEADER:
578 err = generatePassthroughMethod(out,
579 className,
580 method,
581 specifyNamespaces);
582 break;
583 default:
584 LOG(ERROR) << "Unkown method type: " << type;
585 err = UNKNOWN_ERROR;
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700586 }
587
Yifan Hong10fe0b52016-10-19 14:20:17 -0700588 if (err != OK) {
589 return err;
590 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700591 }
592
Yifan Hong10fe0b52016-10-19 14:20:17 -0700593 out << "\n";
594
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700595 return OK;
596}
597
Andreas Huberb82318c2016-08-02 14:45:54 -0700598status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700599 std::string ifaceName;
600 if (!AST::isInterface(&ifaceName)) {
601 // types.hal does not get a stub header.
602 return OK;
603 }
604
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700605 const Interface *iface = mRootScope->getInterface();
606 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700607 const std::string klassName = "Bn" + baseName;
Andreas Huber881227d2016-08-02 14:20:21 -0700608
Andreas Huberb82318c2016-08-02 14:45:54 -0700609 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700610 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700611 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700612 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700613 path.append(".h");
614
Andreas Huberd2943e12016-08-05 11:59:31 -0700615 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700616 FILE *file = fopen(path.c_str(), "w");
617
618 if (file == NULL) {
619 return -errno;
620 }
621
622 Formatter out(file);
623
Steven Moreland40786312016-08-16 10:29:40 -0700624 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700625
626 out << "#ifndef " << guard << "\n";
627 out << "#define " << guard << "\n\n";
628
629 std::vector<std::string> packageComponents;
630 getPackageAndVersionComponents(
631 &packageComponents, false /* cpp_compatible */);
632
633 out << "#include <";
634 for (const auto &component : packageComponents) {
635 out << component << "/";
636 }
Steven Moreland40786312016-08-16 10:29:40 -0700637 out << "IHw" << baseName << ".h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700638
639 enterLeaveNamespace(out, true /* enter */);
640 out << "\n";
641
642 out << "struct "
643 << "Bn"
644 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700645 << " : public ::android::hardware::BnInterface<I"
646 << baseName << ", IHw" << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700647 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700648
649 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700650 out << "explicit Bn"
651 << baseName
652 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
653 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700654 out << "::android::status_t onTransact(\n";
655 out.indent();
656 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700657 out << "uint32_t _hidl_code,\n";
658 out << "const ::android::hardware::Parcel &_hidl_data,\n";
659 out << "::android::hardware::Parcel *_hidl_reply,\n";
660 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700661 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700662 out.unindent();
663 out.unindent();
664
Steven Moreland9c387612016-09-07 09:54:26 -0700665 status_t err = generateMethods(out,
666 "" /* class name */,
667 MethodLocation::STUB_HEADER,
668 true /* specify namespaces */);
669
670 if (err != OK) {
671 return err;
672 }
673
Zhuoyao Zhangde578002016-09-07 18:24:17 -0700674
Andreas Huber881227d2016-08-02 14:20:21 -0700675 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700676 out << "};\n\n";
677
678 enterLeaveNamespace(out, false /* enter */);
679
680 out << "\n#endif // " << guard << "\n";
681
682 return OK;
683}
684
Andreas Huberb82318c2016-08-02 14:45:54 -0700685status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700686 std::string ifaceName;
687 if (!AST::isInterface(&ifaceName)) {
688 // types.hal does not get a proxy header.
689 return OK;
690 }
691
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700692 const Interface *iface = mRootScope->getInterface();
693 const std::string baseName = iface->getBaseName();
Andreas Huber881227d2016-08-02 14:20:21 -0700694
Andreas Huberb82318c2016-08-02 14:45:54 -0700695 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700696 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700697 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700698 path.append("Bp");
699 path.append(baseName);
700 path.append(".h");
701
Andreas Huberd2943e12016-08-05 11:59:31 -0700702 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700703 FILE *file = fopen(path.c_str(), "w");
704
705 if (file == NULL) {
706 return -errno;
707 }
708
709 Formatter out(file);
710
711 const std::string guard = makeHeaderGuard("Bp" + baseName);
712
713 out << "#ifndef " << guard << "\n";
714 out << "#define " << guard << "\n\n";
715
716 std::vector<std::string> packageComponents;
717 getPackageAndVersionComponents(
718 &packageComponents, false /* cpp_compatible */);
719
720 out << "#include <";
721 for (const auto &component : packageComponents) {
722 out << component << "/";
723 }
Steven Moreland40786312016-08-16 10:29:40 -0700724 out << "IHw" << baseName << ".h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700725
726 enterLeaveNamespace(out, true /* enter */);
727 out << "\n";
728
729 out << "struct "
730 << "Bp"
731 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700732 << " : public ::android::hardware::BpInterface<IHw"
733 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700734 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700735
736 out.indent();
737
738 out << "explicit Bp"
739 << baseName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700740 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700741 << "\n\n";
742
Yifan Hong10fe0b52016-10-19 14:20:17 -0700743 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700744
Steven Moreland9c387612016-09-07 09:54:26 -0700745 status_t err = generateMethods(out,
746 "" /* class name */,
747 MethodLocation::PROXY_HEADER,
748 true /* generate specify namespaces */);
749
750 if (err != OK) {
751 return err;
752 }
Andreas Huber881227d2016-08-02 14:20:21 -0700753
754 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700755 out << "};\n\n";
756
757 enterLeaveNamespace(out, false /* enter */);
758
759 out << "\n#endif // " << guard << "\n";
760
761 return OK;
762}
763
Andreas Huberb82318c2016-08-02 14:45:54 -0700764status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700765
Andreas Huberb82318c2016-08-02 14:45:54 -0700766 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700767 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700768 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700769
770 std::string ifaceName;
771 std::string baseName;
772
Yifan Hongfe95aa22016-10-19 17:26:45 -0700773 const Interface *iface = nullptr;
774 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700775 if (!AST::isInterface(&ifaceName)) {
776 baseName = "types";
777 isInterface = false;
778 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700779 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700780 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700781 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700782 }
783
784 path.append(baseName);
785
786 if (baseName != "types") {
787 path.append("All");
788 }
789
790 path.append(".cpp");
791
Andreas Huberd2943e12016-08-05 11:59:31 -0700792 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700793 FILE *file = fopen(path.c_str(), "w");
794
795 if (file == NULL) {
796 return -errno;
797 }
798
799 Formatter out(file);
800
801 std::vector<std::string> packageComponents;
802 getPackageAndVersionComponents(
803 &packageComponents, false /* cpp_compatible */);
804
805 std::string prefix;
806 for (const auto &component : packageComponents) {
807 prefix += component;
808 prefix += "/";
809 }
810
811 if (isInterface) {
812 out << "#include <" << prefix << "/Bp" << baseName << ".h>\n";
813 out << "#include <" << prefix << "/Bn" << baseName << ".h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700814 out << "#include <" << prefix << "/Bs" << baseName << ".h>\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700815
816 for (const Interface *superType : iface->superTypeChain()) {
817 std::vector<std::string> superPackageComponents;
818 superType->fqName().getPackageAndVersionComponents(&superPackageComponents, false /* cpp_compatible */);
819 std::string superPrefix;
820 for (const auto &component : superPackageComponents) {
821 superPrefix += component;
822 superPrefix += "/";
823 }
824 out << "#include <" << superPrefix << "/Bp" << superType->getBaseName() << ".h>\n";
825 }
Andreas Huber881227d2016-08-02 14:20:21 -0700826 } else {
827 out << "#include <" << prefix << "types.h>\n";
828 }
829
830 out << "\n";
831
832 enterLeaveNamespace(out, true /* enter */);
833 out << "\n";
834
835 status_t err = generateTypeSource(out, ifaceName);
836
837 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700838 const Interface *iface = mRootScope->getInterface();
Martijn Coenena21f1492016-09-08 15:55:14 +0200839 out << "constexpr hidl_version " << ifaceName << "::version;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700840
841 // need to be put here, generateStubSource is using this.
842 out << "const ::android::String16 I"
843 << iface->getBaseName()
844 << "::descriptor(\""
845 << iface->fqName().string()
846 << "\");\n\n";
847
Yifan Hongfe95aa22016-10-19 17:26:45 -0700848 err = generateInterfaceSource(out);
849 }
850
851 if (err == OK && isInterface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700852 err = generateProxySource(out, baseName);
853 }
854
855 if (err == OK && isInterface) {
856 err = generateStubSource(out, baseName);
857 }
858
Steven Moreland40786312016-08-16 10:29:40 -0700859 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -0700860 err = generatePassthroughSource(out);
861 }
862
863 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -0700864 const Interface *iface = mRootScope->getInterface();
865
866 out << "IMPLEMENT_REGISTER_AND_GET_SERVICE("
867 << baseName << ", "
868 << "\"" << iface->fqName().package()
Iliyan Malchev4923f932016-09-09 13:04:59 -0700869 << iface->fqName().version() << "-impl.so\""
Steven Moreland9c387612016-09-07 09:54:26 -0700870 << ")\n";
Steven Moreland40786312016-08-16 10:29:40 -0700871 }
872
Andreas Huber881227d2016-08-02 14:20:21 -0700873 enterLeaveNamespace(out, false /* enter */);
874
875 return err;
876}
877
Steven Moreland67f67b42016-09-29 08:59:02 -0700878// static
879void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
880 out << "if (" << nonNull << " == nullptr) {\n";
881 out.indent();
882 out << "return ::android::hardware::Status::fromExceptionCode(\n";
883 out.indent();
884 out.indent();
885 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
886 out.unindent();
887 out.unindent();
888 out.unindent();
889 out << "}\n\n";
890}
891
Andreas Huber881227d2016-08-02 14:20:21 -0700892status_t AST::generateTypeSource(
893 Formatter &out, const std::string &ifaceName) const {
894 return mRootScope->emitTypeDefinitions(out, ifaceName);
895}
896
Andreas Hubere7ff2282016-08-16 13:50:03 -0700897void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -0700898 Formatter &out,
899 const std::vector<TypedVar *> &args,
900 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700901 if (args.empty()) {
902 return;
903 }
904
905 for (const auto &arg : args) {
906 const Type &type = arg->type();
907
908 std::string extra;
909 out << type.getCppResultType(&extra)
910 << " "
Andreas Huber5e44a292016-09-27 14:52:39 -0700911 << (forResults ? "_hidl_out_" : "")
Andreas Hubere7ff2282016-08-16 13:50:03 -0700912 << arg->name()
913 << extra
914 << ";\n";
915 }
916
917 out << "\n";
918}
919
Andreas Huber881227d2016-08-02 14:20:21 -0700920void AST::emitCppReaderWriter(
921 Formatter &out,
922 const std::string &parcelObj,
923 bool parcelObjIsPointer,
924 const TypedVar *arg,
925 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -0700926 Type::ErrorMode mode,
927 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700928 const Type &type = arg->type();
929
Andreas Huber881227d2016-08-02 14:20:21 -0700930 type.emitReaderWriter(
931 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700932 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700933 parcelObj,
934 parcelObjIsPointer,
935 isReader,
936 mode);
937}
938
Yifan Hongbf459bc2016-08-23 16:50:37 -0700939void AST::emitCppResolveReferences(
940 Formatter &out,
941 const std::string &parcelObj,
942 bool parcelObjIsPointer,
943 const TypedVar *arg,
944 bool isReader,
945 Type::ErrorMode mode,
946 bool addPrefixToName) const {
947 const Type &type = arg->type();
948 if(type.needsResolveReferences()) {
949 type.emitResolveReferences(
950 out,
951 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
952 isReader, // nameIsPointer
953 parcelObj,
954 parcelObjIsPointer,
955 isReader,
956 mode);
957 }
958}
959
Andreas Huber881227d2016-08-02 14:20:21 -0700960status_t AST::generateProxySource(
961 Formatter &out, const std::string &baseName) const {
962 const std::string klassName = "Bp" + baseName;
963
964 out << klassName
965 << "::"
966 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700967 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700968
969 out.indent();
970 out.indent();
971
972 out << ": BpInterface"
Steven Moreland40786312016-08-16 10:29:40 -0700973 << "<IHw"
Andreas Huber881227d2016-08-02 14:20:21 -0700974 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700975 << ">(_hidl_impl),\n"
976 << " HidlInstrumentor(\""
977 << mPackage.string()
978 << "::I"
979 << baseName
980 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -0700981
Andreas Huber881227d2016-08-02 14:20:21 -0700982 out.unindent();
983 out.unindent();
984 out << "}\n\n";
985
986 const Interface *iface = mRootScope->getInterface();
987
Yifan Hong10fe0b52016-10-19 14:20:17 -0700988 for (const auto &tuple : iface->allMethodsFromRoot()) {
989 const Method *method = tuple.method();
990 const Interface *superInterface = tuple.interface();
991 method->generateCppSignature(out,
992 klassName,
993 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700994
Yifan Hong10fe0b52016-10-19 14:20:17 -0700995 const bool returnsValue = !method->results().empty();
996 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -0700997
Yifan Hong10fe0b52016-10-19 14:20:17 -0700998 out << "{\n";
Steven Morelanda7a421a2016-09-07 08:35:18 -0700999
Yifan Hong10fe0b52016-10-19 14:20:17 -07001000 out.indent();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001001
Yifan Hong10fe0b52016-10-19 14:20:17 -07001002 if (returnsValue && elidedReturn == nullptr) {
1003 generateCheckNonNull(out, "_hidl_cb");
1004 }
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001005
Yifan Hong10fe0b52016-10-19 14:20:17 -07001006 status_t status = generateCppInstrumentationCall(
1007 out,
1008 InstrumentationEvent::CLIENT_API_ENTRY,
1009 superInterface,
1010 method);
1011 if (status != OK) {
1012 return status;
1013 }
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001014
Yifan Hong10fe0b52016-10-19 14:20:17 -07001015 out << "::android::hardware::Parcel _hidl_data;\n";
1016 out << "::android::hardware::Parcel _hidl_reply;\n";
1017 out << "::android::status_t _hidl_err;\n";
1018 out << "::android::hardware::Status _hidl_status;\n\n";
1019
1020 declareCppReaderLocals(
1021 out, method->results(), true /* forResults */);
1022
1023 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
1024 if (!method->isHidlReserved()) {
1025 out << superInterface->fqName().cppNamespace()
1026 << "::IHw"
1027 << superInterface->getBaseName();
1028 } else {
1029 out << "::android::hardware::IHidlInterfaceBase";
1030 }
1031 out << "::descriptor);\n";
1032
1033 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1034
1035 // First DFS: write all buffers and resolve pointers for parent
1036 for (const auto &arg : method->args()) {
1037 emitCppReaderWriter(
1038 out,
1039 "_hidl_data",
1040 false /* parcelObjIsPointer */,
1041 arg,
1042 false /* reader */,
1043 Type::ErrorMode_Goto,
1044 false /* addPrefixToName */);
1045 }
1046
1047 // Second DFS: resolve references.
1048 for (const auto &arg : method->args()) {
1049 emitCppResolveReferences(
1050 out,
1051 "_hidl_data",
1052 false /* parcelObjIsPointer */,
1053 arg,
1054 false /* reader */,
1055 Type::ErrorMode_Goto,
1056 false /* addPrefixToName */);
1057 }
1058
1059 out << "_hidl_err = remote()->transact("
1060 << method->getSerialId()
1061 << " /* "
1062 << method->name()
1063 << " */, _hidl_data, &_hidl_reply";
1064
1065 if (method->isOneway()) {
1066 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1067 }
1068 out << ");\n";
1069
1070 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1071
1072 if (!method->isOneway()) {
1073 out << "_hidl_err = _hidl_status.readFromParcel(_hidl_reply);\n";
1074 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1075 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1076
1077
1078 // First DFS: write all buffers and resolve pointers for parent
1079 for (const auto &arg : method->results()) {
1080 emitCppReaderWriter(
1081 out,
1082 "_hidl_reply",
1083 false /* parcelObjIsPointer */,
1084 arg,
1085 true /* reader */,
1086 Type::ErrorMode_Goto,
1087 true /* addPrefixToName */);
Steven Moreland67f67b42016-09-29 08:59:02 -07001088 }
1089
Yifan Hong10fe0b52016-10-19 14:20:17 -07001090 // Second DFS: resolve references.
1091 for (const auto &arg : method->results()) {
1092 emitCppResolveReferences(
1093 out,
1094 "_hidl_reply",
1095 false /* parcelObjIsPointer */,
1096 arg,
1097 true /* reader */,
1098 Type::ErrorMode_Goto,
1099 true /* addPrefixToName */);
1100 }
1101
1102 if (returnsValue && elidedReturn == nullptr) {
1103 out << "_hidl_cb(";
1104
1105 bool first = true;
1106 for (const auto &arg : method->results()) {
1107 if (!first) {
1108 out << ", ";
1109 }
1110
1111 if (arg->type().resultNeedsDeref()) {
1112 out << "*";
1113 }
1114 out << "_hidl_out_" << arg->name();
1115
1116 first = false;
1117 }
1118
1119 out << ");\n\n";
1120 }
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001121 status_t status = generateCppInstrumentationCall(
1122 out,
Yifan Hong10fe0b52016-10-19 14:20:17 -07001123 InstrumentationEvent::CLIENT_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001124 superInterface,
1125 method);
1126 if (status != OK) {
1127 return status;
1128 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001129 }
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001130
Yifan Hong10fe0b52016-10-19 14:20:17 -07001131 if (elidedReturn != nullptr) {
1132 std::string extra;
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001133 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1134 out << "return ::android::hardware::Return<";
Yifan Hong10fe0b52016-10-19 14:20:17 -07001135 out << elidedReturn->type().getCppResultType(&extra)
1136 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1137 } else {
1138 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1139 out << "return ::android::hardware::Return<void>();\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001140 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001141
1142 out.unindent();
1143 out << "_hidl_error:\n";
1144 out.indent();
1145 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1146 out << "return ::android::hardware::Return<";
1147 if (elidedReturn != nullptr) {
1148 std::string extra;
1149 out << method->results().at(0)->type().getCppResultType(&extra);
1150 } else {
1151 out << "void";
1152 }
1153 out << ">(_hidl_status);\n";
1154
1155 out.unindent();
1156 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001157 }
1158
Yifan Hong10fe0b52016-10-19 14:20:17 -07001159
Andreas Huber881227d2016-08-02 14:20:21 -07001160 return OK;
1161}
1162
1163status_t AST::generateStubSource(
1164 Formatter &out, const std::string &baseName) const {
1165 out << "IMPLEMENT_HWBINDER_META_INTERFACE("
1166 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001167 << ", "
1168 << mPackage.cppNamespace()
Andreas Huber881227d2016-08-02 14:20:21 -07001169 << "::I"
1170 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001171 << "::descriptor);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001172
1173 const std::string klassName = "Bn" + baseName;
1174
Steven Moreland40786312016-08-16 10:29:40 -07001175 out << klassName
1176 << "::"
1177 << klassName
1178 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl)\n";
1179
1180 out.indent();
1181 out.indent();
1182
1183 out << ": BnInterface"
1184 << "<I"
1185 << baseName
1186 << ", IHw"
1187 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001188 << ">(_hidl_impl),\n"
1189 << " HidlInstrumentor(\""
1190 << mPackage.string()
1191 << "::I"
1192 << baseName
1193 << "\") {\n";
Steven Moreland40786312016-08-16 10:29:40 -07001194
1195 out.unindent();
1196 out.unindent();
1197 out << "}\n\n";
1198
Andreas Huber881227d2016-08-02 14:20:21 -07001199 out << "::android::status_t " << klassName << "::onTransact(\n";
1200
1201 out.indent();
1202 out.indent();
1203
Iliyan Malchev549e2592016-08-10 08:59:12 -07001204 out << "uint32_t _hidl_code,\n"
1205 << "const ::android::hardware::Parcel &_hidl_data,\n"
1206 << "::android::hardware::Parcel *_hidl_reply,\n"
1207 << "uint32_t _hidl_flags,\n"
1208 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001209
1210 out.unindent();
1211
Iliyan Malchev549e2592016-08-10 08:59:12 -07001212 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001213 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001214 out.indent();
1215
1216 const Interface *iface = mRootScope->getInterface();
1217
Yifan Hong10fe0b52016-10-19 14:20:17 -07001218 for (const auto &tuple : iface->allMethodsFromRoot()) {
1219 const Method *method = tuple.method();
1220 const Interface *superInterface = tuple.interface();
1221 out << "case "
1222 << method->getSerialId()
1223 << " /* "
1224 << method->name()
1225 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001226
Yifan Hong10fe0b52016-10-19 14:20:17 -07001227 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001228
Yifan Hong10fe0b52016-10-19 14:20:17 -07001229 status_t err =
1230 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001231
Yifan Hong10fe0b52016-10-19 14:20:17 -07001232 if (err != OK) {
1233 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001234 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001235
1236 out.unindent();
1237 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001238 }
1239
1240 out << "default:\n{\n";
1241 out.indent();
1242
Andreas Huber8a82ff72016-08-04 10:29:39 -07001243 out << "return ::android::hardware::BnInterface<I"
Steven Moreland40786312016-08-16 10:29:40 -07001244 << baseName << ", IHw" << baseName
Andreas Huber881227d2016-08-02 14:20:21 -07001245 << ">::onTransact(\n";
1246
1247 out.indent();
1248 out.indent();
1249
Iliyan Malchev549e2592016-08-10 08:59:12 -07001250 out << "_hidl_code, _hidl_data, _hidl_reply, "
1251 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001252
1253 out.unindent();
1254 out.unindent();
1255
1256 out.unindent();
1257 out << "}\n";
1258
1259 out.unindent();
1260 out << "}\n\n";
1261
Iliyan Malchev549e2592016-08-10 08:59:12 -07001262 out << "if (_hidl_err == ::android::UNEXPECTED_NULL) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001263 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001264 out << "_hidl_err = ::android::hardware::Status::fromExceptionCode(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001265 out.indent();
1266 out.indent();
Andreas Huber8a82ff72016-08-04 10:29:39 -07001267 out << "::android::hardware::Status::EX_NULL_POINTER)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001268 out.indent();
1269 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001270 out << ".writeToParcel(_hidl_reply);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001271 out.unindent();
1272 out.unindent();
1273 out.unindent();
1274 out.unindent();
1275
1276 out.unindent();
1277 out << "}\n\n";
1278
Iliyan Malchev549e2592016-08-10 08:59:12 -07001279 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001280
1281 out.unindent();
1282 out << "}\n\n";
1283
1284 return OK;
1285}
1286
1287status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001288 Formatter &out, const Interface *iface, const Method *method) const {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001289 out << "if (!_hidl_data.enforceInterface(";
1290
1291 if (!method->isHidlReserved()) {
1292 out << iface->fqName().cppNamespace()
1293 << "::IHw"
1294 << iface->getBaseName();
1295 } else {
1296 out << "::android::hardware::IHidlInterfaceBase";
1297 }
1298
1299 out << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001300
Andreas Huber881227d2016-08-02 14:20:21 -07001301 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001302 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001303 out << "break;\n";
1304 out.unindent();
1305 out << "}\n\n";
1306
Andreas Huber5e44a292016-09-27 14:52:39 -07001307 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001308
Yifan Hongbf459bc2016-08-23 16:50:37 -07001309 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001310 for (const auto &arg : method->args()) {
1311 emitCppReaderWriter(
1312 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001313 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001314 false /* parcelObjIsPointer */,
1315 arg,
1316 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001317 Type::ErrorMode_Break,
1318 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001319 }
1320
Yifan Hongbf459bc2016-08-23 16:50:37 -07001321 // Second DFS: resolve references
1322 for (const auto &arg : method->args()) {
1323 emitCppResolveReferences(
1324 out,
1325 "_hidl_data",
1326 false /* parcelObjIsPointer */,
1327 arg,
1328 true /* reader */,
1329 Type::ErrorMode_Break,
1330 false /* addPrefixToName */);
1331 }
1332
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001333 status_t status = generateCppInstrumentationCall(
1334 out,
1335 InstrumentationEvent::SERVER_API_ENTRY,
1336 iface,
1337 method);
1338 if (status != OK) {
1339 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001340 }
1341
Andreas Huber881227d2016-08-02 14:20:21 -07001342 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001343 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001344
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001345 if (elidedReturn != nullptr) {
1346 std::string extra;
Andreas Huber881227d2016-08-02 14:20:21 -07001347
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001348 out << elidedReturn->type().getCppResultType(&extra) << " ";
1349 out << elidedReturn->name() << " = ";
1350 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001351
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001352 bool first = true;
1353 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001354 if (!first) {
1355 out << ", ";
1356 }
1357
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001358 if (arg->type().resultNeedsDeref()) {
1359 out << "*";
1360 }
1361
1362 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001363
1364 first = false;
1365 }
1366
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001367 out << ");\n\n";
Andreas Huber8a82ff72016-08-04 10:29:39 -07001368 out << "::android::hardware::Status::ok()"
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001369 << ".writeToParcel(_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001370
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001371 elidedReturn->type().emitReaderWriter(
1372 out,
1373 elidedReturn->name(),
1374 "_hidl_reply",
1375 true, /* parcelObjIsPointer */
1376 false, /* isReader */
1377 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001378
Yifan Hongbf459bc2016-08-23 16:50:37 -07001379 emitCppResolveReferences(
1380 out,
1381 "_hidl_reply",
1382 true /* parcelObjIsPointer */,
1383 elidedReturn,
1384 false /* reader */,
1385 Type::ErrorMode_Ignore,
1386 false /* addPrefixToName */);
1387
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001388 status_t status = generateCppInstrumentationCall(
1389 out,
1390 InstrumentationEvent::SERVER_API_EXIT,
1391 iface,
1392 method);
1393 if (status != OK) {
1394 return status;
1395 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001396
Iliyan Malchev549e2592016-08-10 08:59:12 -07001397 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001398 } else {
1399 if (returnsValue) {
1400 out << "bool _hidl_callbackCalled = false;\n\n";
1401 }
Andreas Huber881227d2016-08-02 14:20:21 -07001402
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001403 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001404
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001405 bool first = true;
1406 for (const auto &arg : method->args()) {
1407 if (!first) {
1408 out << ", ";
1409 }
Andreas Huber881227d2016-08-02 14:20:21 -07001410
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001411 if (arg->type().resultNeedsDeref()) {
1412 out << "*";
1413 }
1414
1415 out << arg->name();
1416
1417 first = false;
1418 }
1419
1420 if (returnsValue) {
1421 if (!first) {
1422 out << ", ";
1423 }
1424
1425 out << "[&](";
1426
1427 first = true;
1428 for (const auto &arg : method->results()) {
1429 if (!first) {
1430 out << ", ";
1431 }
1432
1433 out << "const auto &" << arg->name();
1434
1435 first = false;
1436 }
1437
1438 out << ") {\n";
1439 out.indent();
1440 out << "_hidl_callbackCalled = true;\n\n";
1441
1442 out << "::android::hardware::Status::ok()"
1443 << ".writeToParcel(_hidl_reply);\n\n";
1444
Yifan Hongbf459bc2016-08-23 16:50:37 -07001445 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001446 for (const auto &arg : method->results()) {
1447 emitCppReaderWriter(
1448 out,
1449 "_hidl_reply",
1450 true /* parcelObjIsPointer */,
1451 arg,
1452 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001453 Type::ErrorMode_Ignore,
1454 false /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001455 }
1456
Yifan Hongbf459bc2016-08-23 16:50:37 -07001457 // Second DFS: resolve references
1458 for (const auto &arg : method->results()) {
1459 emitCppResolveReferences(
1460 out,
1461 "_hidl_reply",
1462 true /* parcelObjIsPointer */,
1463 arg,
1464 false /* reader */,
1465 Type::ErrorMode_Ignore,
1466 false /* addPrefixToName */);
1467 }
1468
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001469 status_t status = generateCppInstrumentationCall(
1470 out,
1471 InstrumentationEvent::SERVER_API_EXIT,
1472 iface,
1473 method);
1474 if (status != OK) {
1475 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001476 }
1477
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001478 out << "_hidl_cb(*_hidl_reply);\n";
1479
1480 out.unindent();
1481 out << "}\n";
1482 }
1483
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001484 out << ");\n\n";
1485
1486 // What to do if the stub implementation has a synchronous callback
1487 // which does not get invoked? This is not a transport error but a
1488 // service error of sorts. For now, return OK to the caller, as this is
1489 // not a transport error.
1490 //
1491 // TODO(b/31365311) Figure out how to deal with this later.
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001492
1493 if (returnsValue) {
1494 out << "if (!_hidl_callbackCalled) {\n";
1495 out.indent();
1496 }
1497
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001498 out << "::android::hardware::Status::ok()"
1499 << ".writeToParcel(_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001500
1501 if (returnsValue) {
1502 out.unindent();
1503 out << "}\n\n";
1504 }
Andreas Huber881227d2016-08-02 14:20:21 -07001505 }
1506
1507 out << "break;\n";
1508
1509 return OK;
1510}
1511
Steven Moreland69e7c702016-09-09 11:16:32 -07001512status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1513 std::string ifaceName;
1514 if (!AST::isInterface(&ifaceName)) {
1515 // types.hal does not get a stub header.
1516 return OK;
1517 }
1518
1519 const Interface *iface = mRootScope->getInterface();
1520
1521 const std::string baseName = iface->getBaseName();
1522 const std::string klassName = "Bs" + baseName;
1523
1524 bool supportOneway = iface->hasOnewayMethods();
1525
1526 std::string path = outputPath;
1527 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1528 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1529 path.append(klassName);
1530 path.append(".h");
1531
1532 CHECK(Coordinator::MakeParentHierarchy(path));
1533 FILE *file = fopen(path.c_str(), "w");
1534
1535 if (file == NULL) {
1536 return -errno;
1537 }
1538
1539 Formatter out(file);
1540
1541 const std::string guard = makeHeaderGuard(klassName);
1542
1543 out << "#ifndef " << guard << "\n";
1544 out << "#define " << guard << "\n\n";
1545
1546 std::vector<std::string> packageComponents;
1547 getPackageAndVersionComponents(
1548 &packageComponents, false /* cpp_compatible */);
1549
1550 out << "#include <future>\n";
1551 out << "#include <";
1552 for (const auto &component : packageComponents) {
1553 out << component << "/";
1554 }
1555 out << ifaceName << ".h>\n\n";
1556
1557 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001558 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001559 }
1560
1561 enterLeaveNamespace(out, true /* enter */);
1562 out << "\n";
1563
1564 out << "struct "
1565 << klassName
1566 << " : " << ifaceName
1567 << " {\n";
1568
1569 out.indent();
1570 out << "explicit "
1571 << klassName
1572 << "(const sp<"
1573 << ifaceName
1574 << "> impl);\n";
1575
1576 status_t err = generateMethods(out,
1577 "" /* class name */,
1578 MethodLocation::PASSTHROUGH_HEADER,
1579 true /* specify namespaces */);
1580
1581 if (err != OK) {
1582 return err;
1583 }
1584
1585 out.unindent();
1586 out << "private:\n";
1587 out.indent();
1588 out << "const sp<" << ifaceName << "> mImpl;\n";
1589
1590 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001591 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001592
1593 out << "\n";
1594
1595 out << "::android::hardware::Return<void> addOnewayTask("
1596 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001597 }
1598
1599 out.unindent();
1600
1601 out << "};\n\n";
1602
1603 enterLeaveNamespace(out, false /* enter */);
1604
1605 out << "\n#endif // " << guard << "\n";
1606
1607 return OK;
1608}
1609
Yifan Hongfe95aa22016-10-19 17:26:45 -07001610status_t AST::generateInterfaceSource(Formatter &out) const {
1611 const Interface *iface = mRootScope->getInterface();
1612
1613 if (!iface->isRootType()) {
1614 std::string childTypeExtra;
1615 std::string childTypeResult = iface->getCppResultType(&childTypeExtra);
1616 childTypeResult += childTypeExtra;
1617
1618 for (const Interface *superType : iface->superTypeChain()) {
1619 std::string superTypeExtra;
1620 out << "// static \n"
1621 << childTypeResult
1622 << " I"
1623 << iface->getBaseName()
1624 << "::castFrom("
1625 << superType->getCppArgumentType(&superTypeExtra)
1626 << " parent"
1627 << superTypeExtra
1628 << ")";
1629 out << " {\n";
1630 out.indent();
1631 out << "return ::android::hardware::castInterface<";
1632 out << "I" << iface->getBaseName() << ", "
1633 << superType->fqName().cppName() << ", "
1634 << "Bp" << iface->getBaseName()
1635 << ">(\n";
1636 out.indent();
1637 out.indent();
1638 out << "parent, \""
1639 << iface->fqName().string()
1640 << "\");\n";
1641 out.unindent();
1642 out.unindent();
1643 out.unindent();
1644 out << "}\n\n";
1645 }
1646 }
1647
1648 return OK;
1649}
1650
Steven Moreland69e7c702016-09-09 11:16:32 -07001651status_t AST::generatePassthroughSource(Formatter &out) const {
1652 const Interface *iface = mRootScope->getInterface();
1653
1654 const std::string baseName = iface->getBaseName();
1655 const std::string klassName = "Bs" + baseName;
1656
1657 out << klassName
1658 << "::"
1659 << klassName
1660 << "(const sp<"
1661 << iface->fullName()
Yifan Hong2cbc1472016-10-25 19:02:40 -07001662 << "> impl) : mImpl(impl) {";
1663 if (iface->hasOnewayMethods()) {
1664 out << "\n";
1665 out.indentBlock([&] {
1666 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1667 });
1668 }
1669 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001670
1671 if (iface->hasOnewayMethods()) {
1672 out << "::android::hardware::Return<void> "
1673 << klassName
1674 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1675 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001676 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001677 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001678 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1679 out.indent();
1680 out.indent();
1681 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1682 out.unindent();
1683 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001684 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001685 out << "}\n";
1686
Steven Morelandd366c262016-10-11 15:29:10 -07001687 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001688
1689 out.unindent();
1690 out << "}\n\n";
1691
1692
1693 }
1694
1695 return OK;
1696}
1697
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001698status_t AST::generateCppInstrumentationCall(
1699 Formatter &out,
1700 InstrumentationEvent event,
1701 const Interface *iface, const Method *method) const {
1702 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1703 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001704 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001705 std::string event_str = "";
1706 switch (event) {
1707 case SERVER_API_ENTRY:
1708 {
1709 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1710 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001711 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001712 << (arg->type().resultNeedsDeref() ? "" : "&")
1713 << arg->name()
1714 << ");\n";
1715 }
1716 break;
1717 }
1718 case SERVER_API_EXIT:
1719 {
1720 event_str = "InstrumentationEvent::SERVER_API_EXIT";
1721 const TypedVar *elidedReturn = method->canElideCallback();
1722 if (elidedReturn != nullptr) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001723 out << "_hidl_args.push_back((void *)&"
1724 << elidedReturn->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001725 << ");\n";
1726 } else {
1727 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001728 out << "_hidl_args.push_back((void *)&"
1729 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001730 << ");\n";
1731 }
1732 }
1733 break;
1734 }
1735 case CLIENT_API_ENTRY:
1736 {
1737 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1738 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001739 out << "_hidl_args.push_back((void *)&"
1740 << arg->name()
1741 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001742 }
1743 break;
1744 }
1745 case CLIENT_API_EXIT:
1746 {
1747 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1748 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001749 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001750 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001751 << "_hidl_out_"
1752 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001753 << ");\n";
1754 }
1755 break;
1756 }
1757 case SYNC_CALLBACK_ENTRY:
1758 case SYNC_CALLBACK_EXIT:
1759 case ASYNC_CALLBACK_ENTRY:
1760 case ASYNC_CALLBACK_EXIT:
1761 {
1762 LOG(ERROR) << "Not supported instrumentation event: " << event;
1763 return UNKNOWN_ERROR;
1764 }
1765 }
1766
1767 out << "for (auto callback: mInstrumentationCallbacks) {\n";
1768 out.indent();
1769 out << "callback("
1770 << event_str
1771 << ", \""
1772 << mPackage.package()
1773 << "\", \""
1774 << mPackage.getPackageFullVersion()
1775 << "\", \""
1776 << iface->localName()
1777 << "\", \""
1778 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001779 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001780 out.unindent();
1781 out << "}\n";
1782 out.unindent();
1783 out << "}\n\n";
1784
1785 return OK;
1786}
1787
Andreas Huber881227d2016-08-02 14:20:21 -07001788} // namespace android
1789