blob: 95176f9995fbc2ae62489aa92555be1ee3a3d9f3 [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>
Steven Moreland5708edf2016-11-04 15:33:31 +000028#include <hidl-util/StringHelper.h>
Andreas Huber881227d2016-08-02 14:20:21 -070029#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070030#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070031#include <vector>
32
33namespace android {
34
Andreas Huberb82318c2016-08-02 14:45:54 -070035status_t AST::generateCpp(const std::string &outputPath) const {
36 status_t err = generateInterfaceHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070037
38 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070039 err = generateStubHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070040 }
41
42 if (err == OK) {
Steven Moreland40786312016-08-16 10:29:40 -070043 err = generateHwBinderHeader(outputPath);
44 }
45
46 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070047 err = generateProxyHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070048 }
49
50 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070051 err = generateAllSource(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070052 }
53
Steven Moreland69e7c702016-09-09 11:16:32 -070054 if (err == OK) {
55 generatePassthroughHeader(outputPath);
56 }
57
Andreas Huber881227d2016-08-02 14:20:21 -070058 return err;
59}
60
Andreas Huber737080b2016-08-02 15:38:04 -070061void AST::getPackageComponents(
62 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070063 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070064}
65
66void AST::getPackageAndVersionComponents(
67 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070068 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070069}
70
Steven Moreland5708edf2016-11-04 15:33:31 +000071std::string AST::makeHeaderGuard(const std::string &baseName,
72 bool indicateGenerated) const {
73 std::string guard;
Andreas Huber881227d2016-08-02 14:20:21 -070074
Steven Moreland5708edf2016-11-04 15:33:31 +000075 if (indicateGenerated) {
76 guard += "HIDL_GENERATED_";
77 }
78
79 guard += StringHelper::Uppercase(mPackage.tokenName());
Andreas Huber881227d2016-08-02 14:20:21 -070080 guard += "_";
Steven Moreland5708edf2016-11-04 15:33:31 +000081 guard += StringHelper::Uppercase(baseName);
82 guard += "_H";
Andreas Huber881227d2016-08-02 14:20:21 -070083
84 return guard;
85}
86
Steven Morelandee88eed2016-10-31 17:49:00 -070087// static
88void AST::generateCppPackageInclude(
89 Formatter &out,
90 const FQName &package,
91 const std::string &klass) {
92
93 out << "#include <";
94
95 std::vector<std::string> components;
96 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
97
98 for (const auto &component : components) {
99 out << component << "/";
100 }
101
102 out << klass
103 << ".h>\n";
104}
105
Andreas Huber881227d2016-08-02 14:20:21 -0700106void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
107 std::vector<std::string> packageComponents;
108 getPackageAndVersionComponents(
109 &packageComponents, true /* cpp_compatible */);
110
111 if (enter) {
112 for (const auto &component : packageComponents) {
113 out << "namespace " << component << " {\n";
114 }
Andreas Huber0e00de42016-08-03 09:56:02 -0700115
Andreas Huber2831d512016-08-15 09:33:47 -0700116 out.setNamespace(mPackage.cppNamespace() + "::");
Andreas Huber881227d2016-08-02 14:20:21 -0700117 } else {
Andreas Huber0e00de42016-08-03 09:56:02 -0700118 out.setNamespace(std::string());
119
Andreas Huber881227d2016-08-02 14:20:21 -0700120 for (auto it = packageComponents.rbegin();
121 it != packageComponents.rend();
122 ++it) {
123 out << "} // namespace " << *it << "\n";
124 }
125 }
126}
127
Andreas Huberb82318c2016-08-02 14:45:54 -0700128status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700129
Andreas Huberb82318c2016-08-02 14:45:54 -0700130 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700131 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700132 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700133
134 std::string ifaceName;
135 bool isInterface = true;
136 if (!AST::isInterface(&ifaceName)) {
137 ifaceName = "types";
138 isInterface = false;
139 }
140 path.append(ifaceName);
141 path.append(".h");
142
Andreas Huberd2943e12016-08-05 11:59:31 -0700143 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700144 FILE *file = fopen(path.c_str(), "w");
145
146 if (file == NULL) {
147 return -errno;
148 }
149
150 Formatter out(file);
151
152 const std::string guard = makeHeaderGuard(ifaceName);
153
154 out << "#ifndef " << guard << "\n";
155 out << "#define " << guard << "\n\n";
156
Andreas Huber737080b2016-08-02 15:38:04 -0700157 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700158 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700159 }
160
161 if (!mImportedNames.empty()) {
162 out << "\n";
163 }
164
Martijn Coenen7473fab2016-08-19 14:05:40 +0200165 out << "#include <hidl/HidlSupport.h>\n";
Steven Moreland19d5c172016-10-20 19:20:25 -0700166 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700167 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700168
169 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200170 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700171 }
172
173 out << "#include <utils/NativeHandle.h>\n\n";
174
175 enterLeaveNamespace(out, true /* enter */);
176 out << "\n";
177
178 if (isInterface) {
179 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700180 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700181
182 const Interface *iface = mRootScope->getInterface();
183 const Interface *superType = iface->superType();
184
Steven Moreland40786312016-08-16 10:29:40 -0700185 if (superType == NULL) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700186 out << " : virtual public ::android::hardware::IHidlInterfaceBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700187 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000188 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700189 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700190 }
191
192 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700193
194 out.indent();
195
Andreas Huber881227d2016-08-02 14:20:21 -0700196 }
197
198 status_t err = emitTypeDeclarations(out);
199
200 if (err != OK) {
201 return err;
202 }
203
204 if (isInterface) {
205 const Interface *iface = mRootScope->getInterface();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700206 const Interface *superType = iface->superType();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700207 const std::string baseName = iface->getBaseName();
Steven Moreland19d5c172016-10-20 19:20:25 -0700208 out << "constexpr static ::android::hardware::hidl_version version = {"
Martijn Coenena21f1492016-09-08 15:55:14 +0200209 << mPackage.getPackageMajorVersion() << ","
210 << mPackage.getPackageMinorVersion() << "};\n";
Steven Moreland19d5c172016-10-20 19:20:25 -0700211 out << "virtual const ::android::hardware::hidl_version&"
212 << "getInterfaceVersion() const {\n";
Martijn Coenena21f1492016-09-08 15:55:14 +0200213 out.indent();
214 out << "return version;\n";
215 out.unindent();
216 out << "}\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700217 out << "virtual bool isRemote() const override { return false; }\n\n";
Yifan Hong2d7126b2016-10-20 15:12:57 -0700218 out << "virtual ::android::sp<::android::hardware::IBinder> "
219 << "toBinder() override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700220 bool haveCallbacks = false;
221 for (const auto &method : iface->methods()) {
222 const bool returnsValue = !method->results().empty();
223
224 if (!returnsValue) {
225 continue;
226 }
227
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700228 if (method->canElideCallback() != nullptr) {
229 continue;
230 }
231
Andreas Huber881227d2016-08-02 14:20:21 -0700232 haveCallbacks = true;
233
234 out << "using "
235 << method->name()
236 << "_cb = std::function<void("
Steven Moreland979e0992016-09-07 09:18:08 -0700237 << Method::GetArgSignature(method->results(),
238 true /* specify namespaces */)
Andreas Huber881227d2016-08-02 14:20:21 -0700239 << ")>;\n";
240 }
241
242 if (haveCallbacks) {
243 out << "\n";
244 }
245
246 for (const auto &method : iface->methods()) {
247 const bool returnsValue = !method->results().empty();
248
Andreas Huber3599d922016-08-09 10:42:57 -0700249 method->dumpAnnotations(out);
250
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700251 const TypedVar *elidedReturn = method->canElideCallback();
252 if (elidedReturn) {
253 std::string extra;
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700254 out << "virtual ::android::hardware::Return<";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700255 out << elidedReturn->type().getCppResultType(&extra) << "> ";
256 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700257 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700258 }
259
260 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700261 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700262 << Method::GetArgSignature(method->args(),
263 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700264
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700265 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700266 if (!method->args().empty()) {
267 out << ", ";
268 }
269
Steven Moreland67f67b42016-09-29 08:59:02 -0700270 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700271 }
272
Yifan Hong10fe0b52016-10-19 14:20:17 -0700273 out << ")";
274 if (method->isHidlReserved()) {
275 out << " override";
276 out << " {\n";
277 out.indent();
278 method->cppImpl(out);
279 out.unindent();
280 out << "\n}\n";
281 } else {
282 out << " = 0;\n";
283 }
Andreas Huber881227d2016-08-02 14:20:21 -0700284 }
Steven Moreland40786312016-08-16 10:29:40 -0700285
Yifan Hongfe95aa22016-10-19 17:26:45 -0700286 if (!iface->isRootType()) {
287 out << "// cast static functions\n";
288 std::string childTypeExtra;
289 std::string childTypeResult = iface->getCppResultType(&childTypeExtra);
290 childTypeResult += childTypeExtra;
291
292 for (const Interface *superType : iface->superTypeChain()) {
293 std::string superTypeExtra;
294 out << "static "
295 << childTypeResult
296 << " castFrom("
297 << superType->getCppArgumentType(&superTypeExtra)
298 << " parent"
299 << superTypeExtra
300 << ");\n";
301 }
302 }
303
Yifan Hong10fe0b52016-10-19 14:20:17 -0700304 out << "\nstatic const ::android::String16 descriptor;\n\n";
305
Steven Moreland40786312016-08-16 10:29:40 -0700306 out << "DECLARE_REGISTER_AND_GET_SERVICE(" << baseName << ")\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700307 }
308
309 if (isInterface) {
310 out.unindent();
311
Andreas Hubere3f769a2016-10-10 10:54:44 -0700312 out << "};\n\n";
313 }
314
315 err = mRootScope->emitGlobalTypeDeclarations(out);
316
317 if (err != OK) {
318 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700319 }
320
321 out << "\n";
322 enterLeaveNamespace(out, false /* enter */);
323
324 out << "\n#endif // " << guard << "\n";
325
326 return OK;
327}
328
Steven Moreland40786312016-08-16 10:29:40 -0700329status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
330 std::string ifaceName;
331 if(!AST::isInterface(&ifaceName)) {
332 // types.hal does not get an HwBinder header.
333 return OK;
334 }
335
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700336 const Interface *iface = mRootScope->getInterface();
337 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700338
339 const std::string klassName = "IHw" + baseName;
340
341 std::string path = outputPath;
342 path.append(mCoordinator->convertPackageRootToPath(mPackage));
343 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
344 path.append(klassName + ".h");
345
346 FILE* file = fopen(path.c_str(), "w");
347
348 if (file == NULL) {
349 return -errno;
350 }
351
352 Formatter out(file);
353
354 const std::string guard = makeHeaderGuard(klassName);
355
356 out << "#ifndef " << guard << "\n";
357 out << "#define " << guard << "\n\n";
358
Steven Morelandee88eed2016-10-31 17:49:00 -0700359 generateCppPackageInclude(out, mPackage, ifaceName);
Steven Moreland40786312016-08-16 10:29:40 -0700360
Steven Morelandee88eed2016-10-31 17:49:00 -0700361 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700362
363 for (const auto &item : mImportedNames) {
364 if (item.name() == "types") {
365 continue;
366 }
367
Steven Morelandee88eed2016-10-31 17:49:00 -0700368 generateCppPackageInclude(out, item, "Bn" + item.getInterfaceBaseName());
Steven Moreland40786312016-08-16 10:29:40 -0700369 }
370
371 out << "\n";
372
373 out << "#include <hidl/HidlSupport.h>\n";
Martijn Coenen93915102016-09-01 01:35:52 +0200374 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700375 out << "#include <hwbinder/IBinder.h>\n";
376 out << "#include <hwbinder/IInterface.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700377
378 out << "\n";
379
380 enterLeaveNamespace(out, true /* enter */);
381 out << "\n";
382
383 out << "struct "
384 << klassName
385 << " : public "
386 << ifaceName;
387
Steven Moreland40786312016-08-16 10:29:40 -0700388 const Interface *superType = iface->superType();
389
390 out << ", public ::android::hardware::IInterface";
391
392 out << " {\n";
393
394 out.indent();
395
396 out << "DECLARE_HWBINDER_META_INTERFACE(" << baseName << ");\n\n";
397
Steven Moreland40786312016-08-16 10:29:40 -0700398 out.unindent();
399
400 out << "};\n\n";
401
402 enterLeaveNamespace(out, false /* enter */);
403
404 out << "\n#endif // " << guard << "\n";
405
406 return OK;
407}
408
Andreas Huber881227d2016-08-02 14:20:21 -0700409status_t AST::emitTypeDeclarations(Formatter &out) const {
410 return mRootScope->emitTypeDeclarations(out);
411}
412
Steven Morelanda7a421a2016-09-07 08:35:18 -0700413status_t AST::generateStubMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700414 const Method *method) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700415 out << "inline ";
416
Yifan Hong068c5522016-10-31 14:07:25 -0700417 method->generateCppSignature(out);
Steven Morelanda7a421a2016-09-07 08:35:18 -0700418
419 const bool returnsValue = !method->results().empty();
420 const TypedVar *elidedReturn = method->canElideCallback();
421 out << " {\n";
422 out.indent();
423 out << "return mImpl->"
424 << method->name()
425 << "(";
426 bool first = true;
427 for (const auto &arg : method->args()) {
428 if (!first) {
429 out << ", ";
430 }
431 first = false;
432 out << arg->name();
433 }
434 if (returnsValue && elidedReturn == nullptr) {
435 if (!method->args().empty()) {
436 out << ", ";
437 }
438
439 out << "_hidl_cb";
440 }
441 out << ");\n";
442 out.unindent();
443 out << "}";
444
445 out << ";\n";
446
447 return OK;
448}
449
Steven Moreland69e7c702016-09-09 11:16:32 -0700450status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700451 const Method *method) const {
452 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700453
454 out << " {\n";
455 out.indent();
456
457 const bool returnsValue = !method->results().empty();
458 const TypedVar *elidedReturn = method->canElideCallback();
459
Steven Moreland67f67b42016-09-29 08:59:02 -0700460 if (returnsValue && elidedReturn == nullptr) {
461 generateCheckNonNull(out, "_hidl_cb");
462 }
463
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700464 generateCppInstrumentationCall(
465 out,
466 InstrumentationEvent::PASSTHROUGH_ENTRY,
467 method);
468
469 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700470
471 if (method->isOneway()) {
472 out << "addOnewayTask([this";
473 for (const auto &arg : method->args()) {
474 out << ", " << arg->name();
475 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700476 out << "] {\n";
477 out.indent();
478 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700479 }
480
481 out << "mImpl->"
482 << method->name()
483 << "(";
484
485 bool first = true;
486 for (const auto &arg : method->args()) {
487 if (!first) {
488 out << ", ";
489 }
490 first = false;
491 out << arg->name();
492 }
493 if (returnsValue && elidedReturn == nullptr) {
494 if (!method->args().empty()) {
495 out << ", ";
496 }
497
498 out << "_hidl_cb";
499 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700500 out << ");\n\n";
501
502 generateCppInstrumentationCall(
503 out,
504 InstrumentationEvent::PASSTHROUGH_EXIT,
505 method);
Steven Moreland69e7c702016-09-09 11:16:32 -0700506
507 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700508 out.unindent();
509 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700510 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700511
512 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700513
514 out.unindent();
515 out << "}\n";
516
517 return OK;
518}
519
Yifan Hong068c5522016-10-31 14:07:25 -0700520status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700521
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700522 const Interface *iface = mRootScope->getInterface();
523
Yifan Hong10fe0b52016-10-19 14:20:17 -0700524 const Interface *prevIterface = nullptr;
525 for (const auto &tuple : iface->allMethodsFromRoot()) {
526 const Method *method = tuple.method();
527 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700528
Yifan Hong10fe0b52016-10-19 14:20:17 -0700529 if(prevIterface != superInterface) {
530 if (prevIterface != nullptr) {
531 out << "\n";
532 }
533 out << "// Methods from "
534 << superInterface->fullName()
535 << " follow.\n";
536 prevIterface = superInterface;
537 }
Yifan Hong068c5522016-10-31 14:07:25 -0700538 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700539
Yifan Hong10fe0b52016-10-19 14:20:17 -0700540 if (err != OK) {
541 return err;
542 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700543 }
544
Yifan Hong10fe0b52016-10-19 14:20:17 -0700545 out << "\n";
546
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700547 return OK;
548}
549
Andreas Huberb82318c2016-08-02 14:45:54 -0700550status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700551 std::string ifaceName;
552 if (!AST::isInterface(&ifaceName)) {
553 // types.hal does not get a stub header.
554 return OK;
555 }
556
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700557 const Interface *iface = mRootScope->getInterface();
558 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700559 const std::string klassName = "Bn" + baseName;
Andreas Huber881227d2016-08-02 14:20:21 -0700560
Andreas Huberb82318c2016-08-02 14:45:54 -0700561 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700562 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700563 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700564 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700565 path.append(".h");
566
Andreas Huberd2943e12016-08-05 11:59:31 -0700567 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700568 FILE *file = fopen(path.c_str(), "w");
569
570 if (file == NULL) {
571 return -errno;
572 }
573
574 Formatter out(file);
575
Steven Moreland40786312016-08-16 10:29:40 -0700576 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700577
578 out << "#ifndef " << guard << "\n";
579 out << "#define " << guard << "\n\n";
580
Steven Morelandee88eed2016-10-31 17:49:00 -0700581 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
582 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700583
584 enterLeaveNamespace(out, true /* enter */);
585 out << "\n";
586
587 out << "struct "
588 << "Bn"
589 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700590 << " : public ::android::hardware::BnInterface<I"
591 << baseName << ", IHw" << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700592 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700593
594 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700595 out << "explicit Bn"
596 << baseName
597 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
598 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700599 out << "::android::status_t onTransact(\n";
600 out.indent();
601 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700602 out << "uint32_t _hidl_code,\n";
603 out << "const ::android::hardware::Parcel &_hidl_data,\n";
604 out << "::android::hardware::Parcel *_hidl_reply,\n";
605 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700606 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700607 out.unindent();
608 out.unindent();
609
Yifan Hong068c5522016-10-31 14:07:25 -0700610 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
611 return generateStubMethod(out, method);
612 });
Steven Moreland9c387612016-09-07 09:54:26 -0700613
614 if (err != OK) {
615 return err;
616 }
617
Zhuoyao Zhangde578002016-09-07 18:24:17 -0700618
Andreas Huber881227d2016-08-02 14:20:21 -0700619 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700620 out << "};\n\n";
621
622 enterLeaveNamespace(out, false /* enter */);
623
624 out << "\n#endif // " << guard << "\n";
625
626 return OK;
627}
628
Andreas Huberb82318c2016-08-02 14:45:54 -0700629status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700630 std::string ifaceName;
631 if (!AST::isInterface(&ifaceName)) {
632 // types.hal does not get a proxy header.
633 return OK;
634 }
635
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700636 const Interface *iface = mRootScope->getInterface();
637 const std::string baseName = iface->getBaseName();
Andreas Huber881227d2016-08-02 14:20:21 -0700638
Andreas Huberb82318c2016-08-02 14:45:54 -0700639 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700640 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700641 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700642 path.append("Bp");
643 path.append(baseName);
644 path.append(".h");
645
Andreas Huberd2943e12016-08-05 11:59:31 -0700646 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700647 FILE *file = fopen(path.c_str(), "w");
648
649 if (file == NULL) {
650 return -errno;
651 }
652
653 Formatter out(file);
654
655 const std::string guard = makeHeaderGuard("Bp" + baseName);
656
657 out << "#ifndef " << guard << "\n";
658 out << "#define " << guard << "\n\n";
659
660 std::vector<std::string> packageComponents;
661 getPackageAndVersionComponents(
662 &packageComponents, false /* cpp_compatible */);
663
Steven Morelandee88eed2016-10-31 17:49:00 -0700664 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
665 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700666
667 enterLeaveNamespace(out, true /* enter */);
668 out << "\n";
669
670 out << "struct "
671 << "Bp"
672 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700673 << " : public ::android::hardware::BpInterface<IHw"
674 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700675 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700676
677 out.indent();
678
679 out << "explicit Bp"
680 << baseName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700681 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700682 << "\n\n";
683
Yifan Hong10fe0b52016-10-19 14:20:17 -0700684 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700685
Yifan Hong068c5522016-10-31 14:07:25 -0700686 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
687 method->generateCppSignature(out);
688 out << " override;\n";
689 return OK;
690 });
Steven Moreland9c387612016-09-07 09:54:26 -0700691
692 if (err != OK) {
693 return err;
694 }
Andreas Huber881227d2016-08-02 14:20:21 -0700695
696 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700697 out << "};\n\n";
698
699 enterLeaveNamespace(out, false /* enter */);
700
701 out << "\n#endif // " << guard << "\n";
702
703 return OK;
704}
705
Andreas Huberb82318c2016-08-02 14:45:54 -0700706status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700707
Andreas Huberb82318c2016-08-02 14:45:54 -0700708 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700709 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700710 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700711
712 std::string ifaceName;
713 std::string baseName;
714
Yifan Hongfe95aa22016-10-19 17:26:45 -0700715 const Interface *iface = nullptr;
716 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700717 if (!AST::isInterface(&ifaceName)) {
718 baseName = "types";
719 isInterface = false;
720 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700721 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700722 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700723 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700724 }
725
726 path.append(baseName);
727
728 if (baseName != "types") {
729 path.append("All");
730 }
731
732 path.append(".cpp");
733
Andreas Huberd2943e12016-08-05 11:59:31 -0700734 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700735 FILE *file = fopen(path.c_str(), "w");
736
737 if (file == NULL) {
738 return -errno;
739 }
740
741 Formatter out(file);
742
Andreas Huber881227d2016-08-02 14:20:21 -0700743 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700744 // This is a no-op for IServiceManager itself.
745 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
746
Steven Morelandee88eed2016-10-31 17:49:00 -0700747 generateCppPackageInclude(out, mPackage, "Bp" + baseName);
748 generateCppPackageInclude(out, mPackage, "Bn" + baseName);
749 generateCppPackageInclude(out, mPackage, "Bs" + baseName);
Yifan Hongfe95aa22016-10-19 17:26:45 -0700750
751 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700752 generateCppPackageInclude(out,
753 superType->fqName(),
754 "Bp" + superType->getBaseName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700755 }
Andreas Huber881227d2016-08-02 14:20:21 -0700756 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700757 generateCppPackageInclude(out, mPackage, "types");
Andreas Huber881227d2016-08-02 14:20:21 -0700758 }
759
760 out << "\n";
761
762 enterLeaveNamespace(out, true /* enter */);
763 out << "\n";
764
765 status_t err = generateTypeSource(out, ifaceName);
766
767 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700768 const Interface *iface = mRootScope->getInterface();
Steven Moreland19d5c172016-10-20 19:20:25 -0700769 out << "constexpr ::android::hardware::hidl_version "
770 << ifaceName
771 << "::version;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700772
773 // need to be put here, generateStubSource is using this.
774 out << "const ::android::String16 I"
775 << iface->getBaseName()
776 << "::descriptor(\""
777 << iface->fqName().string()
778 << "\");\n\n";
779
Yifan Hongfe95aa22016-10-19 17:26:45 -0700780 err = generateInterfaceSource(out);
781 }
782
783 if (err == OK && isInterface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700784 err = generateProxySource(out, baseName);
785 }
786
787 if (err == OK && isInterface) {
788 err = generateStubSource(out, baseName);
789 }
790
Steven Moreland40786312016-08-16 10:29:40 -0700791 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -0700792 err = generatePassthroughSource(out);
793 }
794
795 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -0700796 const Interface *iface = mRootScope->getInterface();
797
798 out << "IMPLEMENT_REGISTER_AND_GET_SERVICE("
799 << baseName << ", "
800 << "\"" << iface->fqName().package()
Yifan Hong90ea87f2016-11-01 14:25:47 -0700801 << iface->fqName().atVersion() << "-impl.so\""
Steven Moreland9c387612016-09-07 09:54:26 -0700802 << ")\n";
Steven Moreland40786312016-08-16 10:29:40 -0700803 }
804
Andreas Huber881227d2016-08-02 14:20:21 -0700805 enterLeaveNamespace(out, false /* enter */);
806
807 return err;
808}
809
Steven Moreland67f67b42016-09-29 08:59:02 -0700810// static
811void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
812 out << "if (" << nonNull << " == nullptr) {\n";
813 out.indent();
814 out << "return ::android::hardware::Status::fromExceptionCode(\n";
815 out.indent();
816 out.indent();
817 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
818 out.unindent();
819 out.unindent();
820 out.unindent();
821 out << "}\n\n";
822}
823
Andreas Huber881227d2016-08-02 14:20:21 -0700824status_t AST::generateTypeSource(
825 Formatter &out, const std::string &ifaceName) const {
826 return mRootScope->emitTypeDefinitions(out, ifaceName);
827}
828
Andreas Hubere7ff2282016-08-16 13:50:03 -0700829void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -0700830 Formatter &out,
831 const std::vector<TypedVar *> &args,
832 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700833 if (args.empty()) {
834 return;
835 }
836
837 for (const auto &arg : args) {
838 const Type &type = arg->type();
839
840 std::string extra;
841 out << type.getCppResultType(&extra)
842 << " "
Andreas Huber5e44a292016-09-27 14:52:39 -0700843 << (forResults ? "_hidl_out_" : "")
Andreas Hubere7ff2282016-08-16 13:50:03 -0700844 << arg->name()
845 << extra
846 << ";\n";
847 }
848
849 out << "\n";
850}
851
Andreas Huber881227d2016-08-02 14:20:21 -0700852void AST::emitCppReaderWriter(
853 Formatter &out,
854 const std::string &parcelObj,
855 bool parcelObjIsPointer,
856 const TypedVar *arg,
857 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -0700858 Type::ErrorMode mode,
859 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700860 const Type &type = arg->type();
861
Andreas Huber881227d2016-08-02 14:20:21 -0700862 type.emitReaderWriter(
863 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700864 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700865 parcelObj,
866 parcelObjIsPointer,
867 isReader,
868 mode);
869}
870
Yifan Hongbf459bc2016-08-23 16:50:37 -0700871void AST::emitCppResolveReferences(
872 Formatter &out,
873 const std::string &parcelObj,
874 bool parcelObjIsPointer,
875 const TypedVar *arg,
876 bool isReader,
877 Type::ErrorMode mode,
878 bool addPrefixToName) const {
879 const Type &type = arg->type();
880 if(type.needsResolveReferences()) {
881 type.emitResolveReferences(
882 out,
883 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
884 isReader, // nameIsPointer
885 parcelObj,
886 parcelObjIsPointer,
887 isReader,
888 mode);
889 }
890}
891
Yifan Hong068c5522016-10-31 14:07:25 -0700892status_t AST::generateProxyMethodSource(Formatter &out,
893 const std::string &klassName,
894 const Method *method,
895 const Interface *superInterface) const {
896
897 method->generateCppSignature(out,
898 klassName,
899 true /* specify namespaces */);
900
901 const bool returnsValue = !method->results().empty();
902 const TypedVar *elidedReturn = method->canElideCallback();
903
904 out << "{\n";
905
906 out.indent();
907
908 if (returnsValue && elidedReturn == nullptr) {
909 generateCheckNonNull(out, "_hidl_cb");
910 }
911
912 status_t status = generateCppInstrumentationCall(
913 out,
914 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -0700915 method);
916 if (status != OK) {
917 return status;
918 }
919
920 out << "::android::hardware::Parcel _hidl_data;\n";
921 out << "::android::hardware::Parcel _hidl_reply;\n";
922 out << "::android::status_t _hidl_err;\n";
923 out << "::android::hardware::Status _hidl_status;\n\n";
924
925 declareCppReaderLocals(
926 out, method->results(), true /* forResults */);
927
928 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
929 if (!method->isHidlReserved()) {
930 out << superInterface->fqName().cppNamespace()
931 << "::IHw"
932 << superInterface->getBaseName();
933 } else {
934 out << "::android::hardware::IHidlInterfaceBase";
935 }
936 out << "::descriptor);\n";
937
938 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
939
940 // First DFS: write all buffers and resolve pointers for parent
941 for (const auto &arg : method->args()) {
942 emitCppReaderWriter(
943 out,
944 "_hidl_data",
945 false /* parcelObjIsPointer */,
946 arg,
947 false /* reader */,
948 Type::ErrorMode_Goto,
949 false /* addPrefixToName */);
950 }
951
952 // Second DFS: resolve references.
953 for (const auto &arg : method->args()) {
954 emitCppResolveReferences(
955 out,
956 "_hidl_data",
957 false /* parcelObjIsPointer */,
958 arg,
959 false /* reader */,
960 Type::ErrorMode_Goto,
961 false /* addPrefixToName */);
962 }
963
964 out << "_hidl_err = remote()->transact("
965 << method->getSerialId()
966 << " /* "
967 << method->name()
968 << " */, _hidl_data, &_hidl_reply";
969
970 if (method->isOneway()) {
971 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
972 }
973 out << ");\n";
974
975 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
976
977 if (!method->isOneway()) {
978 out << "_hidl_err = _hidl_status.readFromParcel(_hidl_reply);\n";
979 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
980 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
981
982
983 // First DFS: write all buffers and resolve pointers for parent
984 for (const auto &arg : method->results()) {
985 emitCppReaderWriter(
986 out,
987 "_hidl_reply",
988 false /* parcelObjIsPointer */,
989 arg,
990 true /* reader */,
991 Type::ErrorMode_Goto,
992 true /* addPrefixToName */);
993 }
994
995 // Second DFS: resolve references.
996 for (const auto &arg : method->results()) {
997 emitCppResolveReferences(
998 out,
999 "_hidl_reply",
1000 false /* parcelObjIsPointer */,
1001 arg,
1002 true /* reader */,
1003 Type::ErrorMode_Goto,
1004 true /* addPrefixToName */);
1005 }
1006
1007 if (returnsValue && elidedReturn == nullptr) {
1008 out << "_hidl_cb(";
1009
1010 bool first = true;
1011 for (const auto &arg : method->results()) {
1012 if (!first) {
1013 out << ", ";
1014 }
1015
1016 if (arg->type().resultNeedsDeref()) {
1017 out << "*";
1018 }
1019 out << "_hidl_out_" << arg->name();
1020
1021 first = false;
1022 }
1023
1024 out << ");\n\n";
1025 }
1026 status_t status = generateCppInstrumentationCall(
1027 out,
1028 InstrumentationEvent::CLIENT_API_EXIT,
Yifan Hong068c5522016-10-31 14:07:25 -07001029 method);
1030 if (status != OK) {
1031 return status;
1032 }
1033 }
1034
1035 if (elidedReturn != nullptr) {
1036 std::string extra;
1037 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1038 out << "return ::android::hardware::Return<";
1039 out << elidedReturn->type().getCppResultType(&extra)
1040 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1041 } else {
1042 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1043 out << "return ::android::hardware::Return<void>();\n\n";
1044 }
1045
1046 out.unindent();
1047 out << "_hidl_error:\n";
1048 out.indent();
1049 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1050 out << "return ::android::hardware::Return<";
1051 if (elidedReturn != nullptr) {
1052 std::string extra;
1053 out << method->results().at(0)->type().getCppResultType(&extra);
1054 } else {
1055 out << "void";
1056 }
1057 out << ">(_hidl_status);\n";
1058
1059 out.unindent();
1060 out << "}\n\n";
1061 return OK;
1062}
1063
Andreas Huber881227d2016-08-02 14:20:21 -07001064status_t AST::generateProxySource(
1065 Formatter &out, const std::string &baseName) const {
1066 const std::string klassName = "Bp" + baseName;
1067
1068 out << klassName
1069 << "::"
1070 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001071 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001072
1073 out.indent();
1074 out.indent();
1075
1076 out << ": BpInterface"
Steven Moreland40786312016-08-16 10:29:40 -07001077 << "<IHw"
Andreas Huber881227d2016-08-02 14:20:21 -07001078 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001079 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001080 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001081 << mPackage.string()
1082 << "::I"
1083 << baseName
1084 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001085
Andreas Huber881227d2016-08-02 14:20:21 -07001086 out.unindent();
1087 out.unindent();
1088 out << "}\n\n";
1089
Yifan Hong068c5522016-10-31 14:07:25 -07001090 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1091 return generateProxyMethodSource(out, klassName, method, superInterface);
1092 });
Andreas Huber881227d2016-08-02 14:20:21 -07001093
Yifan Hong068c5522016-10-31 14:07:25 -07001094 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001095}
1096
1097status_t AST::generateStubSource(
1098 Formatter &out, const std::string &baseName) const {
1099 out << "IMPLEMENT_HWBINDER_META_INTERFACE("
1100 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001101 << ", "
1102 << mPackage.cppNamespace()
Andreas Huber881227d2016-08-02 14:20:21 -07001103 << "::I"
1104 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001105 << "::descriptor);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001106
1107 const std::string klassName = "Bn" + baseName;
1108
Steven Moreland40786312016-08-16 10:29:40 -07001109 out << klassName
1110 << "::"
1111 << klassName
1112 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl)\n";
1113
1114 out.indent();
1115 out.indent();
1116
1117 out << ": BnInterface"
1118 << "<I"
1119 << baseName
1120 << ", IHw"
1121 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001122 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001123 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001124 << mPackage.string()
1125 << "::I"
1126 << baseName
1127 << "\") {\n";
Steven Moreland40786312016-08-16 10:29:40 -07001128
1129 out.unindent();
1130 out.unindent();
1131 out << "}\n\n";
1132
Andreas Huber881227d2016-08-02 14:20:21 -07001133 out << "::android::status_t " << klassName << "::onTransact(\n";
1134
1135 out.indent();
1136 out.indent();
1137
Iliyan Malchev549e2592016-08-10 08:59:12 -07001138 out << "uint32_t _hidl_code,\n"
1139 << "const ::android::hardware::Parcel &_hidl_data,\n"
1140 << "::android::hardware::Parcel *_hidl_reply,\n"
1141 << "uint32_t _hidl_flags,\n"
1142 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001143
1144 out.unindent();
1145
Iliyan Malchev549e2592016-08-10 08:59:12 -07001146 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001147 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001148 out.indent();
1149
1150 const Interface *iface = mRootScope->getInterface();
1151
Yifan Hong10fe0b52016-10-19 14:20:17 -07001152 for (const auto &tuple : iface->allMethodsFromRoot()) {
1153 const Method *method = tuple.method();
1154 const Interface *superInterface = tuple.interface();
1155 out << "case "
1156 << method->getSerialId()
1157 << " /* "
1158 << method->name()
1159 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001160
Yifan Hong10fe0b52016-10-19 14:20:17 -07001161 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001162
Yifan Hong10fe0b52016-10-19 14:20:17 -07001163 status_t err =
1164 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001165
Yifan Hong10fe0b52016-10-19 14:20:17 -07001166 if (err != OK) {
1167 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001168 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001169
1170 out.unindent();
1171 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001172 }
1173
1174 out << "default:\n{\n";
1175 out.indent();
1176
Andreas Huber8a82ff72016-08-04 10:29:39 -07001177 out << "return ::android::hardware::BnInterface<I"
Steven Moreland40786312016-08-16 10:29:40 -07001178 << baseName << ", IHw" << baseName
Andreas Huber881227d2016-08-02 14:20:21 -07001179 << ">::onTransact(\n";
1180
1181 out.indent();
1182 out.indent();
1183
Iliyan Malchev549e2592016-08-10 08:59:12 -07001184 out << "_hidl_code, _hidl_data, _hidl_reply, "
1185 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001186
1187 out.unindent();
1188 out.unindent();
1189
1190 out.unindent();
1191 out << "}\n";
1192
1193 out.unindent();
1194 out << "}\n\n";
1195
Iliyan Malchev549e2592016-08-10 08:59:12 -07001196 out << "if (_hidl_err == ::android::UNEXPECTED_NULL) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001197 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001198 out << "_hidl_err = ::android::hardware::Status::fromExceptionCode(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001199 out.indent();
1200 out.indent();
Andreas Huber8a82ff72016-08-04 10:29:39 -07001201 out << "::android::hardware::Status::EX_NULL_POINTER)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001202 out.indent();
1203 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001204 out << ".writeToParcel(_hidl_reply);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001205 out.unindent();
1206 out.unindent();
1207 out.unindent();
1208 out.unindent();
1209
1210 out.unindent();
1211 out << "}\n\n";
1212
Iliyan Malchev549e2592016-08-10 08:59:12 -07001213 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001214
1215 out.unindent();
1216 out << "}\n\n";
1217
1218 return OK;
1219}
1220
1221status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001222 Formatter &out, const Interface *iface, const Method *method) const {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001223 out << "if (!_hidl_data.enforceInterface(";
1224
1225 if (!method->isHidlReserved()) {
1226 out << iface->fqName().cppNamespace()
1227 << "::IHw"
1228 << iface->getBaseName();
1229 } else {
1230 out << "::android::hardware::IHidlInterfaceBase";
1231 }
1232
1233 out << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001234
Andreas Huber881227d2016-08-02 14:20:21 -07001235 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001236 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001237 out << "break;\n";
1238 out.unindent();
1239 out << "}\n\n";
1240
Andreas Huber5e44a292016-09-27 14:52:39 -07001241 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001242
Yifan Hongbf459bc2016-08-23 16:50:37 -07001243 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001244 for (const auto &arg : method->args()) {
1245 emitCppReaderWriter(
1246 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001247 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001248 false /* parcelObjIsPointer */,
1249 arg,
1250 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001251 Type::ErrorMode_Break,
1252 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001253 }
1254
Yifan Hongbf459bc2016-08-23 16:50:37 -07001255 // Second DFS: resolve references
1256 for (const auto &arg : method->args()) {
1257 emitCppResolveReferences(
1258 out,
1259 "_hidl_data",
1260 false /* parcelObjIsPointer */,
1261 arg,
1262 true /* reader */,
1263 Type::ErrorMode_Break,
1264 false /* addPrefixToName */);
1265 }
1266
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001267 status_t status = generateCppInstrumentationCall(
1268 out,
1269 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001270 method);
1271 if (status != OK) {
1272 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001273 }
1274
Andreas Huber881227d2016-08-02 14:20:21 -07001275 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001276 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001277
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001278 if (elidedReturn != nullptr) {
1279 std::string extra;
Andreas Huber881227d2016-08-02 14:20:21 -07001280
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001281 out << elidedReturn->type().getCppResultType(&extra) << " ";
1282 out << elidedReturn->name() << " = ";
1283 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001284
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001285 bool first = true;
1286 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001287 if (!first) {
1288 out << ", ";
1289 }
1290
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001291 if (arg->type().resultNeedsDeref()) {
1292 out << "*";
1293 }
1294
1295 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001296
1297 first = false;
1298 }
1299
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001300 out << ");\n\n";
Andreas Huber8a82ff72016-08-04 10:29:39 -07001301 out << "::android::hardware::Status::ok()"
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001302 << ".writeToParcel(_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001303
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001304 elidedReturn->type().emitReaderWriter(
1305 out,
1306 elidedReturn->name(),
1307 "_hidl_reply",
1308 true, /* parcelObjIsPointer */
1309 false, /* isReader */
1310 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001311
Yifan Hongbf459bc2016-08-23 16:50:37 -07001312 emitCppResolveReferences(
1313 out,
1314 "_hidl_reply",
1315 true /* parcelObjIsPointer */,
1316 elidedReturn,
1317 false /* reader */,
1318 Type::ErrorMode_Ignore,
1319 false /* addPrefixToName */);
1320
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001321 status_t status = generateCppInstrumentationCall(
1322 out,
1323 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001324 method);
1325 if (status != OK) {
1326 return status;
1327 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001328
Iliyan Malchev549e2592016-08-10 08:59:12 -07001329 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001330 } else {
1331 if (returnsValue) {
1332 out << "bool _hidl_callbackCalled = false;\n\n";
1333 }
Andreas Huber881227d2016-08-02 14:20:21 -07001334
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001335 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001336
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001337 bool first = true;
1338 for (const auto &arg : method->args()) {
1339 if (!first) {
1340 out << ", ";
1341 }
Andreas Huber881227d2016-08-02 14:20:21 -07001342
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001343 if (arg->type().resultNeedsDeref()) {
1344 out << "*";
1345 }
1346
1347 out << arg->name();
1348
1349 first = false;
1350 }
1351
1352 if (returnsValue) {
1353 if (!first) {
1354 out << ", ";
1355 }
1356
1357 out << "[&](";
1358
1359 first = true;
1360 for (const auto &arg : method->results()) {
1361 if (!first) {
1362 out << ", ";
1363 }
1364
1365 out << "const auto &" << arg->name();
1366
1367 first = false;
1368 }
1369
1370 out << ") {\n";
1371 out.indent();
1372 out << "_hidl_callbackCalled = true;\n\n";
1373
1374 out << "::android::hardware::Status::ok()"
1375 << ".writeToParcel(_hidl_reply);\n\n";
1376
Yifan Hongbf459bc2016-08-23 16:50:37 -07001377 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001378 for (const auto &arg : method->results()) {
1379 emitCppReaderWriter(
1380 out,
1381 "_hidl_reply",
1382 true /* parcelObjIsPointer */,
1383 arg,
1384 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001385 Type::ErrorMode_Ignore,
1386 false /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001387 }
1388
Yifan Hongbf459bc2016-08-23 16:50:37 -07001389 // Second DFS: resolve references
1390 for (const auto &arg : method->results()) {
1391 emitCppResolveReferences(
1392 out,
1393 "_hidl_reply",
1394 true /* parcelObjIsPointer */,
1395 arg,
1396 false /* reader */,
1397 Type::ErrorMode_Ignore,
1398 false /* addPrefixToName */);
1399 }
1400
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001401 status_t status = generateCppInstrumentationCall(
1402 out,
1403 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001404 method);
1405 if (status != OK) {
1406 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001407 }
1408
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001409 out << "_hidl_cb(*_hidl_reply);\n";
1410
1411 out.unindent();
1412 out << "}\n";
1413 }
1414
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001415 out << ");\n\n";
1416
1417 // What to do if the stub implementation has a synchronous callback
1418 // which does not get invoked? This is not a transport error but a
1419 // service error of sorts. For now, return OK to the caller, as this is
1420 // not a transport error.
1421 //
1422 // TODO(b/31365311) Figure out how to deal with this later.
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001423
1424 if (returnsValue) {
1425 out << "if (!_hidl_callbackCalled) {\n";
1426 out.indent();
1427 }
1428
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001429 out << "::android::hardware::Status::ok()"
1430 << ".writeToParcel(_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001431
1432 if (returnsValue) {
1433 out.unindent();
1434 out << "}\n\n";
1435 }
Andreas Huber881227d2016-08-02 14:20:21 -07001436 }
1437
1438 out << "break;\n";
1439
1440 return OK;
1441}
1442
Steven Moreland69e7c702016-09-09 11:16:32 -07001443status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1444 std::string ifaceName;
1445 if (!AST::isInterface(&ifaceName)) {
1446 // types.hal does not get a stub header.
1447 return OK;
1448 }
1449
1450 const Interface *iface = mRootScope->getInterface();
1451
1452 const std::string baseName = iface->getBaseName();
1453 const std::string klassName = "Bs" + baseName;
1454
1455 bool supportOneway = iface->hasOnewayMethods();
1456
1457 std::string path = outputPath;
1458 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1459 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1460 path.append(klassName);
1461 path.append(".h");
1462
1463 CHECK(Coordinator::MakeParentHierarchy(path));
1464 FILE *file = fopen(path.c_str(), "w");
1465
1466 if (file == NULL) {
1467 return -errno;
1468 }
1469
1470 Formatter out(file);
1471
1472 const std::string guard = makeHeaderGuard(klassName);
1473
1474 out << "#ifndef " << guard << "\n";
1475 out << "#define " << guard << "\n\n";
1476
1477 std::vector<std::string> packageComponents;
1478 getPackageAndVersionComponents(
1479 &packageComponents, false /* cpp_compatible */);
1480
1481 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001482
1483 generateCppPackageInclude(out, mPackage, ifaceName);
1484 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001485
1486 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001487 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001488 }
1489
1490 enterLeaveNamespace(out, true /* enter */);
1491 out << "\n";
1492
1493 out << "struct "
1494 << klassName
1495 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001496 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001497
1498 out.indent();
1499 out << "explicit "
1500 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001501 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001502 << ifaceName
1503 << "> impl);\n";
1504
Yifan Hong068c5522016-10-31 14:07:25 -07001505 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1506 return generatePassthroughMethod(out, method);
1507 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001508
1509 if (err != OK) {
1510 return err;
1511 }
1512
1513 out.unindent();
1514 out << "private:\n";
1515 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001516 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001517
1518 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001519 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001520
1521 out << "\n";
1522
1523 out << "::android::hardware::Return<void> addOnewayTask("
1524 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001525 }
1526
1527 out.unindent();
1528
1529 out << "};\n\n";
1530
1531 enterLeaveNamespace(out, false /* enter */);
1532
1533 out << "\n#endif // " << guard << "\n";
1534
1535 return OK;
1536}
1537
Yifan Hongfe95aa22016-10-19 17:26:45 -07001538status_t AST::generateInterfaceSource(Formatter &out) const {
1539 const Interface *iface = mRootScope->getInterface();
1540
Yifan Hong2d7126b2016-10-20 15:12:57 -07001541
1542 // generate toBinder functions
1543 out << "::android::sp<::android::hardware::IBinder> I"
1544 << iface->getBaseName()
1545 << "::toBinder() {\n";
1546 out.indent();
1547 out << "if (isRemote()) {\n";
1548 out.indent();
1549 out << "return ::android::hardware::IInterface::asBinder("
1550 << "static_cast<IHw"
1551 << iface->getBaseName()
1552 << " *>(this));\n";
1553 out.unindent();
1554 out << "} else {\n";
1555 out.indent();
1556 out << "return new Bn" << iface->getBaseName() << "(this);\n";
1557 out.unindent();
1558 out << "}\n";
1559 out.unindent();
1560 out << "}\n\n";
1561
1562 // generate castFrom functions
Yifan Hongfe95aa22016-10-19 17:26:45 -07001563 if (!iface->isRootType()) {
1564 std::string childTypeExtra;
1565 std::string childTypeResult = iface->getCppResultType(&childTypeExtra);
1566 childTypeResult += childTypeExtra;
1567
1568 for (const Interface *superType : iface->superTypeChain()) {
1569 std::string superTypeExtra;
1570 out << "// static \n"
1571 << childTypeResult
1572 << " I"
1573 << iface->getBaseName()
1574 << "::castFrom("
1575 << superType->getCppArgumentType(&superTypeExtra)
1576 << " parent"
1577 << superTypeExtra
1578 << ")";
1579 out << " {\n";
1580 out.indent();
1581 out << "return ::android::hardware::castInterface<";
1582 out << "I" << iface->getBaseName() << ", "
1583 << superType->fqName().cppName() << ", "
1584 << "Bp" << iface->getBaseName()
1585 << ">(\n";
1586 out.indent();
1587 out.indent();
1588 out << "parent, \""
1589 << iface->fqName().string()
1590 << "\");\n";
1591 out.unindent();
1592 out.unindent();
1593 out.unindent();
1594 out << "}\n\n";
1595 }
1596 }
1597
1598 return OK;
1599}
1600
Steven Moreland69e7c702016-09-09 11:16:32 -07001601status_t AST::generatePassthroughSource(Formatter &out) const {
1602 const Interface *iface = mRootScope->getInterface();
1603
1604 const std::string baseName = iface->getBaseName();
1605 const std::string klassName = "Bs" + baseName;
1606
1607 out << klassName
1608 << "::"
1609 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001610 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001611 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001612 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001613 << iface->fqName().string()
1614 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001615 if (iface->hasOnewayMethods()) {
1616 out << "\n";
1617 out.indentBlock([&] {
1618 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1619 });
1620 }
1621 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001622
1623 if (iface->hasOnewayMethods()) {
1624 out << "::android::hardware::Return<void> "
1625 << klassName
1626 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1627 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001628 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001629 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001630 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1631 out.indent();
1632 out.indent();
1633 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1634 out.unindent();
1635 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001636 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001637 out << "}\n";
1638
Steven Morelandd366c262016-10-11 15:29:10 -07001639 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001640
1641 out.unindent();
1642 out << "}\n\n";
1643
1644
1645 }
1646
1647 return OK;
1648}
1649
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001650status_t AST::generateCppInstrumentationCall(
1651 Formatter &out,
1652 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001653 const Method *method) const {
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001654 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1655 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001656 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001657 std::string event_str = "";
1658 switch (event) {
1659 case SERVER_API_ENTRY:
1660 {
1661 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1662 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001663 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001664 << (arg->type().resultNeedsDeref() ? "" : "&")
1665 << arg->name()
1666 << ");\n";
1667 }
1668 break;
1669 }
1670 case SERVER_API_EXIT:
1671 {
1672 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001673 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001674 out << "_hidl_args.push_back((void *)&"
Steven Moreland031ccf12016-10-31 15:54:38 -07001675 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001676 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001677 }
1678 break;
1679 }
1680 case CLIENT_API_ENTRY:
1681 {
1682 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1683 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001684 out << "_hidl_args.push_back((void *)&"
1685 << arg->name()
1686 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001687 }
1688 break;
1689 }
1690 case CLIENT_API_EXIT:
1691 {
1692 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1693 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001694 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001695 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001696 << "_hidl_out_"
1697 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001698 << ");\n";
1699 }
1700 break;
1701 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001702 case PASSTHROUGH_ENTRY:
1703 {
1704 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1705 for (const auto &arg : method->args()) {
1706 out << "_hidl_args.push_back((void *)&"
1707 << arg->name()
1708 << ");\n";
1709 }
1710 break;
1711 }
1712 case PASSTHROUGH_EXIT:
1713 {
1714 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
1715 // TODO(b/32576620): passthrough return values
1716 break;
1717 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001718 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001719 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001720 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001721 return UNKNOWN_ERROR;
1722 }
1723 }
1724
Steven Moreland031ccf12016-10-31 15:54:38 -07001725 const Interface *iface = mRootScope->getInterface();
1726
Steven Moreland1ab31442016-11-03 18:37:51 -07001727 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001728 out.indent();
1729 out << "callback("
1730 << event_str
1731 << ", \""
1732 << mPackage.package()
1733 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07001734 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001735 << "\", \""
1736 << iface->localName()
1737 << "\", \""
1738 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001739 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001740 out.unindent();
1741 out << "}\n";
1742 out.unindent();
1743 out << "}\n\n";
1744
1745 return OK;
1746}
1747
Andreas Huber881227d2016-08-02 14:20:21 -07001748} // namespace android
1749