blob: 6b162ffc9eb7c57ce7bb781e085ce04e60b2951c [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";
Andreas Huber881227d2016-08-02 14:20:21 -0700218 bool haveCallbacks = false;
219 for (const auto &method : iface->methods()) {
220 const bool returnsValue = !method->results().empty();
221
222 if (!returnsValue) {
223 continue;
224 }
225
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700226 if (method->canElideCallback() != nullptr) {
227 continue;
228 }
229
Andreas Huber881227d2016-08-02 14:20:21 -0700230 haveCallbacks = true;
231
232 out << "using "
233 << method->name()
234 << "_cb = std::function<void("
Steven Moreland979e0992016-09-07 09:18:08 -0700235 << Method::GetArgSignature(method->results(),
236 true /* specify namespaces */)
Andreas Huber881227d2016-08-02 14:20:21 -0700237 << ")>;\n";
238 }
239
240 if (haveCallbacks) {
241 out << "\n";
242 }
243
244 for (const auto &method : iface->methods()) {
245 const bool returnsValue = !method->results().empty();
246
Andreas Huber3599d922016-08-09 10:42:57 -0700247 method->dumpAnnotations(out);
248
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700249 const TypedVar *elidedReturn = method->canElideCallback();
250 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700251 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700252 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700253 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700254 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700255 }
256
257 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700258 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700259 << Method::GetArgSignature(method->args(),
260 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700261
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700262 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700263 if (!method->args().empty()) {
264 out << ", ";
265 }
266
Steven Moreland67f67b42016-09-29 08:59:02 -0700267 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700268 }
269
Yifan Hong10fe0b52016-10-19 14:20:17 -0700270 out << ")";
271 if (method->isHidlReserved()) {
272 out << " override";
273 out << " {\n";
274 out.indent();
275 method->cppImpl(out);
276 out.unindent();
277 out << "\n}\n";
278 } else {
279 out << " = 0;\n";
280 }
Andreas Huber881227d2016-08-02 14:20:21 -0700281 }
Steven Moreland40786312016-08-16 10:29:40 -0700282
Yifan Hongfe95aa22016-10-19 17:26:45 -0700283 if (!iface->isRootType()) {
284 out << "// cast static functions\n";
Yifan Hong3b320f82016-11-01 15:15:54 -0700285 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700286
287 for (const Interface *superType : iface->superTypeChain()) {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700288 out << "static "
289 << childTypeResult
290 << " castFrom("
Yifan Hong3b320f82016-11-01 15:15:54 -0700291 << superType->getCppArgumentType()
Yifan Hongfe95aa22016-10-19 17:26:45 -0700292 << " parent"
Yifan Hongfe95aa22016-10-19 17:26:45 -0700293 << ");\n";
294 }
295 }
296
Yifan Hong10fe0b52016-10-19 14:20:17 -0700297 out << "\nstatic const ::android::String16 descriptor;\n\n";
298
Yifan Hong158655a2016-11-08 12:34:07 -0800299 out << "DECLARE_REGISTER_AND_GET_SERVICE(" << baseName << ")\n\n";
300
301 out << "private: static int hidlStaticBlock;\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 Hong158655a2016-11-08 12:34:07 -0800775 out << "int I"
776 << iface->getBaseName()
777 << "::hidlStaticBlock = []() -> int {\n";
778 out.indentBlock([&] {
779 out << "::android::hardware::gBnConstructorMap[::android::String16::std_string(I"
780 << iface->getBaseName()
781 << "::descriptor)]\n";
782 out.indentBlock(2, [&] {
783 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
784 out.indentBlock([&] {
785 out << "return new Bn"
786 << iface->getBaseName()
787 << "(reinterpret_cast<I"
788 << iface->getBaseName()
789 << " *>(iIntf));\n";
790 });
791 out << "};\n";
792 });
793 out << "return 1;\n";
794 });
795 out << "}();\n\n";
796
Yifan Hongfe95aa22016-10-19 17:26:45 -0700797 err = generateInterfaceSource(out);
798 }
799
800 if (err == OK && isInterface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700801 err = generateProxySource(out, baseName);
802 }
803
804 if (err == OK && isInterface) {
805 err = generateStubSource(out, baseName);
806 }
807
Steven Moreland40786312016-08-16 10:29:40 -0700808 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -0700809 err = generatePassthroughSource(out);
810 }
811
812 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -0700813 const Interface *iface = mRootScope->getInterface();
814
815 out << "IMPLEMENT_REGISTER_AND_GET_SERVICE("
816 << baseName << ", "
817 << "\"" << iface->fqName().package()
Steven Moreland7e367bf2016-11-04 11:31:41 -0700818 << iface->fqName().atVersion()
819 << "\")\n";
Steven Moreland40786312016-08-16 10:29:40 -0700820 }
821
Andreas Huber881227d2016-08-02 14:20:21 -0700822 enterLeaveNamespace(out, false /* enter */);
823
824 return err;
825}
826
Steven Moreland67f67b42016-09-29 08:59:02 -0700827// static
828void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
829 out << "if (" << nonNull << " == nullptr) {\n";
830 out.indent();
831 out << "return ::android::hardware::Status::fromExceptionCode(\n";
832 out.indent();
833 out.indent();
834 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
835 out.unindent();
836 out.unindent();
837 out.unindent();
838 out << "}\n\n";
839}
840
Andreas Huber881227d2016-08-02 14:20:21 -0700841status_t AST::generateTypeSource(
842 Formatter &out, const std::string &ifaceName) const {
843 return mRootScope->emitTypeDefinitions(out, ifaceName);
844}
845
Andreas Hubere7ff2282016-08-16 13:50:03 -0700846void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -0700847 Formatter &out,
848 const std::vector<TypedVar *> &args,
849 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700850 if (args.empty()) {
851 return;
852 }
853
854 for (const auto &arg : args) {
855 const Type &type = arg->type();
856
Yifan Hong3b320f82016-11-01 15:15:54 -0700857 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700858 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700859 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700860 << ";\n";
861 }
862
863 out << "\n";
864}
865
Andreas Huber881227d2016-08-02 14:20:21 -0700866void AST::emitCppReaderWriter(
867 Formatter &out,
868 const std::string &parcelObj,
869 bool parcelObjIsPointer,
870 const TypedVar *arg,
871 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -0700872 Type::ErrorMode mode,
873 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700874 const Type &type = arg->type();
875
Andreas Huber881227d2016-08-02 14:20:21 -0700876 type.emitReaderWriter(
877 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700878 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700879 parcelObj,
880 parcelObjIsPointer,
881 isReader,
882 mode);
883}
884
Yifan Hongbf459bc2016-08-23 16:50:37 -0700885void AST::emitCppResolveReferences(
886 Formatter &out,
887 const std::string &parcelObj,
888 bool parcelObjIsPointer,
889 const TypedVar *arg,
890 bool isReader,
891 Type::ErrorMode mode,
892 bool addPrefixToName) const {
893 const Type &type = arg->type();
894 if(type.needsResolveReferences()) {
895 type.emitResolveReferences(
896 out,
897 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
898 isReader, // nameIsPointer
899 parcelObj,
900 parcelObjIsPointer,
901 isReader,
902 mode);
903 }
904}
905
Yifan Hong068c5522016-10-31 14:07:25 -0700906status_t AST::generateProxyMethodSource(Formatter &out,
907 const std::string &klassName,
908 const Method *method,
909 const Interface *superInterface) const {
910
911 method->generateCppSignature(out,
912 klassName,
913 true /* specify namespaces */);
914
915 const bool returnsValue = !method->results().empty();
916 const TypedVar *elidedReturn = method->canElideCallback();
917
Steven Moreland41c6d2e2016-11-07 12:26:54 -0800918 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700919
920 out.indent();
921
922 if (returnsValue && elidedReturn == nullptr) {
923 generateCheckNonNull(out, "_hidl_cb");
924 }
925
926 status_t status = generateCppInstrumentationCall(
927 out,
928 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -0700929 method);
930 if (status != OK) {
931 return status;
932 }
933
934 out << "::android::hardware::Parcel _hidl_data;\n";
935 out << "::android::hardware::Parcel _hidl_reply;\n";
936 out << "::android::status_t _hidl_err;\n";
937 out << "::android::hardware::Status _hidl_status;\n\n";
938
939 declareCppReaderLocals(
940 out, method->results(), true /* forResults */);
941
942 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
943 if (!method->isHidlReserved()) {
944 out << superInterface->fqName().cppNamespace()
945 << "::IHw"
946 << superInterface->getBaseName();
947 } else {
948 out << "::android::hardware::IHidlInterfaceBase";
949 }
950 out << "::descriptor);\n";
951
952 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
953
954 // First DFS: write all buffers and resolve pointers for parent
955 for (const auto &arg : method->args()) {
956 emitCppReaderWriter(
957 out,
958 "_hidl_data",
959 false /* parcelObjIsPointer */,
960 arg,
961 false /* reader */,
962 Type::ErrorMode_Goto,
963 false /* addPrefixToName */);
964 }
965
966 // Second DFS: resolve references.
967 for (const auto &arg : method->args()) {
968 emitCppResolveReferences(
969 out,
970 "_hidl_data",
971 false /* parcelObjIsPointer */,
972 arg,
973 false /* reader */,
974 Type::ErrorMode_Goto,
975 false /* addPrefixToName */);
976 }
977
978 out << "_hidl_err = remote()->transact("
979 << method->getSerialId()
980 << " /* "
981 << method->name()
982 << " */, _hidl_data, &_hidl_reply";
983
984 if (method->isOneway()) {
985 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
986 }
987 out << ");\n";
988
989 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
990
991 if (!method->isOneway()) {
992 out << "_hidl_err = _hidl_status.readFromParcel(_hidl_reply);\n";
993 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
994 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
995
996
997 // First DFS: write all buffers and resolve pointers for parent
998 for (const auto &arg : method->results()) {
999 emitCppReaderWriter(
1000 out,
1001 "_hidl_reply",
1002 false /* parcelObjIsPointer */,
1003 arg,
1004 true /* reader */,
1005 Type::ErrorMode_Goto,
1006 true /* addPrefixToName */);
1007 }
1008
1009 // Second DFS: resolve references.
1010 for (const auto &arg : method->results()) {
1011 emitCppResolveReferences(
1012 out,
1013 "_hidl_reply",
1014 false /* parcelObjIsPointer */,
1015 arg,
1016 true /* reader */,
1017 Type::ErrorMode_Goto,
1018 true /* addPrefixToName */);
1019 }
1020
1021 if (returnsValue && elidedReturn == nullptr) {
1022 out << "_hidl_cb(";
1023
1024 bool first = true;
1025 for (const auto &arg : method->results()) {
1026 if (!first) {
1027 out << ", ";
1028 }
1029
1030 if (arg->type().resultNeedsDeref()) {
1031 out << "*";
1032 }
1033 out << "_hidl_out_" << arg->name();
1034
1035 first = false;
1036 }
1037
1038 out << ");\n\n";
1039 }
1040 status_t status = generateCppInstrumentationCall(
1041 out,
1042 InstrumentationEvent::CLIENT_API_EXIT,
Yifan Hong068c5522016-10-31 14:07:25 -07001043 method);
1044 if (status != OK) {
1045 return status;
1046 }
1047 }
1048
1049 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001050 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1051 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001052 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001053 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1054 } else {
1055 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1056 out << "return ::android::hardware::Return<void>();\n\n";
1057 }
1058
1059 out.unindent();
1060 out << "_hidl_error:\n";
1061 out.indent();
1062 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1063 out << "return ::android::hardware::Return<";
1064 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001065 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001066 } else {
1067 out << "void";
1068 }
1069 out << ">(_hidl_status);\n";
1070
1071 out.unindent();
1072 out << "}\n\n";
1073 return OK;
1074}
1075
Andreas Huber881227d2016-08-02 14:20:21 -07001076status_t AST::generateProxySource(
1077 Formatter &out, const std::string &baseName) const {
1078 const std::string klassName = "Bp" + baseName;
1079
1080 out << klassName
1081 << "::"
1082 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001083 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001084
1085 out.indent();
1086 out.indent();
1087
1088 out << ": BpInterface"
Steven Moreland40786312016-08-16 10:29:40 -07001089 << "<IHw"
Andreas Huber881227d2016-08-02 14:20:21 -07001090 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001091 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001092 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001093 << mPackage.string()
1094 << "::I"
1095 << baseName
1096 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001097
Andreas Huber881227d2016-08-02 14:20:21 -07001098 out.unindent();
1099 out.unindent();
1100 out << "}\n\n";
1101
Yifan Hong068c5522016-10-31 14:07:25 -07001102 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1103 return generateProxyMethodSource(out, klassName, method, superInterface);
1104 });
Andreas Huber881227d2016-08-02 14:20:21 -07001105
Yifan Hong068c5522016-10-31 14:07:25 -07001106 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001107}
1108
1109status_t AST::generateStubSource(
1110 Formatter &out, const std::string &baseName) const {
1111 out << "IMPLEMENT_HWBINDER_META_INTERFACE("
1112 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001113 << ", "
1114 << mPackage.cppNamespace()
Andreas Huber881227d2016-08-02 14:20:21 -07001115 << "::I"
1116 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001117 << "::descriptor);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001118
1119 const std::string klassName = "Bn" + baseName;
1120
Steven Moreland40786312016-08-16 10:29:40 -07001121 out << klassName
1122 << "::"
1123 << klassName
1124 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl)\n";
1125
1126 out.indent();
1127 out.indent();
1128
1129 out << ": BnInterface"
1130 << "<I"
1131 << baseName
1132 << ", IHw"
1133 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001134 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001135 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001136 << mPackage.string()
1137 << "::I"
1138 << baseName
1139 << "\") {\n";
Steven Moreland40786312016-08-16 10:29:40 -07001140
1141 out.unindent();
1142 out.unindent();
1143 out << "}\n\n";
1144
Andreas Huber881227d2016-08-02 14:20:21 -07001145 out << "::android::status_t " << klassName << "::onTransact(\n";
1146
1147 out.indent();
1148 out.indent();
1149
Iliyan Malchev549e2592016-08-10 08:59:12 -07001150 out << "uint32_t _hidl_code,\n"
1151 << "const ::android::hardware::Parcel &_hidl_data,\n"
1152 << "::android::hardware::Parcel *_hidl_reply,\n"
1153 << "uint32_t _hidl_flags,\n"
1154 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001155
1156 out.unindent();
1157
Iliyan Malchev549e2592016-08-10 08:59:12 -07001158 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001159 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001160 out.indent();
1161
1162 const Interface *iface = mRootScope->getInterface();
1163
Yifan Hong10fe0b52016-10-19 14:20:17 -07001164 for (const auto &tuple : iface->allMethodsFromRoot()) {
1165 const Method *method = tuple.method();
1166 const Interface *superInterface = tuple.interface();
1167 out << "case "
1168 << method->getSerialId()
1169 << " /* "
1170 << method->name()
1171 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001172
Yifan Hong10fe0b52016-10-19 14:20:17 -07001173 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001174
Yifan Hong10fe0b52016-10-19 14:20:17 -07001175 status_t err =
1176 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001177
Yifan Hong10fe0b52016-10-19 14:20:17 -07001178 if (err != OK) {
1179 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001180 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001181
1182 out.unindent();
1183 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001184 }
1185
1186 out << "default:\n{\n";
1187 out.indent();
1188
Andreas Huber8a82ff72016-08-04 10:29:39 -07001189 out << "return ::android::hardware::BnInterface<I"
Steven Moreland40786312016-08-16 10:29:40 -07001190 << baseName << ", IHw" << baseName
Andreas Huber881227d2016-08-02 14:20:21 -07001191 << ">::onTransact(\n";
1192
1193 out.indent();
1194 out.indent();
1195
Iliyan Malchev549e2592016-08-10 08:59:12 -07001196 out << "_hidl_code, _hidl_data, _hidl_reply, "
1197 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001198
1199 out.unindent();
1200 out.unindent();
1201
1202 out.unindent();
1203 out << "}\n";
1204
1205 out.unindent();
1206 out << "}\n\n";
1207
Iliyan Malchev549e2592016-08-10 08:59:12 -07001208 out << "if (_hidl_err == ::android::UNEXPECTED_NULL) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001209 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001210 out << "_hidl_err = ::android::hardware::Status::fromExceptionCode(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001211 out.indent();
1212 out.indent();
Andreas Huber8a82ff72016-08-04 10:29:39 -07001213 out << "::android::hardware::Status::EX_NULL_POINTER)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001214 out.indent();
1215 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001216 out << ".writeToParcel(_hidl_reply);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001217 out.unindent();
1218 out.unindent();
1219 out.unindent();
1220 out.unindent();
1221
1222 out.unindent();
1223 out << "}\n\n";
1224
Iliyan Malchev549e2592016-08-10 08:59:12 -07001225 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001226
1227 out.unindent();
1228 out << "}\n\n";
1229
1230 return OK;
1231}
1232
1233status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001234 Formatter &out, const Interface *iface, const Method *method) const {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001235 out << "if (!_hidl_data.enforceInterface(";
1236
1237 if (!method->isHidlReserved()) {
1238 out << iface->fqName().cppNamespace()
1239 << "::IHw"
1240 << iface->getBaseName();
1241 } else {
1242 out << "::android::hardware::IHidlInterfaceBase";
1243 }
1244
1245 out << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001246
Andreas Huber881227d2016-08-02 14:20:21 -07001247 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001248 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001249 out << "break;\n";
1250 out.unindent();
1251 out << "}\n\n";
1252
Andreas Huber5e44a292016-09-27 14:52:39 -07001253 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001254
Yifan Hongbf459bc2016-08-23 16:50:37 -07001255 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001256 for (const auto &arg : method->args()) {
1257 emitCppReaderWriter(
1258 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001259 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001260 false /* parcelObjIsPointer */,
1261 arg,
1262 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001263 Type::ErrorMode_Break,
1264 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001265 }
1266
Yifan Hongbf459bc2016-08-23 16:50:37 -07001267 // Second DFS: resolve references
1268 for (const auto &arg : method->args()) {
1269 emitCppResolveReferences(
1270 out,
1271 "_hidl_data",
1272 false /* parcelObjIsPointer */,
1273 arg,
1274 true /* reader */,
1275 Type::ErrorMode_Break,
1276 false /* addPrefixToName */);
1277 }
1278
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001279 status_t status = generateCppInstrumentationCall(
1280 out,
1281 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001282 method);
1283 if (status != OK) {
1284 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001285 }
1286
Andreas Huber881227d2016-08-02 14:20:21 -07001287 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001288 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001289
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001290 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001291 out << elidedReturn->type().getCppResultType()
1292 << " "
1293 << elidedReturn->name()
1294 << " = "
1295 << method->name()
1296 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001297
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001298 bool first = true;
1299 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001300 if (!first) {
1301 out << ", ";
1302 }
1303
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001304 if (arg->type().resultNeedsDeref()) {
1305 out << "*";
1306 }
1307
1308 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001309
1310 first = false;
1311 }
1312
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001313 out << ");\n\n";
Andreas Huber8a82ff72016-08-04 10:29:39 -07001314 out << "::android::hardware::Status::ok()"
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001315 << ".writeToParcel(_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001316
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001317 elidedReturn->type().emitReaderWriter(
1318 out,
1319 elidedReturn->name(),
1320 "_hidl_reply",
1321 true, /* parcelObjIsPointer */
1322 false, /* isReader */
1323 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001324
Yifan Hongbf459bc2016-08-23 16:50:37 -07001325 emitCppResolveReferences(
1326 out,
1327 "_hidl_reply",
1328 true /* parcelObjIsPointer */,
1329 elidedReturn,
1330 false /* reader */,
1331 Type::ErrorMode_Ignore,
1332 false /* addPrefixToName */);
1333
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001334 status_t status = generateCppInstrumentationCall(
1335 out,
1336 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001337 method);
1338 if (status != OK) {
1339 return status;
1340 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001341
Iliyan Malchev549e2592016-08-10 08:59:12 -07001342 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001343 } else {
1344 if (returnsValue) {
1345 out << "bool _hidl_callbackCalled = false;\n\n";
1346 }
Andreas Huber881227d2016-08-02 14:20:21 -07001347
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001348 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001349
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001350 bool first = true;
1351 for (const auto &arg : method->args()) {
1352 if (!first) {
1353 out << ", ";
1354 }
Andreas Huber881227d2016-08-02 14:20:21 -07001355
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001356 if (arg->type().resultNeedsDeref()) {
1357 out << "*";
1358 }
1359
1360 out << arg->name();
1361
1362 first = false;
1363 }
1364
1365 if (returnsValue) {
1366 if (!first) {
1367 out << ", ";
1368 }
1369
1370 out << "[&](";
1371
1372 first = true;
1373 for (const auto &arg : method->results()) {
1374 if (!first) {
1375 out << ", ";
1376 }
1377
1378 out << "const auto &" << arg->name();
1379
1380 first = false;
1381 }
1382
1383 out << ") {\n";
1384 out.indent();
1385 out << "_hidl_callbackCalled = true;\n\n";
1386
1387 out << "::android::hardware::Status::ok()"
1388 << ".writeToParcel(_hidl_reply);\n\n";
1389
Yifan Hongbf459bc2016-08-23 16:50:37 -07001390 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001391 for (const auto &arg : method->results()) {
1392 emitCppReaderWriter(
1393 out,
1394 "_hidl_reply",
1395 true /* parcelObjIsPointer */,
1396 arg,
1397 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001398 Type::ErrorMode_Ignore,
1399 false /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001400 }
1401
Yifan Hongbf459bc2016-08-23 16:50:37 -07001402 // Second DFS: resolve references
1403 for (const auto &arg : method->results()) {
1404 emitCppResolveReferences(
1405 out,
1406 "_hidl_reply",
1407 true /* parcelObjIsPointer */,
1408 arg,
1409 false /* reader */,
1410 Type::ErrorMode_Ignore,
1411 false /* addPrefixToName */);
1412 }
1413
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001414 status_t status = generateCppInstrumentationCall(
1415 out,
1416 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001417 method);
1418 if (status != OK) {
1419 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001420 }
1421
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001422 out << "_hidl_cb(*_hidl_reply);\n";
1423
1424 out.unindent();
1425 out << "}\n";
1426 }
1427
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001428 out << ");\n\n";
1429
1430 // What to do if the stub implementation has a synchronous callback
1431 // which does not get invoked? This is not a transport error but a
1432 // service error of sorts. For now, return OK to the caller, as this is
1433 // not a transport error.
1434 //
1435 // TODO(b/31365311) Figure out how to deal with this later.
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001436
1437 if (returnsValue) {
1438 out << "if (!_hidl_callbackCalled) {\n";
1439 out.indent();
1440 }
1441
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001442 out << "::android::hardware::Status::ok()"
1443 << ".writeToParcel(_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001444
1445 if (returnsValue) {
1446 out.unindent();
1447 out << "}\n\n";
1448 }
Andreas Huber881227d2016-08-02 14:20:21 -07001449 }
1450
1451 out << "break;\n";
1452
1453 return OK;
1454}
1455
Steven Moreland69e7c702016-09-09 11:16:32 -07001456status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1457 std::string ifaceName;
1458 if (!AST::isInterface(&ifaceName)) {
1459 // types.hal does not get a stub header.
1460 return OK;
1461 }
1462
1463 const Interface *iface = mRootScope->getInterface();
1464
1465 const std::string baseName = iface->getBaseName();
1466 const std::string klassName = "Bs" + baseName;
1467
1468 bool supportOneway = iface->hasOnewayMethods();
1469
1470 std::string path = outputPath;
1471 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1472 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1473 path.append(klassName);
1474 path.append(".h");
1475
1476 CHECK(Coordinator::MakeParentHierarchy(path));
1477 FILE *file = fopen(path.c_str(), "w");
1478
1479 if (file == NULL) {
1480 return -errno;
1481 }
1482
1483 Formatter out(file);
1484
1485 const std::string guard = makeHeaderGuard(klassName);
1486
1487 out << "#ifndef " << guard << "\n";
1488 out << "#define " << guard << "\n\n";
1489
1490 std::vector<std::string> packageComponents;
1491 getPackageAndVersionComponents(
1492 &packageComponents, false /* cpp_compatible */);
1493
1494 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001495
1496 generateCppPackageInclude(out, mPackage, ifaceName);
1497 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001498
1499 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001500 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001501 }
1502
1503 enterLeaveNamespace(out, true /* enter */);
1504 out << "\n";
1505
1506 out << "struct "
1507 << klassName
1508 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001509 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001510
1511 out.indent();
1512 out << "explicit "
1513 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001514 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001515 << ifaceName
1516 << "> impl);\n";
1517
Yifan Hong068c5522016-10-31 14:07:25 -07001518 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1519 return generatePassthroughMethod(out, method);
1520 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001521
1522 if (err != OK) {
1523 return err;
1524 }
1525
1526 out.unindent();
1527 out << "private:\n";
1528 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001529 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001530
1531 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001532 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001533
1534 out << "\n";
1535
1536 out << "::android::hardware::Return<void> addOnewayTask("
1537 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001538 }
1539
1540 out.unindent();
1541
1542 out << "};\n\n";
1543
1544 enterLeaveNamespace(out, false /* enter */);
1545
1546 out << "\n#endif // " << guard << "\n";
1547
1548 return OK;
1549}
1550
Yifan Hongfe95aa22016-10-19 17:26:45 -07001551status_t AST::generateInterfaceSource(Formatter &out) const {
1552 const Interface *iface = mRootScope->getInterface();
1553
Yifan Hong2d7126b2016-10-20 15:12:57 -07001554 // generate castFrom functions
Yifan Hongfe95aa22016-10-19 17:26:45 -07001555 if (!iface->isRootType()) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001556 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001557
1558 for (const Interface *superType : iface->superTypeChain()) {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001559 out << "// static \n"
1560 << childTypeResult
1561 << " I"
1562 << iface->getBaseName()
1563 << "::castFrom("
Yifan Hong3b320f82016-11-01 15:15:54 -07001564 << superType->getCppArgumentType()
1565 << " parent) {\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001566 out.indent();
1567 out << "return ::android::hardware::castInterface<";
1568 out << "I" << iface->getBaseName() << ", "
1569 << superType->fqName().cppName() << ", "
Yifan Hong158655a2016-11-08 12:34:07 -08001570 << "Bp" << iface->getBaseName() << ", "
1571 << superType->getHwName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001572 << ">(\n";
1573 out.indent();
1574 out.indent();
1575 out << "parent, \""
1576 << iface->fqName().string()
1577 << "\");\n";
1578 out.unindent();
1579 out.unindent();
1580 out.unindent();
1581 out << "}\n\n";
1582 }
1583 }
1584
1585 return OK;
1586}
1587
Steven Moreland69e7c702016-09-09 11:16:32 -07001588status_t AST::generatePassthroughSource(Formatter &out) const {
1589 const Interface *iface = mRootScope->getInterface();
1590
1591 const std::string baseName = iface->getBaseName();
1592 const std::string klassName = "Bs" + baseName;
1593
1594 out << klassName
1595 << "::"
1596 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001597 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001598 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001599 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001600 << iface->fqName().string()
1601 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001602 if (iface->hasOnewayMethods()) {
1603 out << "\n";
1604 out.indentBlock([&] {
1605 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1606 });
1607 }
1608 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001609
1610 if (iface->hasOnewayMethods()) {
1611 out << "::android::hardware::Return<void> "
1612 << klassName
1613 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1614 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001615 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001616 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001617 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1618 out.indent();
1619 out.indent();
1620 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1621 out.unindent();
1622 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001623 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001624 out << "}\n";
1625
Steven Morelandd366c262016-10-11 15:29:10 -07001626 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001627
1628 out.unindent();
1629 out << "}\n\n";
1630
1631
1632 }
1633
1634 return OK;
1635}
1636
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001637status_t AST::generateCppInstrumentationCall(
1638 Formatter &out,
1639 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001640 const Method *method) const {
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001641 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1642 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001643 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001644 std::string event_str = "";
1645 switch (event) {
1646 case SERVER_API_ENTRY:
1647 {
1648 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1649 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001650 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001651 << (arg->type().resultNeedsDeref() ? "" : "&")
1652 << arg->name()
1653 << ");\n";
1654 }
1655 break;
1656 }
1657 case SERVER_API_EXIT:
1658 {
1659 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001660 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001661 out << "_hidl_args.push_back((void *)&"
Steven Moreland031ccf12016-10-31 15:54:38 -07001662 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001663 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001664 }
1665 break;
1666 }
1667 case CLIENT_API_ENTRY:
1668 {
1669 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1670 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001671 out << "_hidl_args.push_back((void *)&"
1672 << arg->name()
1673 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001674 }
1675 break;
1676 }
1677 case CLIENT_API_EXIT:
1678 {
1679 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1680 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001681 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001682 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001683 << "_hidl_out_"
1684 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001685 << ");\n";
1686 }
1687 break;
1688 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001689 case PASSTHROUGH_ENTRY:
1690 {
1691 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1692 for (const auto &arg : method->args()) {
1693 out << "_hidl_args.push_back((void *)&"
1694 << arg->name()
1695 << ");\n";
1696 }
1697 break;
1698 }
1699 case PASSTHROUGH_EXIT:
1700 {
1701 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
1702 // TODO(b/32576620): passthrough return values
1703 break;
1704 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001705 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001706 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001707 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001708 return UNKNOWN_ERROR;
1709 }
1710 }
1711
Steven Moreland031ccf12016-10-31 15:54:38 -07001712 const Interface *iface = mRootScope->getInterface();
1713
Steven Moreland1ab31442016-11-03 18:37:51 -07001714 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001715 out.indent();
1716 out << "callback("
1717 << event_str
1718 << ", \""
1719 << mPackage.package()
1720 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07001721 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001722 << "\", \""
1723 << iface->localName()
1724 << "\", \""
1725 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001726 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001727 out.unindent();
1728 out << "}\n";
1729 out.unindent();
1730 out << "}\n\n";
1731
1732 return OK;
1733}
1734
Andreas Huber881227d2016-08-02 14:20:21 -07001735} // namespace android
1736