blob: 6c721da0f25e8c75c78bbcd73ed982f19f6c1e01 [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) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700253 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700254 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700255 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700256 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700257 }
258
259 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700260 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700261 << Method::GetArgSignature(method->args(),
262 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700263
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700264 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700265 if (!method->args().empty()) {
266 out << ", ";
267 }
268
Steven Moreland67f67b42016-09-29 08:59:02 -0700269 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700270 }
271
Yifan Hong10fe0b52016-10-19 14:20:17 -0700272 out << ")";
273 if (method->isHidlReserved()) {
274 out << " override";
275 out << " {\n";
276 out.indent();
277 method->cppImpl(out);
278 out.unindent();
279 out << "\n}\n";
280 } else {
281 out << " = 0;\n";
282 }
Andreas Huber881227d2016-08-02 14:20:21 -0700283 }
Steven Moreland40786312016-08-16 10:29:40 -0700284
Yifan Hongfe95aa22016-10-19 17:26:45 -0700285 if (!iface->isRootType()) {
286 out << "// cast static functions\n";
Yifan Hong3b320f82016-11-01 15:15:54 -0700287 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700288
289 for (const Interface *superType : iface->superTypeChain()) {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700290 out << "static "
291 << childTypeResult
292 << " castFrom("
Yifan Hong3b320f82016-11-01 15:15:54 -0700293 << superType->getCppArgumentType()
Yifan Hongfe95aa22016-10-19 17:26:45 -0700294 << " parent"
Yifan Hongfe95aa22016-10-19 17:26:45 -0700295 << ");\n";
296 }
297 }
298
Yifan Hong10fe0b52016-10-19 14:20:17 -0700299 out << "\nstatic const ::android::String16 descriptor;\n\n";
300
Steven Moreland40786312016-08-16 10:29:40 -0700301 out << "DECLARE_REGISTER_AND_GET_SERVICE(" << baseName << ")\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700302 }
303
304 if (isInterface) {
305 out.unindent();
306
Andreas Hubere3f769a2016-10-10 10:54:44 -0700307 out << "};\n\n";
308 }
309
310 err = mRootScope->emitGlobalTypeDeclarations(out);
311
312 if (err != OK) {
313 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700314 }
315
316 out << "\n";
317 enterLeaveNamespace(out, false /* enter */);
318
319 out << "\n#endif // " << guard << "\n";
320
321 return OK;
322}
323
Steven Moreland40786312016-08-16 10:29:40 -0700324status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
325 std::string ifaceName;
326 if(!AST::isInterface(&ifaceName)) {
327 // types.hal does not get an HwBinder header.
328 return OK;
329 }
330
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700331 const Interface *iface = mRootScope->getInterface();
332 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700333
334 const std::string klassName = "IHw" + baseName;
335
336 std::string path = outputPath;
337 path.append(mCoordinator->convertPackageRootToPath(mPackage));
338 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
339 path.append(klassName + ".h");
340
341 FILE* file = fopen(path.c_str(), "w");
342
343 if (file == NULL) {
344 return -errno;
345 }
346
347 Formatter out(file);
348
349 const std::string guard = makeHeaderGuard(klassName);
350
351 out << "#ifndef " << guard << "\n";
352 out << "#define " << guard << "\n\n";
353
Steven Morelandee88eed2016-10-31 17:49:00 -0700354 generateCppPackageInclude(out, mPackage, ifaceName);
Steven Moreland40786312016-08-16 10:29:40 -0700355
Steven Morelandee88eed2016-10-31 17:49:00 -0700356 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700357
358 for (const auto &item : mImportedNames) {
359 if (item.name() == "types") {
360 continue;
361 }
362
Steven Morelandee88eed2016-10-31 17:49:00 -0700363 generateCppPackageInclude(out, item, "Bn" + item.getInterfaceBaseName());
Steven Moreland40786312016-08-16 10:29:40 -0700364 }
365
366 out << "\n";
367
368 out << "#include <hidl/HidlSupport.h>\n";
Martijn Coenen93915102016-09-01 01:35:52 +0200369 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700370 out << "#include <hwbinder/IBinder.h>\n";
371 out << "#include <hwbinder/IInterface.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700372
373 out << "\n";
374
375 enterLeaveNamespace(out, true /* enter */);
376 out << "\n";
377
378 out << "struct "
379 << klassName
380 << " : public "
381 << ifaceName;
382
Steven Moreland40786312016-08-16 10:29:40 -0700383 const Interface *superType = iface->superType();
384
385 out << ", public ::android::hardware::IInterface";
386
387 out << " {\n";
388
389 out.indent();
390
391 out << "DECLARE_HWBINDER_META_INTERFACE(" << baseName << ");\n\n";
392
Steven Moreland40786312016-08-16 10:29:40 -0700393 out.unindent();
394
395 out << "};\n\n";
396
397 enterLeaveNamespace(out, false /* enter */);
398
399 out << "\n#endif // " << guard << "\n";
400
401 return OK;
402}
403
Andreas Huber881227d2016-08-02 14:20:21 -0700404status_t AST::emitTypeDeclarations(Formatter &out) const {
405 return mRootScope->emitTypeDeclarations(out);
406}
407
Steven Morelanda7a421a2016-09-07 08:35:18 -0700408status_t AST::generateStubMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700409 const Method *method) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700410 out << "inline ";
411
Yifan Hong068c5522016-10-31 14:07:25 -0700412 method->generateCppSignature(out);
Steven Morelanda7a421a2016-09-07 08:35:18 -0700413
414 const bool returnsValue = !method->results().empty();
415 const TypedVar *elidedReturn = method->canElideCallback();
416 out << " {\n";
417 out.indent();
418 out << "return mImpl->"
419 << method->name()
420 << "(";
421 bool first = true;
422 for (const auto &arg : method->args()) {
423 if (!first) {
424 out << ", ";
425 }
426 first = false;
427 out << arg->name();
428 }
429 if (returnsValue && elidedReturn == nullptr) {
430 if (!method->args().empty()) {
431 out << ", ";
432 }
433
434 out << "_hidl_cb";
435 }
436 out << ");\n";
437 out.unindent();
438 out << "}";
439
440 out << ";\n";
441
442 return OK;
443}
444
Steven Moreland69e7c702016-09-09 11:16:32 -0700445status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700446 const Method *method) const {
447 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700448
449 out << " {\n";
450 out.indent();
451
452 const bool returnsValue = !method->results().empty();
453 const TypedVar *elidedReturn = method->canElideCallback();
454
Steven Moreland67f67b42016-09-29 08:59:02 -0700455 if (returnsValue && elidedReturn == nullptr) {
456 generateCheckNonNull(out, "_hidl_cb");
457 }
458
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700459 generateCppInstrumentationCall(
460 out,
461 InstrumentationEvent::PASSTHROUGH_ENTRY,
462 method);
463
464 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700465
466 if (method->isOneway()) {
467 out << "addOnewayTask([this";
468 for (const auto &arg : method->args()) {
469 out << ", " << arg->name();
470 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700471 out << "] {\n";
472 out.indent();
473 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700474 }
475
476 out << "mImpl->"
477 << method->name()
478 << "(";
479
480 bool first = true;
481 for (const auto &arg : method->args()) {
482 if (!first) {
483 out << ", ";
484 }
485 first = false;
486 out << arg->name();
487 }
488 if (returnsValue && elidedReturn == nullptr) {
489 if (!method->args().empty()) {
490 out << ", ";
491 }
492
493 out << "_hidl_cb";
494 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700495 out << ");\n\n";
496
497 generateCppInstrumentationCall(
498 out,
499 InstrumentationEvent::PASSTHROUGH_EXIT,
500 method);
Steven Moreland69e7c702016-09-09 11:16:32 -0700501
502 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700503 out.unindent();
504 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700505 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700506
507 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700508
509 out.unindent();
510 out << "}\n";
511
512 return OK;
513}
514
Yifan Hong068c5522016-10-31 14:07:25 -0700515status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700516
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700517 const Interface *iface = mRootScope->getInterface();
518
Yifan Hong10fe0b52016-10-19 14:20:17 -0700519 const Interface *prevIterface = nullptr;
520 for (const auto &tuple : iface->allMethodsFromRoot()) {
521 const Method *method = tuple.method();
522 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700523
Yifan Hong10fe0b52016-10-19 14:20:17 -0700524 if(prevIterface != superInterface) {
525 if (prevIterface != nullptr) {
526 out << "\n";
527 }
528 out << "// Methods from "
529 << superInterface->fullName()
530 << " follow.\n";
531 prevIterface = superInterface;
532 }
Yifan Hong068c5522016-10-31 14:07:25 -0700533 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700534
Yifan Hong10fe0b52016-10-19 14:20:17 -0700535 if (err != OK) {
536 return err;
537 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700538 }
539
Yifan Hong10fe0b52016-10-19 14:20:17 -0700540 out << "\n";
541
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700542 return OK;
543}
544
Andreas Huberb82318c2016-08-02 14:45:54 -0700545status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700546 std::string ifaceName;
547 if (!AST::isInterface(&ifaceName)) {
548 // types.hal does not get a stub header.
549 return OK;
550 }
551
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700552 const Interface *iface = mRootScope->getInterface();
553 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700554 const std::string klassName = "Bn" + baseName;
Andreas Huber881227d2016-08-02 14:20:21 -0700555
Andreas Huberb82318c2016-08-02 14:45:54 -0700556 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700557 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700558 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700559 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700560 path.append(".h");
561
Andreas Huberd2943e12016-08-05 11:59:31 -0700562 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700563 FILE *file = fopen(path.c_str(), "w");
564
565 if (file == NULL) {
566 return -errno;
567 }
568
569 Formatter out(file);
570
Steven Moreland40786312016-08-16 10:29:40 -0700571 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700572
573 out << "#ifndef " << guard << "\n";
574 out << "#define " << guard << "\n\n";
575
Steven Morelandee88eed2016-10-31 17:49:00 -0700576 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
577 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700578
579 enterLeaveNamespace(out, true /* enter */);
580 out << "\n";
581
582 out << "struct "
583 << "Bn"
584 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700585 << " : public ::android::hardware::BnInterface<I"
586 << baseName << ", IHw" << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700587 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700588
589 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700590 out << "explicit Bn"
591 << baseName
592 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
593 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700594 out << "::android::status_t onTransact(\n";
595 out.indent();
596 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700597 out << "uint32_t _hidl_code,\n";
598 out << "const ::android::hardware::Parcel &_hidl_data,\n";
599 out << "::android::hardware::Parcel *_hidl_reply,\n";
600 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700601 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700602 out.unindent();
603 out.unindent();
604
Yifan Hong068c5522016-10-31 14:07:25 -0700605 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
606 return generateStubMethod(out, method);
607 });
Steven Moreland9c387612016-09-07 09:54:26 -0700608
609 if (err != OK) {
610 return err;
611 }
612
Zhuoyao Zhangde578002016-09-07 18:24:17 -0700613
Andreas Huber881227d2016-08-02 14:20:21 -0700614 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700615 out << "};\n\n";
616
617 enterLeaveNamespace(out, false /* enter */);
618
619 out << "\n#endif // " << guard << "\n";
620
621 return OK;
622}
623
Andreas Huberb82318c2016-08-02 14:45:54 -0700624status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700625 std::string ifaceName;
626 if (!AST::isInterface(&ifaceName)) {
627 // types.hal does not get a proxy header.
628 return OK;
629 }
630
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700631 const Interface *iface = mRootScope->getInterface();
632 const std::string baseName = iface->getBaseName();
Andreas Huber881227d2016-08-02 14:20:21 -0700633
Andreas Huberb82318c2016-08-02 14:45:54 -0700634 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700635 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700636 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700637 path.append("Bp");
638 path.append(baseName);
639 path.append(".h");
640
Andreas Huberd2943e12016-08-05 11:59:31 -0700641 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700642 FILE *file = fopen(path.c_str(), "w");
643
644 if (file == NULL) {
645 return -errno;
646 }
647
648 Formatter out(file);
649
650 const std::string guard = makeHeaderGuard("Bp" + baseName);
651
652 out << "#ifndef " << guard << "\n";
653 out << "#define " << guard << "\n\n";
654
655 std::vector<std::string> packageComponents;
656 getPackageAndVersionComponents(
657 &packageComponents, false /* cpp_compatible */);
658
Steven Morelandee88eed2016-10-31 17:49:00 -0700659 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
660 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700661
662 enterLeaveNamespace(out, true /* enter */);
663 out << "\n";
664
665 out << "struct "
666 << "Bp"
667 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700668 << " : public ::android::hardware::BpInterface<IHw"
669 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700670 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700671
672 out.indent();
673
674 out << "explicit Bp"
675 << baseName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700676 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700677 << "\n\n";
678
Yifan Hong10fe0b52016-10-19 14:20:17 -0700679 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700680
Yifan Hong068c5522016-10-31 14:07:25 -0700681 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
682 method->generateCppSignature(out);
683 out << " override;\n";
684 return OK;
685 });
Steven Moreland9c387612016-09-07 09:54:26 -0700686
687 if (err != OK) {
688 return err;
689 }
Andreas Huber881227d2016-08-02 14:20:21 -0700690
691 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700692 out << "};\n\n";
693
694 enterLeaveNamespace(out, false /* enter */);
695
696 out << "\n#endif // " << guard << "\n";
697
698 return OK;
699}
700
Andreas Huberb82318c2016-08-02 14:45:54 -0700701status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700702
Andreas Huberb82318c2016-08-02 14:45:54 -0700703 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700704 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700705 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700706
707 std::string ifaceName;
708 std::string baseName;
709
Yifan Hongfe95aa22016-10-19 17:26:45 -0700710 const Interface *iface = nullptr;
711 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700712 if (!AST::isInterface(&ifaceName)) {
713 baseName = "types";
714 isInterface = false;
715 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700716 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700717 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700718 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700719 }
720
721 path.append(baseName);
722
723 if (baseName != "types") {
724 path.append("All");
725 }
726
727 path.append(".cpp");
728
Andreas Huberd2943e12016-08-05 11:59:31 -0700729 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700730 FILE *file = fopen(path.c_str(), "w");
731
732 if (file == NULL) {
733 return -errno;
734 }
735
736 Formatter out(file);
737
Andreas Huber881227d2016-08-02 14:20:21 -0700738 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700739 // This is a no-op for IServiceManager itself.
740 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
741
Steven Morelandee88eed2016-10-31 17:49:00 -0700742 generateCppPackageInclude(out, mPackage, "Bp" + baseName);
743 generateCppPackageInclude(out, mPackage, "Bn" + baseName);
744 generateCppPackageInclude(out, mPackage, "Bs" + baseName);
Yifan Hongfe95aa22016-10-19 17:26:45 -0700745
746 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700747 generateCppPackageInclude(out,
748 superType->fqName(),
749 "Bp" + superType->getBaseName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700750 }
Andreas Huber881227d2016-08-02 14:20:21 -0700751 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700752 generateCppPackageInclude(out, mPackage, "types");
Andreas Huber881227d2016-08-02 14:20:21 -0700753 }
754
755 out << "\n";
756
757 enterLeaveNamespace(out, true /* enter */);
758 out << "\n";
759
760 status_t err = generateTypeSource(out, ifaceName);
761
762 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700763 const Interface *iface = mRootScope->getInterface();
Steven Moreland19d5c172016-10-20 19:20:25 -0700764 out << "constexpr ::android::hardware::hidl_version "
765 << ifaceName
766 << "::version;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700767
768 // need to be put here, generateStubSource is using this.
769 out << "const ::android::String16 I"
770 << iface->getBaseName()
771 << "::descriptor(\""
772 << iface->fqName().string()
773 << "\");\n\n";
774
Yifan Hongfe95aa22016-10-19 17:26:45 -0700775 err = generateInterfaceSource(out);
776 }
777
778 if (err == OK && isInterface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700779 err = generateProxySource(out, baseName);
780 }
781
782 if (err == OK && isInterface) {
783 err = generateStubSource(out, baseName);
784 }
785
Steven Moreland40786312016-08-16 10:29:40 -0700786 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -0700787 err = generatePassthroughSource(out);
788 }
789
790 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -0700791 const Interface *iface = mRootScope->getInterface();
792
793 out << "IMPLEMENT_REGISTER_AND_GET_SERVICE("
794 << baseName << ", "
795 << "\"" << iface->fqName().package()
Yifan Hong90ea87f2016-11-01 14:25:47 -0700796 << iface->fqName().atVersion() << "-impl.so\""
Steven Moreland9c387612016-09-07 09:54:26 -0700797 << ")\n";
Steven Moreland40786312016-08-16 10:29:40 -0700798 }
799
Andreas Huber881227d2016-08-02 14:20:21 -0700800 enterLeaveNamespace(out, false /* enter */);
801
802 return err;
803}
804
Steven Moreland67f67b42016-09-29 08:59:02 -0700805// static
806void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
807 out << "if (" << nonNull << " == nullptr) {\n";
808 out.indent();
809 out << "return ::android::hardware::Status::fromExceptionCode(\n";
810 out.indent();
811 out.indent();
812 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
813 out.unindent();
814 out.unindent();
815 out.unindent();
816 out << "}\n\n";
817}
818
Andreas Huber881227d2016-08-02 14:20:21 -0700819status_t AST::generateTypeSource(
820 Formatter &out, const std::string &ifaceName) const {
821 return mRootScope->emitTypeDefinitions(out, ifaceName);
822}
823
Andreas Hubere7ff2282016-08-16 13:50:03 -0700824void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -0700825 Formatter &out,
826 const std::vector<TypedVar *> &args,
827 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700828 if (args.empty()) {
829 return;
830 }
831
832 for (const auto &arg : args) {
833 const Type &type = arg->type();
834
Yifan Hong3b320f82016-11-01 15:15:54 -0700835 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700836 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700837 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700838 << ";\n";
839 }
840
841 out << "\n";
842}
843
Andreas Huber881227d2016-08-02 14:20:21 -0700844void AST::emitCppReaderWriter(
845 Formatter &out,
846 const std::string &parcelObj,
847 bool parcelObjIsPointer,
848 const TypedVar *arg,
849 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -0700850 Type::ErrorMode mode,
851 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700852 const Type &type = arg->type();
853
Andreas Huber881227d2016-08-02 14:20:21 -0700854 type.emitReaderWriter(
855 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700856 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700857 parcelObj,
858 parcelObjIsPointer,
859 isReader,
860 mode);
861}
862
Yifan Hongbf459bc2016-08-23 16:50:37 -0700863void AST::emitCppResolveReferences(
864 Formatter &out,
865 const std::string &parcelObj,
866 bool parcelObjIsPointer,
867 const TypedVar *arg,
868 bool isReader,
869 Type::ErrorMode mode,
870 bool addPrefixToName) const {
871 const Type &type = arg->type();
872 if(type.needsResolveReferences()) {
873 type.emitResolveReferences(
874 out,
875 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
876 isReader, // nameIsPointer
877 parcelObj,
878 parcelObjIsPointer,
879 isReader,
880 mode);
881 }
882}
883
Yifan Hong068c5522016-10-31 14:07:25 -0700884status_t AST::generateProxyMethodSource(Formatter &out,
885 const std::string &klassName,
886 const Method *method,
887 const Interface *superInterface) const {
888
889 method->generateCppSignature(out,
890 klassName,
891 true /* specify namespaces */);
892
893 const bool returnsValue = !method->results().empty();
894 const TypedVar *elidedReturn = method->canElideCallback();
895
Steven Moreland41c6d2e2016-11-07 12:26:54 -0800896 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700897
898 out.indent();
899
900 if (returnsValue && elidedReturn == nullptr) {
901 generateCheckNonNull(out, "_hidl_cb");
902 }
903
904 status_t status = generateCppInstrumentationCall(
905 out,
906 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -0700907 method);
908 if (status != OK) {
909 return status;
910 }
911
912 out << "::android::hardware::Parcel _hidl_data;\n";
913 out << "::android::hardware::Parcel _hidl_reply;\n";
914 out << "::android::status_t _hidl_err;\n";
915 out << "::android::hardware::Status _hidl_status;\n\n";
916
917 declareCppReaderLocals(
918 out, method->results(), true /* forResults */);
919
920 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
921 if (!method->isHidlReserved()) {
922 out << superInterface->fqName().cppNamespace()
923 << "::IHw"
924 << superInterface->getBaseName();
925 } else {
926 out << "::android::hardware::IHidlInterfaceBase";
927 }
928 out << "::descriptor);\n";
929
930 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
931
932 // First DFS: write all buffers and resolve pointers for parent
933 for (const auto &arg : method->args()) {
934 emitCppReaderWriter(
935 out,
936 "_hidl_data",
937 false /* parcelObjIsPointer */,
938 arg,
939 false /* reader */,
940 Type::ErrorMode_Goto,
941 false /* addPrefixToName */);
942 }
943
944 // Second DFS: resolve references.
945 for (const auto &arg : method->args()) {
946 emitCppResolveReferences(
947 out,
948 "_hidl_data",
949 false /* parcelObjIsPointer */,
950 arg,
951 false /* reader */,
952 Type::ErrorMode_Goto,
953 false /* addPrefixToName */);
954 }
955
956 out << "_hidl_err = remote()->transact("
957 << method->getSerialId()
958 << " /* "
959 << method->name()
960 << " */, _hidl_data, &_hidl_reply";
961
962 if (method->isOneway()) {
963 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
964 }
965 out << ");\n";
966
967 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
968
969 if (!method->isOneway()) {
970 out << "_hidl_err = _hidl_status.readFromParcel(_hidl_reply);\n";
971 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
972 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
973
974
975 // First DFS: write all buffers and resolve pointers for parent
976 for (const auto &arg : method->results()) {
977 emitCppReaderWriter(
978 out,
979 "_hidl_reply",
980 false /* parcelObjIsPointer */,
981 arg,
982 true /* reader */,
983 Type::ErrorMode_Goto,
984 true /* addPrefixToName */);
985 }
986
987 // Second DFS: resolve references.
988 for (const auto &arg : method->results()) {
989 emitCppResolveReferences(
990 out,
991 "_hidl_reply",
992 false /* parcelObjIsPointer */,
993 arg,
994 true /* reader */,
995 Type::ErrorMode_Goto,
996 true /* addPrefixToName */);
997 }
998
999 if (returnsValue && elidedReturn == nullptr) {
1000 out << "_hidl_cb(";
1001
1002 bool first = true;
1003 for (const auto &arg : method->results()) {
1004 if (!first) {
1005 out << ", ";
1006 }
1007
1008 if (arg->type().resultNeedsDeref()) {
1009 out << "*";
1010 }
1011 out << "_hidl_out_" << arg->name();
1012
1013 first = false;
1014 }
1015
1016 out << ");\n\n";
1017 }
1018 status_t status = generateCppInstrumentationCall(
1019 out,
1020 InstrumentationEvent::CLIENT_API_EXIT,
Yifan Hong068c5522016-10-31 14:07:25 -07001021 method);
1022 if (status != OK) {
1023 return status;
1024 }
1025 }
1026
1027 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001028 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1029 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001030 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001031 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1032 } else {
1033 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1034 out << "return ::android::hardware::Return<void>();\n\n";
1035 }
1036
1037 out.unindent();
1038 out << "_hidl_error:\n";
1039 out.indent();
1040 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1041 out << "return ::android::hardware::Return<";
1042 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001043 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001044 } else {
1045 out << "void";
1046 }
1047 out << ">(_hidl_status);\n";
1048
1049 out.unindent();
1050 out << "}\n\n";
1051 return OK;
1052}
1053
Andreas Huber881227d2016-08-02 14:20:21 -07001054status_t AST::generateProxySource(
1055 Formatter &out, const std::string &baseName) const {
1056 const std::string klassName = "Bp" + baseName;
1057
1058 out << klassName
1059 << "::"
1060 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001061 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001062
1063 out.indent();
1064 out.indent();
1065
1066 out << ": BpInterface"
Steven Moreland40786312016-08-16 10:29:40 -07001067 << "<IHw"
Andreas Huber881227d2016-08-02 14:20:21 -07001068 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001069 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001070 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001071 << mPackage.string()
1072 << "::I"
1073 << baseName
1074 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001075
Andreas Huber881227d2016-08-02 14:20:21 -07001076 out.unindent();
1077 out.unindent();
1078 out << "}\n\n";
1079
Yifan Hong068c5522016-10-31 14:07:25 -07001080 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1081 return generateProxyMethodSource(out, klassName, method, superInterface);
1082 });
Andreas Huber881227d2016-08-02 14:20:21 -07001083
Yifan Hong068c5522016-10-31 14:07:25 -07001084 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001085}
1086
1087status_t AST::generateStubSource(
1088 Formatter &out, const std::string &baseName) const {
1089 out << "IMPLEMENT_HWBINDER_META_INTERFACE("
1090 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001091 << ", "
1092 << mPackage.cppNamespace()
Andreas Huber881227d2016-08-02 14:20:21 -07001093 << "::I"
1094 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001095 << "::descriptor);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001096
1097 const std::string klassName = "Bn" + baseName;
1098
Steven Moreland40786312016-08-16 10:29:40 -07001099 out << klassName
1100 << "::"
1101 << klassName
1102 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl)\n";
1103
1104 out.indent();
1105 out.indent();
1106
1107 out << ": BnInterface"
1108 << "<I"
1109 << baseName
1110 << ", IHw"
1111 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001112 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001113 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001114 << mPackage.string()
1115 << "::I"
1116 << baseName
1117 << "\") {\n";
Steven Moreland40786312016-08-16 10:29:40 -07001118
1119 out.unindent();
1120 out.unindent();
1121 out << "}\n\n";
1122
Andreas Huber881227d2016-08-02 14:20:21 -07001123 out << "::android::status_t " << klassName << "::onTransact(\n";
1124
1125 out.indent();
1126 out.indent();
1127
Iliyan Malchev549e2592016-08-10 08:59:12 -07001128 out << "uint32_t _hidl_code,\n"
1129 << "const ::android::hardware::Parcel &_hidl_data,\n"
1130 << "::android::hardware::Parcel *_hidl_reply,\n"
1131 << "uint32_t _hidl_flags,\n"
1132 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001133
1134 out.unindent();
1135
Iliyan Malchev549e2592016-08-10 08:59:12 -07001136 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001137 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001138 out.indent();
1139
1140 const Interface *iface = mRootScope->getInterface();
1141
Yifan Hong10fe0b52016-10-19 14:20:17 -07001142 for (const auto &tuple : iface->allMethodsFromRoot()) {
1143 const Method *method = tuple.method();
1144 const Interface *superInterface = tuple.interface();
1145 out << "case "
1146 << method->getSerialId()
1147 << " /* "
1148 << method->name()
1149 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001150
Yifan Hong10fe0b52016-10-19 14:20:17 -07001151 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001152
Yifan Hong10fe0b52016-10-19 14:20:17 -07001153 status_t err =
1154 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001155
Yifan Hong10fe0b52016-10-19 14:20:17 -07001156 if (err != OK) {
1157 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001158 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001159
1160 out.unindent();
1161 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001162 }
1163
1164 out << "default:\n{\n";
1165 out.indent();
1166
Andreas Huber8a82ff72016-08-04 10:29:39 -07001167 out << "return ::android::hardware::BnInterface<I"
Steven Moreland40786312016-08-16 10:29:40 -07001168 << baseName << ", IHw" << baseName
Andreas Huber881227d2016-08-02 14:20:21 -07001169 << ">::onTransact(\n";
1170
1171 out.indent();
1172 out.indent();
1173
Iliyan Malchev549e2592016-08-10 08:59:12 -07001174 out << "_hidl_code, _hidl_data, _hidl_reply, "
1175 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001176
1177 out.unindent();
1178 out.unindent();
1179
1180 out.unindent();
1181 out << "}\n";
1182
1183 out.unindent();
1184 out << "}\n\n";
1185
Iliyan Malchev549e2592016-08-10 08:59:12 -07001186 out << "if (_hidl_err == ::android::UNEXPECTED_NULL) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001187 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001188 out << "_hidl_err = ::android::hardware::Status::fromExceptionCode(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001189 out.indent();
1190 out.indent();
Andreas Huber8a82ff72016-08-04 10:29:39 -07001191 out << "::android::hardware::Status::EX_NULL_POINTER)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001192 out.indent();
1193 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001194 out << ".writeToParcel(_hidl_reply);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001195 out.unindent();
1196 out.unindent();
1197 out.unindent();
1198 out.unindent();
1199
1200 out.unindent();
1201 out << "}\n\n";
1202
Iliyan Malchev549e2592016-08-10 08:59:12 -07001203 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001204
1205 out.unindent();
1206 out << "}\n\n";
1207
1208 return OK;
1209}
1210
1211status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001212 Formatter &out, const Interface *iface, const Method *method) const {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001213 out << "if (!_hidl_data.enforceInterface(";
1214
1215 if (!method->isHidlReserved()) {
1216 out << iface->fqName().cppNamespace()
1217 << "::IHw"
1218 << iface->getBaseName();
1219 } else {
1220 out << "::android::hardware::IHidlInterfaceBase";
1221 }
1222
1223 out << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001224
Andreas Huber881227d2016-08-02 14:20:21 -07001225 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001226 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001227 out << "break;\n";
1228 out.unindent();
1229 out << "}\n\n";
1230
Andreas Huber5e44a292016-09-27 14:52:39 -07001231 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001232
Yifan Hongbf459bc2016-08-23 16:50:37 -07001233 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001234 for (const auto &arg : method->args()) {
1235 emitCppReaderWriter(
1236 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001237 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001238 false /* parcelObjIsPointer */,
1239 arg,
1240 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001241 Type::ErrorMode_Break,
1242 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001243 }
1244
Yifan Hongbf459bc2016-08-23 16:50:37 -07001245 // Second DFS: resolve references
1246 for (const auto &arg : method->args()) {
1247 emitCppResolveReferences(
1248 out,
1249 "_hidl_data",
1250 false /* parcelObjIsPointer */,
1251 arg,
1252 true /* reader */,
1253 Type::ErrorMode_Break,
1254 false /* addPrefixToName */);
1255 }
1256
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001257 status_t status = generateCppInstrumentationCall(
1258 out,
1259 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001260 method);
1261 if (status != OK) {
1262 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001263 }
1264
Andreas Huber881227d2016-08-02 14:20:21 -07001265 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001266 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001267
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001268 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001269 out << elidedReturn->type().getCppResultType()
1270 << " "
1271 << elidedReturn->name()
1272 << " = "
1273 << method->name()
1274 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001275
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001276 bool first = true;
1277 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001278 if (!first) {
1279 out << ", ";
1280 }
1281
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001282 if (arg->type().resultNeedsDeref()) {
1283 out << "*";
1284 }
1285
1286 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001287
1288 first = false;
1289 }
1290
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001291 out << ");\n\n";
Andreas Huber8a82ff72016-08-04 10:29:39 -07001292 out << "::android::hardware::Status::ok()"
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001293 << ".writeToParcel(_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001294
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001295 elidedReturn->type().emitReaderWriter(
1296 out,
1297 elidedReturn->name(),
1298 "_hidl_reply",
1299 true, /* parcelObjIsPointer */
1300 false, /* isReader */
1301 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001302
Yifan Hongbf459bc2016-08-23 16:50:37 -07001303 emitCppResolveReferences(
1304 out,
1305 "_hidl_reply",
1306 true /* parcelObjIsPointer */,
1307 elidedReturn,
1308 false /* reader */,
1309 Type::ErrorMode_Ignore,
1310 false /* addPrefixToName */);
1311
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001312 status_t status = generateCppInstrumentationCall(
1313 out,
1314 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001315 method);
1316 if (status != OK) {
1317 return status;
1318 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001319
Iliyan Malchev549e2592016-08-10 08:59:12 -07001320 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001321 } else {
1322 if (returnsValue) {
1323 out << "bool _hidl_callbackCalled = false;\n\n";
1324 }
Andreas Huber881227d2016-08-02 14:20:21 -07001325
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001326 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001327
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001328 bool first = true;
1329 for (const auto &arg : method->args()) {
1330 if (!first) {
1331 out << ", ";
1332 }
Andreas Huber881227d2016-08-02 14:20:21 -07001333
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001334 if (arg->type().resultNeedsDeref()) {
1335 out << "*";
1336 }
1337
1338 out << arg->name();
1339
1340 first = false;
1341 }
1342
1343 if (returnsValue) {
1344 if (!first) {
1345 out << ", ";
1346 }
1347
1348 out << "[&](";
1349
1350 first = true;
1351 for (const auto &arg : method->results()) {
1352 if (!first) {
1353 out << ", ";
1354 }
1355
1356 out << "const auto &" << arg->name();
1357
1358 first = false;
1359 }
1360
1361 out << ") {\n";
1362 out.indent();
1363 out << "_hidl_callbackCalled = true;\n\n";
1364
1365 out << "::android::hardware::Status::ok()"
1366 << ".writeToParcel(_hidl_reply);\n\n";
1367
Yifan Hongbf459bc2016-08-23 16:50:37 -07001368 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001369 for (const auto &arg : method->results()) {
1370 emitCppReaderWriter(
1371 out,
1372 "_hidl_reply",
1373 true /* parcelObjIsPointer */,
1374 arg,
1375 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001376 Type::ErrorMode_Ignore,
1377 false /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001378 }
1379
Yifan Hongbf459bc2016-08-23 16:50:37 -07001380 // Second DFS: resolve references
1381 for (const auto &arg : method->results()) {
1382 emitCppResolveReferences(
1383 out,
1384 "_hidl_reply",
1385 true /* parcelObjIsPointer */,
1386 arg,
1387 false /* reader */,
1388 Type::ErrorMode_Ignore,
1389 false /* addPrefixToName */);
1390 }
1391
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001392 status_t status = generateCppInstrumentationCall(
1393 out,
1394 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001395 method);
1396 if (status != OK) {
1397 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001398 }
1399
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001400 out << "_hidl_cb(*_hidl_reply);\n";
1401
1402 out.unindent();
1403 out << "}\n";
1404 }
1405
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001406 out << ");\n\n";
1407
1408 // What to do if the stub implementation has a synchronous callback
1409 // which does not get invoked? This is not a transport error but a
1410 // service error of sorts. For now, return OK to the caller, as this is
1411 // not a transport error.
1412 //
1413 // TODO(b/31365311) Figure out how to deal with this later.
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001414
1415 if (returnsValue) {
1416 out << "if (!_hidl_callbackCalled) {\n";
1417 out.indent();
1418 }
1419
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001420 out << "::android::hardware::Status::ok()"
1421 << ".writeToParcel(_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001422
1423 if (returnsValue) {
1424 out.unindent();
1425 out << "}\n\n";
1426 }
Andreas Huber881227d2016-08-02 14:20:21 -07001427 }
1428
1429 out << "break;\n";
1430
1431 return OK;
1432}
1433
Steven Moreland69e7c702016-09-09 11:16:32 -07001434status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1435 std::string ifaceName;
1436 if (!AST::isInterface(&ifaceName)) {
1437 // types.hal does not get a stub header.
1438 return OK;
1439 }
1440
1441 const Interface *iface = mRootScope->getInterface();
1442
1443 const std::string baseName = iface->getBaseName();
1444 const std::string klassName = "Bs" + baseName;
1445
1446 bool supportOneway = iface->hasOnewayMethods();
1447
1448 std::string path = outputPath;
1449 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1450 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1451 path.append(klassName);
1452 path.append(".h");
1453
1454 CHECK(Coordinator::MakeParentHierarchy(path));
1455 FILE *file = fopen(path.c_str(), "w");
1456
1457 if (file == NULL) {
1458 return -errno;
1459 }
1460
1461 Formatter out(file);
1462
1463 const std::string guard = makeHeaderGuard(klassName);
1464
1465 out << "#ifndef " << guard << "\n";
1466 out << "#define " << guard << "\n\n";
1467
1468 std::vector<std::string> packageComponents;
1469 getPackageAndVersionComponents(
1470 &packageComponents, false /* cpp_compatible */);
1471
1472 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001473
1474 generateCppPackageInclude(out, mPackage, ifaceName);
1475 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001476
1477 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001478 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001479 }
1480
1481 enterLeaveNamespace(out, true /* enter */);
1482 out << "\n";
1483
1484 out << "struct "
1485 << klassName
1486 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001487 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001488
1489 out.indent();
1490 out << "explicit "
1491 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001492 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001493 << ifaceName
1494 << "> impl);\n";
1495
Yifan Hong068c5522016-10-31 14:07:25 -07001496 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1497 return generatePassthroughMethod(out, method);
1498 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001499
1500 if (err != OK) {
1501 return err;
1502 }
1503
1504 out.unindent();
1505 out << "private:\n";
1506 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001507 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001508
1509 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001510 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001511
1512 out << "\n";
1513
1514 out << "::android::hardware::Return<void> addOnewayTask("
1515 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001516 }
1517
1518 out.unindent();
1519
1520 out << "};\n\n";
1521
1522 enterLeaveNamespace(out, false /* enter */);
1523
1524 out << "\n#endif // " << guard << "\n";
1525
1526 return OK;
1527}
1528
Yifan Hongfe95aa22016-10-19 17:26:45 -07001529status_t AST::generateInterfaceSource(Formatter &out) const {
1530 const Interface *iface = mRootScope->getInterface();
1531
Yifan Hong2d7126b2016-10-20 15:12:57 -07001532
1533 // generate toBinder functions
1534 out << "::android::sp<::android::hardware::IBinder> I"
1535 << iface->getBaseName()
1536 << "::toBinder() {\n";
1537 out.indent();
1538 out << "if (isRemote()) {\n";
1539 out.indent();
1540 out << "return ::android::hardware::IInterface::asBinder("
1541 << "static_cast<IHw"
1542 << iface->getBaseName()
1543 << " *>(this));\n";
1544 out.unindent();
1545 out << "} else {\n";
1546 out.indent();
1547 out << "return new Bn" << iface->getBaseName() << "(this);\n";
1548 out.unindent();
1549 out << "}\n";
1550 out.unindent();
1551 out << "}\n\n";
1552
1553 // generate castFrom functions
Yifan Hongfe95aa22016-10-19 17:26:45 -07001554 if (!iface->isRootType()) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001555 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001556
1557 for (const Interface *superType : iface->superTypeChain()) {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001558 out << "// static \n"
1559 << childTypeResult
1560 << " I"
1561 << iface->getBaseName()
1562 << "::castFrom("
Yifan Hong3b320f82016-11-01 15:15:54 -07001563 << superType->getCppArgumentType()
1564 << " parent) {\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001565 out.indent();
1566 out << "return ::android::hardware::castInterface<";
1567 out << "I" << iface->getBaseName() << ", "
1568 << superType->fqName().cppName() << ", "
1569 << "Bp" << iface->getBaseName()
1570 << ">(\n";
1571 out.indent();
1572 out.indent();
1573 out << "parent, \""
1574 << iface->fqName().string()
1575 << "\");\n";
1576 out.unindent();
1577 out.unindent();
1578 out.unindent();
1579 out << "}\n\n";
1580 }
1581 }
1582
1583 return OK;
1584}
1585
Steven Moreland69e7c702016-09-09 11:16:32 -07001586status_t AST::generatePassthroughSource(Formatter &out) const {
1587 const Interface *iface = mRootScope->getInterface();
1588
1589 const std::string baseName = iface->getBaseName();
1590 const std::string klassName = "Bs" + baseName;
1591
1592 out << klassName
1593 << "::"
1594 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001595 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001596 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001597 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001598 << iface->fqName().string()
1599 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001600 if (iface->hasOnewayMethods()) {
1601 out << "\n";
1602 out.indentBlock([&] {
1603 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1604 });
1605 }
1606 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001607
1608 if (iface->hasOnewayMethods()) {
1609 out << "::android::hardware::Return<void> "
1610 << klassName
1611 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1612 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001613 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001614 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001615 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1616 out.indent();
1617 out.indent();
1618 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1619 out.unindent();
1620 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001621 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001622 out << "}\n";
1623
Steven Morelandd366c262016-10-11 15:29:10 -07001624 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001625
1626 out.unindent();
1627 out << "}\n\n";
1628
1629
1630 }
1631
1632 return OK;
1633}
1634
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001635status_t AST::generateCppInstrumentationCall(
1636 Formatter &out,
1637 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001638 const Method *method) const {
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001639 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1640 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001641 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001642 std::string event_str = "";
1643 switch (event) {
1644 case SERVER_API_ENTRY:
1645 {
1646 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1647 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001648 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001649 << (arg->type().resultNeedsDeref() ? "" : "&")
1650 << arg->name()
1651 << ");\n";
1652 }
1653 break;
1654 }
1655 case SERVER_API_EXIT:
1656 {
1657 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001658 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001659 out << "_hidl_args.push_back((void *)&"
Steven Moreland031ccf12016-10-31 15:54:38 -07001660 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001661 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001662 }
1663 break;
1664 }
1665 case CLIENT_API_ENTRY:
1666 {
1667 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1668 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001669 out << "_hidl_args.push_back((void *)&"
1670 << arg->name()
1671 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001672 }
1673 break;
1674 }
1675 case CLIENT_API_EXIT:
1676 {
1677 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1678 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001679 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001680 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001681 << "_hidl_out_"
1682 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001683 << ");\n";
1684 }
1685 break;
1686 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001687 case PASSTHROUGH_ENTRY:
1688 {
1689 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1690 for (const auto &arg : method->args()) {
1691 out << "_hidl_args.push_back((void *)&"
1692 << arg->name()
1693 << ");\n";
1694 }
1695 break;
1696 }
1697 case PASSTHROUGH_EXIT:
1698 {
1699 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
1700 // TODO(b/32576620): passthrough return values
1701 break;
1702 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001703 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001704 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001705 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001706 return UNKNOWN_ERROR;
1707 }
1708 }
1709
Steven Moreland031ccf12016-10-31 15:54:38 -07001710 const Interface *iface = mRootScope->getInterface();
1711
Steven Moreland1ab31442016-11-03 18:37:51 -07001712 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001713 out.indent();
1714 out << "callback("
1715 << event_str
1716 << ", \""
1717 << mPackage.package()
1718 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07001719 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001720 << "\", \""
1721 << iface->localName()
1722 << "\", \""
1723 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001724 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001725 out.unindent();
1726 out << "}\n";
1727 out.unindent();
1728 out << "}\n\n";
1729
1730 return OK;
1731}
1732
Andreas Huber881227d2016-08-02 14:20:21 -07001733} // namespace android
1734