blob: 68c8bc371c883350bf88d220cad24e34b3e70527 [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Huber881227d2016-08-02 14:20:21 -070017#include "AST.h"
18
19#include "Coordinator.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070020#include "EnumType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070021#include "Interface.h"
22#include "Method.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070023#include "ScalarType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070024#include "Scope.h"
25
Andreas Huberdca261f2016-08-04 13:47:51 -070026#include <algorithm>
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070027#include <hidl-util/Formatter.h>
Andreas Huber881227d2016-08-02 14:20:21 -070028#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070029#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070030#include <vector>
31
32namespace android {
33
Andreas Huberb82318c2016-08-02 14:45:54 -070034status_t AST::generateCpp(const std::string &outputPath) const {
35 status_t err = generateInterfaceHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070036
37 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070038 err = generateStubHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070039 }
40
41 if (err == OK) {
Steven Moreland40786312016-08-16 10:29:40 -070042 err = generateHwBinderHeader(outputPath);
43 }
44
45 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070046 err = generateProxyHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070047 }
48
49 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070050 err = generateAllSource(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070051 }
52
Steven Moreland69e7c702016-09-09 11:16:32 -070053 if (err == OK) {
54 generatePassthroughHeader(outputPath);
55 }
56
Andreas Huber881227d2016-08-02 14:20:21 -070057 return err;
58}
59
Andreas Huber737080b2016-08-02 15:38:04 -070060void AST::getPackageComponents(
61 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070062 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070063}
64
65void AST::getPackageAndVersionComponents(
66 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070067 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070068}
69
Andreas Huber881227d2016-08-02 14:20:21 -070070std::string AST::makeHeaderGuard(const std::string &baseName) const {
Steven Moreland9c387612016-09-07 09:54:26 -070071 std::string guard = "HIDL_GENERATED_";
72 guard += mPackage.tokenName();
Andreas Huber881227d2016-08-02 14:20:21 -070073
74 guard += "_";
75 guard += baseName;
76 guard += "_H_";
77
78 return guard;
79}
80
Steven Morelandee88eed2016-10-31 17:49:00 -070081// static
82void AST::generateCppPackageInclude(
83 Formatter &out,
84 const FQName &package,
85 const std::string &klass) {
86
87 out << "#include <";
88
89 std::vector<std::string> components;
90 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
91
92 for (const auto &component : components) {
93 out << component << "/";
94 }
95
96 out << klass
97 << ".h>\n";
98}
99
Andreas Huber881227d2016-08-02 14:20:21 -0700100void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
101 std::vector<std::string> packageComponents;
102 getPackageAndVersionComponents(
103 &packageComponents, true /* cpp_compatible */);
104
105 if (enter) {
106 for (const auto &component : packageComponents) {
107 out << "namespace " << component << " {\n";
108 }
Andreas Huber0e00de42016-08-03 09:56:02 -0700109
Andreas Huber2831d512016-08-15 09:33:47 -0700110 out.setNamespace(mPackage.cppNamespace() + "::");
Andreas Huber881227d2016-08-02 14:20:21 -0700111 } else {
Andreas Huber0e00de42016-08-03 09:56:02 -0700112 out.setNamespace(std::string());
113
Andreas Huber881227d2016-08-02 14:20:21 -0700114 for (auto it = packageComponents.rbegin();
115 it != packageComponents.rend();
116 ++it) {
117 out << "} // namespace " << *it << "\n";
118 }
119 }
120}
121
Andreas Huberb82318c2016-08-02 14:45:54 -0700122status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700123
Andreas Huberb82318c2016-08-02 14:45:54 -0700124 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700125 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700126 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700127
128 std::string ifaceName;
129 bool isInterface = true;
130 if (!AST::isInterface(&ifaceName)) {
131 ifaceName = "types";
132 isInterface = false;
133 }
134 path.append(ifaceName);
135 path.append(".h");
136
Andreas Huberd2943e12016-08-05 11:59:31 -0700137 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700138 FILE *file = fopen(path.c_str(), "w");
139
140 if (file == NULL) {
141 return -errno;
142 }
143
144 Formatter out(file);
145
146 const std::string guard = makeHeaderGuard(ifaceName);
147
148 out << "#ifndef " << guard << "\n";
149 out << "#define " << guard << "\n\n";
150
Andreas Huber737080b2016-08-02 15:38:04 -0700151 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700152 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700153 }
154
155 if (!mImportedNames.empty()) {
156 out << "\n";
157 }
158
Martijn Coenen7473fab2016-08-19 14:05:40 +0200159 out << "#include <hidl/HidlSupport.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700160 out << "#include <hidl/IServiceManager.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700161 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700162
163 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200164 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700165 }
166
167 out << "#include <utils/NativeHandle.h>\n\n";
168
169 enterLeaveNamespace(out, true /* enter */);
170 out << "\n";
171
172 if (isInterface) {
173 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700174 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700175
176 const Interface *iface = mRootScope->getInterface();
177 const Interface *superType = iface->superType();
178
Steven Moreland40786312016-08-16 10:29:40 -0700179 if (superType == NULL) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700180 out << " : virtual public IHidlInterfaceBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700181 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000182 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700183 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700184 }
185
186 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700187
188 out.indent();
189
Andreas Huber881227d2016-08-02 14:20:21 -0700190 }
191
192 status_t err = emitTypeDeclarations(out);
193
194 if (err != OK) {
195 return err;
196 }
197
198 if (isInterface) {
199 const Interface *iface = mRootScope->getInterface();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700200 const Interface *superType = iface->superType();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700201 const std::string baseName = iface->getBaseName();
Martijn Coenena21f1492016-09-08 15:55:14 +0200202 out << "constexpr static hidl_version version = {"
203 << mPackage.getPackageMajorVersion() << ","
204 << mPackage.getPackageMinorVersion() << "};\n";
205 out << "virtual const hidl_version& getInterfaceVersion() const {\n";
206 out.indent();
207 out << "return version;\n";
208 out.unindent();
209 out << "}\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700210 out << "virtual bool isRemote() const override { return false; }\n\n";
Yifan Hong2d7126b2016-10-20 15:12:57 -0700211 out << "virtual ::android::sp<::android::hardware::IBinder> "
212 << "toBinder() override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700213 bool haveCallbacks = false;
214 for (const auto &method : iface->methods()) {
215 const bool returnsValue = !method->results().empty();
216
217 if (!returnsValue) {
218 continue;
219 }
220
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700221 if (method->canElideCallback() != nullptr) {
222 continue;
223 }
224
Andreas Huber881227d2016-08-02 14:20:21 -0700225 haveCallbacks = true;
226
227 out << "using "
228 << method->name()
229 << "_cb = std::function<void("
Steven Moreland979e0992016-09-07 09:18:08 -0700230 << Method::GetArgSignature(method->results(),
231 true /* specify namespaces */)
Andreas Huber881227d2016-08-02 14:20:21 -0700232 << ")>;\n";
233 }
234
235 if (haveCallbacks) {
236 out << "\n";
237 }
238
239 for (const auto &method : iface->methods()) {
240 const bool returnsValue = !method->results().empty();
241
Andreas Huber3599d922016-08-09 10:42:57 -0700242 method->dumpAnnotations(out);
243
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700244 const TypedVar *elidedReturn = method->canElideCallback();
245 if (elidedReturn) {
246 std::string extra;
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700247 out << "virtual ::android::hardware::Return<";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700248 out << elidedReturn->type().getCppResultType(&extra) << "> ";
249 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700250 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700251 }
252
253 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700254 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700255 << Method::GetArgSignature(method->args(),
256 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700257
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700258 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700259 if (!method->args().empty()) {
260 out << ", ";
261 }
262
Steven Moreland67f67b42016-09-29 08:59:02 -0700263 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700264 }
265
Yifan Hong10fe0b52016-10-19 14:20:17 -0700266 out << ")";
267 if (method->isHidlReserved()) {
268 out << " override";
269 out << " {\n";
270 out.indent();
271 method->cppImpl(out);
272 out.unindent();
273 out << "\n}\n";
274 } else {
275 out << " = 0;\n";
276 }
Andreas Huber881227d2016-08-02 14:20:21 -0700277 }
Steven Moreland40786312016-08-16 10:29:40 -0700278
Yifan Hongfe95aa22016-10-19 17:26:45 -0700279 if (!iface->isRootType()) {
280 out << "// cast static functions\n";
281 std::string childTypeExtra;
282 std::string childTypeResult = iface->getCppResultType(&childTypeExtra);
283 childTypeResult += childTypeExtra;
284
285 for (const Interface *superType : iface->superTypeChain()) {
286 std::string superTypeExtra;
287 out << "static "
288 << childTypeResult
289 << " castFrom("
290 << superType->getCppArgumentType(&superTypeExtra)
291 << " parent"
292 << superTypeExtra
293 << ");\n";
294 }
295 }
296
Yifan Hong10fe0b52016-10-19 14:20:17 -0700297 out << "\nstatic const ::android::String16 descriptor;\n\n";
298
Steven Moreland40786312016-08-16 10:29:40 -0700299 out << "DECLARE_REGISTER_AND_GET_SERVICE(" << baseName << ")\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700300 }
301
302 if (isInterface) {
303 out.unindent();
304
Andreas Hubere3f769a2016-10-10 10:54:44 -0700305 out << "};\n\n";
306 }
307
308 err = mRootScope->emitGlobalTypeDeclarations(out);
309
310 if (err != OK) {
311 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700312 }
313
314 out << "\n";
315 enterLeaveNamespace(out, false /* enter */);
316
317 out << "\n#endif // " << guard << "\n";
318
319 return OK;
320}
321
Steven Moreland40786312016-08-16 10:29:40 -0700322status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
323 std::string ifaceName;
324 if(!AST::isInterface(&ifaceName)) {
325 // types.hal does not get an HwBinder header.
326 return OK;
327 }
328
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700329 const Interface *iface = mRootScope->getInterface();
330 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700331
332 const std::string klassName = "IHw" + baseName;
333
334 std::string path = outputPath;
335 path.append(mCoordinator->convertPackageRootToPath(mPackage));
336 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
337 path.append(klassName + ".h");
338
339 FILE* file = fopen(path.c_str(), "w");
340
341 if (file == NULL) {
342 return -errno;
343 }
344
345 Formatter out(file);
346
347 const std::string guard = makeHeaderGuard(klassName);
348
349 out << "#ifndef " << guard << "\n";
350 out << "#define " << guard << "\n\n";
351
Steven Morelandee88eed2016-10-31 17:49:00 -0700352 generateCppPackageInclude(out, mPackage, ifaceName);
Steven Moreland40786312016-08-16 10:29:40 -0700353
Steven Morelandee88eed2016-10-31 17:49:00 -0700354 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700355
356 for (const auto &item : mImportedNames) {
357 if (item.name() == "types") {
358 continue;
359 }
360
Steven Morelandee88eed2016-10-31 17:49:00 -0700361 generateCppPackageInclude(out, item, "Bn" + item.getInterfaceBaseName());
Steven Moreland40786312016-08-16 10:29:40 -0700362 }
363
364 out << "\n";
365
366 out << "#include <hidl/HidlSupport.h>\n";
Martijn Coenen93915102016-09-01 01:35:52 +0200367 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700368 out << "#include <hwbinder/IBinder.h>\n";
369 out << "#include <hwbinder/IInterface.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700370
371 out << "\n";
372
373 enterLeaveNamespace(out, true /* enter */);
374 out << "\n";
375
376 out << "struct "
377 << klassName
378 << " : public "
379 << ifaceName;
380
Steven Moreland40786312016-08-16 10:29:40 -0700381 const Interface *superType = iface->superType();
382
383 out << ", public ::android::hardware::IInterface";
384
385 out << " {\n";
386
387 out.indent();
388
389 out << "DECLARE_HWBINDER_META_INTERFACE(" << baseName << ");\n\n";
390
Steven Moreland40786312016-08-16 10:29:40 -0700391 out.unindent();
392
393 out << "};\n\n";
394
395 enterLeaveNamespace(out, false /* enter */);
396
397 out << "\n#endif // " << guard << "\n";
398
399 return OK;
400}
401
Andreas Huber881227d2016-08-02 14:20:21 -0700402status_t AST::emitTypeDeclarations(Formatter &out) const {
403 return mRootScope->emitTypeDeclarations(out);
404}
405
Steven Morelanda7a421a2016-09-07 08:35:18 -0700406status_t AST::generateStubMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700407 const Method *method) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700408 out << "inline ";
409
Yifan Hong068c5522016-10-31 14:07:25 -0700410 method->generateCppSignature(out);
Steven Morelanda7a421a2016-09-07 08:35:18 -0700411
412 const bool returnsValue = !method->results().empty();
413 const TypedVar *elidedReturn = method->canElideCallback();
414 out << " {\n";
415 out.indent();
416 out << "return mImpl->"
417 << method->name()
418 << "(";
419 bool first = true;
420 for (const auto &arg : method->args()) {
421 if (!first) {
422 out << ", ";
423 }
424 first = false;
425 out << arg->name();
426 }
427 if (returnsValue && elidedReturn == nullptr) {
428 if (!method->args().empty()) {
429 out << ", ";
430 }
431
432 out << "_hidl_cb";
433 }
434 out << ");\n";
435 out.unindent();
436 out << "}";
437
438 out << ";\n";
439
440 return OK;
441}
442
Steven Moreland69e7c702016-09-09 11:16:32 -0700443status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700444 const Method *method) const {
445 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700446
447 out << " {\n";
448 out.indent();
449
450 const bool returnsValue = !method->results().empty();
451 const TypedVar *elidedReturn = method->canElideCallback();
452
Steven Moreland67f67b42016-09-29 08:59:02 -0700453 if (returnsValue && elidedReturn == nullptr) {
454 generateCheckNonNull(out, "_hidl_cb");
455 }
456
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700457 generateCppInstrumentationCall(
458 out,
459 InstrumentationEvent::PASSTHROUGH_ENTRY,
460 method);
461
462 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700463
464 if (method->isOneway()) {
465 out << "addOnewayTask([this";
466 for (const auto &arg : method->args()) {
467 out << ", " << arg->name();
468 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700469 out << "] {\n";
470 out.indent();
471 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700472 }
473
474 out << "mImpl->"
475 << method->name()
476 << "(";
477
478 bool first = true;
479 for (const auto &arg : method->args()) {
480 if (!first) {
481 out << ", ";
482 }
483 first = false;
484 out << arg->name();
485 }
486 if (returnsValue && elidedReturn == nullptr) {
487 if (!method->args().empty()) {
488 out << ", ";
489 }
490
491 out << "_hidl_cb";
492 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700493 out << ");\n\n";
494
495 generateCppInstrumentationCall(
496 out,
497 InstrumentationEvent::PASSTHROUGH_EXIT,
498 method);
Steven Moreland69e7c702016-09-09 11:16:32 -0700499
500 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700501 out.unindent();
502 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700503 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700504
505 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700506
507 out.unindent();
508 out << "}\n";
509
510 return OK;
511}
512
Yifan Hong068c5522016-10-31 14:07:25 -0700513status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700514
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700515 const Interface *iface = mRootScope->getInterface();
516
Yifan Hong10fe0b52016-10-19 14:20:17 -0700517 const Interface *prevIterface = nullptr;
518 for (const auto &tuple : iface->allMethodsFromRoot()) {
519 const Method *method = tuple.method();
520 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700521
Yifan Hong10fe0b52016-10-19 14:20:17 -0700522 if(prevIterface != superInterface) {
523 if (prevIterface != nullptr) {
524 out << "\n";
525 }
526 out << "// Methods from "
527 << superInterface->fullName()
528 << " follow.\n";
529 prevIterface = superInterface;
530 }
Yifan Hong068c5522016-10-31 14:07:25 -0700531 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700532
Yifan Hong10fe0b52016-10-19 14:20:17 -0700533 if (err != OK) {
534 return err;
535 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700536 }
537
Yifan Hong10fe0b52016-10-19 14:20:17 -0700538 out << "\n";
539
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700540 return OK;
541}
542
Andreas Huberb82318c2016-08-02 14:45:54 -0700543status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700544 std::string ifaceName;
545 if (!AST::isInterface(&ifaceName)) {
546 // types.hal does not get a stub header.
547 return OK;
548 }
549
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700550 const Interface *iface = mRootScope->getInterface();
551 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700552 const std::string klassName = "Bn" + baseName;
Andreas Huber881227d2016-08-02 14:20:21 -0700553
Andreas Huberb82318c2016-08-02 14:45:54 -0700554 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700555 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700556 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700557 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700558 path.append(".h");
559
Andreas Huberd2943e12016-08-05 11:59:31 -0700560 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700561 FILE *file = fopen(path.c_str(), "w");
562
563 if (file == NULL) {
564 return -errno;
565 }
566
567 Formatter out(file);
568
Steven Moreland40786312016-08-16 10:29:40 -0700569 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700570
571 out << "#ifndef " << guard << "\n";
572 out << "#define " << guard << "\n\n";
573
Steven Morelandee88eed2016-10-31 17:49:00 -0700574 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
575 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700576
577 enterLeaveNamespace(out, true /* enter */);
578 out << "\n";
579
580 out << "struct "
581 << "Bn"
582 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700583 << " : public ::android::hardware::BnInterface<I"
584 << baseName << ", IHw" << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700585 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700586
587 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700588 out << "explicit Bn"
589 << baseName
590 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
591 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700592 out << "::android::status_t onTransact(\n";
593 out.indent();
594 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700595 out << "uint32_t _hidl_code,\n";
596 out << "const ::android::hardware::Parcel &_hidl_data,\n";
597 out << "::android::hardware::Parcel *_hidl_reply,\n";
598 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700599 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700600 out.unindent();
601 out.unindent();
602
Yifan Hong068c5522016-10-31 14:07:25 -0700603 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
604 return generateStubMethod(out, method);
605 });
Steven Moreland9c387612016-09-07 09:54:26 -0700606
607 if (err != OK) {
608 return err;
609 }
610
Zhuoyao Zhangde578002016-09-07 18:24:17 -0700611
Andreas Huber881227d2016-08-02 14:20:21 -0700612 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700613 out << "};\n\n";
614
615 enterLeaveNamespace(out, false /* enter */);
616
617 out << "\n#endif // " << guard << "\n";
618
619 return OK;
620}
621
Andreas Huberb82318c2016-08-02 14:45:54 -0700622status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700623 std::string ifaceName;
624 if (!AST::isInterface(&ifaceName)) {
625 // types.hal does not get a proxy header.
626 return OK;
627 }
628
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700629 const Interface *iface = mRootScope->getInterface();
630 const std::string baseName = iface->getBaseName();
Andreas Huber881227d2016-08-02 14:20:21 -0700631
Andreas Huberb82318c2016-08-02 14:45:54 -0700632 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700633 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700634 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700635 path.append("Bp");
636 path.append(baseName);
637 path.append(".h");
638
Andreas Huberd2943e12016-08-05 11:59:31 -0700639 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700640 FILE *file = fopen(path.c_str(), "w");
641
642 if (file == NULL) {
643 return -errno;
644 }
645
646 Formatter out(file);
647
648 const std::string guard = makeHeaderGuard("Bp" + baseName);
649
650 out << "#ifndef " << guard << "\n";
651 out << "#define " << guard << "\n\n";
652
653 std::vector<std::string> packageComponents;
654 getPackageAndVersionComponents(
655 &packageComponents, false /* cpp_compatible */);
656
Steven Morelandee88eed2016-10-31 17:49:00 -0700657 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
658 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700659
660 enterLeaveNamespace(out, true /* enter */);
661 out << "\n";
662
663 out << "struct "
664 << "Bp"
665 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700666 << " : public ::android::hardware::BpInterface<IHw"
667 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700668 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700669
670 out.indent();
671
672 out << "explicit Bp"
673 << baseName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700674 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700675 << "\n\n";
676
Yifan Hong10fe0b52016-10-19 14:20:17 -0700677 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700678
Yifan Hong068c5522016-10-31 14:07:25 -0700679 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
680 method->generateCppSignature(out);
681 out << " override;\n";
682 return OK;
683 });
Steven Moreland9c387612016-09-07 09:54:26 -0700684
685 if (err != OK) {
686 return err;
687 }
Andreas Huber881227d2016-08-02 14:20:21 -0700688
689 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700690 out << "};\n\n";
691
692 enterLeaveNamespace(out, false /* enter */);
693
694 out << "\n#endif // " << guard << "\n";
695
696 return OK;
697}
698
Andreas Huberb82318c2016-08-02 14:45:54 -0700699status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700700
Andreas Huberb82318c2016-08-02 14:45:54 -0700701 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700702 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700703 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700704
705 std::string ifaceName;
706 std::string baseName;
707
Yifan Hongfe95aa22016-10-19 17:26:45 -0700708 const Interface *iface = nullptr;
709 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700710 if (!AST::isInterface(&ifaceName)) {
711 baseName = "types";
712 isInterface = false;
713 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700714 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700715 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700716 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700717 }
718
719 path.append(baseName);
720
721 if (baseName != "types") {
722 path.append("All");
723 }
724
725 path.append(".cpp");
726
Andreas Huberd2943e12016-08-05 11:59:31 -0700727 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700728 FILE *file = fopen(path.c_str(), "w");
729
730 if (file == NULL) {
731 return -errno;
732 }
733
734 Formatter out(file);
735
Andreas Huber881227d2016-08-02 14:20:21 -0700736 if (isInterface) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700737 generateCppPackageInclude(out, mPackage, "Bp" + baseName);
738 generateCppPackageInclude(out, mPackage, "Bn" + baseName);
739 generateCppPackageInclude(out, mPackage, "Bs" + baseName);
Yifan Hongfe95aa22016-10-19 17:26:45 -0700740
741 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700742 generateCppPackageInclude(out,
743 superType->fqName(),
744 "Bp" + superType->getBaseName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700745 }
Andreas Huber881227d2016-08-02 14:20:21 -0700746 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700747 generateCppPackageInclude(out, mPackage, "types");
Andreas Huber881227d2016-08-02 14:20:21 -0700748 }
749
750 out << "\n";
751
752 enterLeaveNamespace(out, true /* enter */);
753 out << "\n";
754
755 status_t err = generateTypeSource(out, ifaceName);
756
757 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700758 const Interface *iface = mRootScope->getInterface();
Martijn Coenena21f1492016-09-08 15:55:14 +0200759 out << "constexpr hidl_version " << ifaceName << "::version;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700760
761 // need to be put here, generateStubSource is using this.
762 out << "const ::android::String16 I"
763 << iface->getBaseName()
764 << "::descriptor(\""
765 << iface->fqName().string()
766 << "\");\n\n";
767
Yifan Hongfe95aa22016-10-19 17:26:45 -0700768 err = generateInterfaceSource(out);
769 }
770
771 if (err == OK && isInterface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700772 err = generateProxySource(out, baseName);
773 }
774
775 if (err == OK && isInterface) {
776 err = generateStubSource(out, baseName);
777 }
778
Steven Moreland40786312016-08-16 10:29:40 -0700779 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -0700780 err = generatePassthroughSource(out);
781 }
782
783 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -0700784 const Interface *iface = mRootScope->getInterface();
785
786 out << "IMPLEMENT_REGISTER_AND_GET_SERVICE("
787 << baseName << ", "
788 << "\"" << iface->fqName().package()
Iliyan Malchev4923f932016-09-09 13:04:59 -0700789 << iface->fqName().version() << "-impl.so\""
Steven Moreland9c387612016-09-07 09:54:26 -0700790 << ")\n";
Steven Moreland40786312016-08-16 10:29:40 -0700791 }
792
Andreas Huber881227d2016-08-02 14:20:21 -0700793 enterLeaveNamespace(out, false /* enter */);
794
795 return err;
796}
797
Steven Moreland67f67b42016-09-29 08:59:02 -0700798// static
799void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
800 out << "if (" << nonNull << " == nullptr) {\n";
801 out.indent();
802 out << "return ::android::hardware::Status::fromExceptionCode(\n";
803 out.indent();
804 out.indent();
805 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
806 out.unindent();
807 out.unindent();
808 out.unindent();
809 out << "}\n\n";
810}
811
Andreas Huber881227d2016-08-02 14:20:21 -0700812status_t AST::generateTypeSource(
813 Formatter &out, const std::string &ifaceName) const {
814 return mRootScope->emitTypeDefinitions(out, ifaceName);
815}
816
Andreas Hubere7ff2282016-08-16 13:50:03 -0700817void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -0700818 Formatter &out,
819 const std::vector<TypedVar *> &args,
820 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700821 if (args.empty()) {
822 return;
823 }
824
825 for (const auto &arg : args) {
826 const Type &type = arg->type();
827
828 std::string extra;
829 out << type.getCppResultType(&extra)
830 << " "
Andreas Huber5e44a292016-09-27 14:52:39 -0700831 << (forResults ? "_hidl_out_" : "")
Andreas Hubere7ff2282016-08-16 13:50:03 -0700832 << arg->name()
833 << extra
834 << ";\n";
835 }
836
837 out << "\n";
838}
839
Andreas Huber881227d2016-08-02 14:20:21 -0700840void AST::emitCppReaderWriter(
841 Formatter &out,
842 const std::string &parcelObj,
843 bool parcelObjIsPointer,
844 const TypedVar *arg,
845 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -0700846 Type::ErrorMode mode,
847 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700848 const Type &type = arg->type();
849
Andreas Huber881227d2016-08-02 14:20:21 -0700850 type.emitReaderWriter(
851 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700852 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700853 parcelObj,
854 parcelObjIsPointer,
855 isReader,
856 mode);
857}
858
Yifan Hongbf459bc2016-08-23 16:50:37 -0700859void AST::emitCppResolveReferences(
860 Formatter &out,
861 const std::string &parcelObj,
862 bool parcelObjIsPointer,
863 const TypedVar *arg,
864 bool isReader,
865 Type::ErrorMode mode,
866 bool addPrefixToName) const {
867 const Type &type = arg->type();
868 if(type.needsResolveReferences()) {
869 type.emitResolveReferences(
870 out,
871 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
872 isReader, // nameIsPointer
873 parcelObj,
874 parcelObjIsPointer,
875 isReader,
876 mode);
877 }
878}
879
Yifan Hong068c5522016-10-31 14:07:25 -0700880status_t AST::generateProxyMethodSource(Formatter &out,
881 const std::string &klassName,
882 const Method *method,
883 const Interface *superInterface) const {
884
885 method->generateCppSignature(out,
886 klassName,
887 true /* specify namespaces */);
888
889 const bool returnsValue = !method->results().empty();
890 const TypedVar *elidedReturn = method->canElideCallback();
891
892 out << "{\n";
893
894 out.indent();
895
896 if (returnsValue && elidedReturn == nullptr) {
897 generateCheckNonNull(out, "_hidl_cb");
898 }
899
900 status_t status = generateCppInstrumentationCall(
901 out,
902 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -0700903 method);
904 if (status != OK) {
905 return status;
906 }
907
908 out << "::android::hardware::Parcel _hidl_data;\n";
909 out << "::android::hardware::Parcel _hidl_reply;\n";
910 out << "::android::status_t _hidl_err;\n";
911 out << "::android::hardware::Status _hidl_status;\n\n";
912
913 declareCppReaderLocals(
914 out, method->results(), true /* forResults */);
915
916 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
917 if (!method->isHidlReserved()) {
918 out << superInterface->fqName().cppNamespace()
919 << "::IHw"
920 << superInterface->getBaseName();
921 } else {
922 out << "::android::hardware::IHidlInterfaceBase";
923 }
924 out << "::descriptor);\n";
925
926 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
927
928 // First DFS: write all buffers and resolve pointers for parent
929 for (const auto &arg : method->args()) {
930 emitCppReaderWriter(
931 out,
932 "_hidl_data",
933 false /* parcelObjIsPointer */,
934 arg,
935 false /* reader */,
936 Type::ErrorMode_Goto,
937 false /* addPrefixToName */);
938 }
939
940 // Second DFS: resolve references.
941 for (const auto &arg : method->args()) {
942 emitCppResolveReferences(
943 out,
944 "_hidl_data",
945 false /* parcelObjIsPointer */,
946 arg,
947 false /* reader */,
948 Type::ErrorMode_Goto,
949 false /* addPrefixToName */);
950 }
951
952 out << "_hidl_err = remote()->transact("
953 << method->getSerialId()
954 << " /* "
955 << method->name()
956 << " */, _hidl_data, &_hidl_reply";
957
958 if (method->isOneway()) {
959 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
960 }
961 out << ");\n";
962
963 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
964
965 if (!method->isOneway()) {
966 out << "_hidl_err = _hidl_status.readFromParcel(_hidl_reply);\n";
967 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
968 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
969
970
971 // First DFS: write all buffers and resolve pointers for parent
972 for (const auto &arg : method->results()) {
973 emitCppReaderWriter(
974 out,
975 "_hidl_reply",
976 false /* parcelObjIsPointer */,
977 arg,
978 true /* reader */,
979 Type::ErrorMode_Goto,
980 true /* addPrefixToName */);
981 }
982
983 // Second DFS: resolve references.
984 for (const auto &arg : method->results()) {
985 emitCppResolveReferences(
986 out,
987 "_hidl_reply",
988 false /* parcelObjIsPointer */,
989 arg,
990 true /* reader */,
991 Type::ErrorMode_Goto,
992 true /* addPrefixToName */);
993 }
994
995 if (returnsValue && elidedReturn == nullptr) {
996 out << "_hidl_cb(";
997
998 bool first = true;
999 for (const auto &arg : method->results()) {
1000 if (!first) {
1001 out << ", ";
1002 }
1003
1004 if (arg->type().resultNeedsDeref()) {
1005 out << "*";
1006 }
1007 out << "_hidl_out_" << arg->name();
1008
1009 first = false;
1010 }
1011
1012 out << ");\n\n";
1013 }
1014 status_t status = generateCppInstrumentationCall(
1015 out,
1016 InstrumentationEvent::CLIENT_API_EXIT,
Yifan Hong068c5522016-10-31 14:07:25 -07001017 method);
1018 if (status != OK) {
1019 return status;
1020 }
1021 }
1022
1023 if (elidedReturn != nullptr) {
1024 std::string extra;
1025 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1026 out << "return ::android::hardware::Return<";
1027 out << elidedReturn->type().getCppResultType(&extra)
1028 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1029 } else {
1030 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1031 out << "return ::android::hardware::Return<void>();\n\n";
1032 }
1033
1034 out.unindent();
1035 out << "_hidl_error:\n";
1036 out.indent();
1037 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1038 out << "return ::android::hardware::Return<";
1039 if (elidedReturn != nullptr) {
1040 std::string extra;
1041 out << method->results().at(0)->type().getCppResultType(&extra);
1042 } else {
1043 out << "void";
1044 }
1045 out << ">(_hidl_status);\n";
1046
1047 out.unindent();
1048 out << "}\n\n";
1049 return OK;
1050}
1051
Andreas Huber881227d2016-08-02 14:20:21 -07001052status_t AST::generateProxySource(
1053 Formatter &out, const std::string &baseName) const {
1054 const std::string klassName = "Bp" + baseName;
1055
1056 out << klassName
1057 << "::"
1058 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001059 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001060
1061 out.indent();
1062 out.indent();
1063
1064 out << ": BpInterface"
Steven Moreland40786312016-08-16 10:29:40 -07001065 << "<IHw"
Andreas Huber881227d2016-08-02 14:20:21 -07001066 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001067 << ">(_hidl_impl),\n"
1068 << " HidlInstrumentor(\""
1069 << mPackage.string()
1070 << "::I"
1071 << baseName
1072 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001073
Andreas Huber881227d2016-08-02 14:20:21 -07001074 out.unindent();
1075 out.unindent();
1076 out << "}\n\n";
1077
Yifan Hong068c5522016-10-31 14:07:25 -07001078 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1079 return generateProxyMethodSource(out, klassName, method, superInterface);
1080 });
Andreas Huber881227d2016-08-02 14:20:21 -07001081
Yifan Hong068c5522016-10-31 14:07:25 -07001082 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001083}
1084
1085status_t AST::generateStubSource(
1086 Formatter &out, const std::string &baseName) const {
1087 out << "IMPLEMENT_HWBINDER_META_INTERFACE("
1088 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001089 << ", "
1090 << mPackage.cppNamespace()
Andreas Huber881227d2016-08-02 14:20:21 -07001091 << "::I"
1092 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001093 << "::descriptor);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001094
1095 const std::string klassName = "Bn" + baseName;
1096
Steven Moreland40786312016-08-16 10:29:40 -07001097 out << klassName
1098 << "::"
1099 << klassName
1100 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl)\n";
1101
1102 out.indent();
1103 out.indent();
1104
1105 out << ": BnInterface"
1106 << "<I"
1107 << baseName
1108 << ", IHw"
1109 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001110 << ">(_hidl_impl),\n"
1111 << " HidlInstrumentor(\""
1112 << mPackage.string()
1113 << "::I"
1114 << baseName
1115 << "\") {\n";
Steven Moreland40786312016-08-16 10:29:40 -07001116
1117 out.unindent();
1118 out.unindent();
1119 out << "}\n\n";
1120
Andreas Huber881227d2016-08-02 14:20:21 -07001121 out << "::android::status_t " << klassName << "::onTransact(\n";
1122
1123 out.indent();
1124 out.indent();
1125
Iliyan Malchev549e2592016-08-10 08:59:12 -07001126 out << "uint32_t _hidl_code,\n"
1127 << "const ::android::hardware::Parcel &_hidl_data,\n"
1128 << "::android::hardware::Parcel *_hidl_reply,\n"
1129 << "uint32_t _hidl_flags,\n"
1130 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001131
1132 out.unindent();
1133
Iliyan Malchev549e2592016-08-10 08:59:12 -07001134 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001135 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001136 out.indent();
1137
1138 const Interface *iface = mRootScope->getInterface();
1139
Yifan Hong10fe0b52016-10-19 14:20:17 -07001140 for (const auto &tuple : iface->allMethodsFromRoot()) {
1141 const Method *method = tuple.method();
1142 const Interface *superInterface = tuple.interface();
1143 out << "case "
1144 << method->getSerialId()
1145 << " /* "
1146 << method->name()
1147 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001148
Yifan Hong10fe0b52016-10-19 14:20:17 -07001149 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001150
Yifan Hong10fe0b52016-10-19 14:20:17 -07001151 status_t err =
1152 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001153
Yifan Hong10fe0b52016-10-19 14:20:17 -07001154 if (err != OK) {
1155 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001156 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001157
1158 out.unindent();
1159 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001160 }
1161
1162 out << "default:\n{\n";
1163 out.indent();
1164
Andreas Huber8a82ff72016-08-04 10:29:39 -07001165 out << "return ::android::hardware::BnInterface<I"
Steven Moreland40786312016-08-16 10:29:40 -07001166 << baseName << ", IHw" << baseName
Andreas Huber881227d2016-08-02 14:20:21 -07001167 << ">::onTransact(\n";
1168
1169 out.indent();
1170 out.indent();
1171
Iliyan Malchev549e2592016-08-10 08:59:12 -07001172 out << "_hidl_code, _hidl_data, _hidl_reply, "
1173 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001174
1175 out.unindent();
1176 out.unindent();
1177
1178 out.unindent();
1179 out << "}\n";
1180
1181 out.unindent();
1182 out << "}\n\n";
1183
Iliyan Malchev549e2592016-08-10 08:59:12 -07001184 out << "if (_hidl_err == ::android::UNEXPECTED_NULL) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001185 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001186 out << "_hidl_err = ::android::hardware::Status::fromExceptionCode(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001187 out.indent();
1188 out.indent();
Andreas Huber8a82ff72016-08-04 10:29:39 -07001189 out << "::android::hardware::Status::EX_NULL_POINTER)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001190 out.indent();
1191 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001192 out << ".writeToParcel(_hidl_reply);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001193 out.unindent();
1194 out.unindent();
1195 out.unindent();
1196 out.unindent();
1197
1198 out.unindent();
1199 out << "}\n\n";
1200
Iliyan Malchev549e2592016-08-10 08:59:12 -07001201 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001202
1203 out.unindent();
1204 out << "}\n\n";
1205
1206 return OK;
1207}
1208
1209status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001210 Formatter &out, const Interface *iface, const Method *method) const {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001211 out << "if (!_hidl_data.enforceInterface(";
1212
1213 if (!method->isHidlReserved()) {
1214 out << iface->fqName().cppNamespace()
1215 << "::IHw"
1216 << iface->getBaseName();
1217 } else {
1218 out << "::android::hardware::IHidlInterfaceBase";
1219 }
1220
1221 out << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001222
Andreas Huber881227d2016-08-02 14:20:21 -07001223 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001224 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001225 out << "break;\n";
1226 out.unindent();
1227 out << "}\n\n";
1228
Andreas Huber5e44a292016-09-27 14:52:39 -07001229 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001230
Yifan Hongbf459bc2016-08-23 16:50:37 -07001231 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001232 for (const auto &arg : method->args()) {
1233 emitCppReaderWriter(
1234 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001235 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001236 false /* parcelObjIsPointer */,
1237 arg,
1238 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001239 Type::ErrorMode_Break,
1240 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001241 }
1242
Yifan Hongbf459bc2016-08-23 16:50:37 -07001243 // Second DFS: resolve references
1244 for (const auto &arg : method->args()) {
1245 emitCppResolveReferences(
1246 out,
1247 "_hidl_data",
1248 false /* parcelObjIsPointer */,
1249 arg,
1250 true /* reader */,
1251 Type::ErrorMode_Break,
1252 false /* addPrefixToName */);
1253 }
1254
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001255 status_t status = generateCppInstrumentationCall(
1256 out,
1257 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001258 method);
1259 if (status != OK) {
1260 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001261 }
1262
Andreas Huber881227d2016-08-02 14:20:21 -07001263 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001264 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001265
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001266 if (elidedReturn != nullptr) {
1267 std::string extra;
Andreas Huber881227d2016-08-02 14:20:21 -07001268
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001269 out << elidedReturn->type().getCppResultType(&extra) << " ";
1270 out << elidedReturn->name() << " = ";
1271 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001272
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001273 bool first = true;
1274 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001275 if (!first) {
1276 out << ", ";
1277 }
1278
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001279 if (arg->type().resultNeedsDeref()) {
1280 out << "*";
1281 }
1282
1283 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001284
1285 first = false;
1286 }
1287
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001288 out << ");\n\n";
Andreas Huber8a82ff72016-08-04 10:29:39 -07001289 out << "::android::hardware::Status::ok()"
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001290 << ".writeToParcel(_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001291
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001292 elidedReturn->type().emitReaderWriter(
1293 out,
1294 elidedReturn->name(),
1295 "_hidl_reply",
1296 true, /* parcelObjIsPointer */
1297 false, /* isReader */
1298 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001299
Yifan Hongbf459bc2016-08-23 16:50:37 -07001300 emitCppResolveReferences(
1301 out,
1302 "_hidl_reply",
1303 true /* parcelObjIsPointer */,
1304 elidedReturn,
1305 false /* reader */,
1306 Type::ErrorMode_Ignore,
1307 false /* addPrefixToName */);
1308
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001309 status_t status = generateCppInstrumentationCall(
1310 out,
1311 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001312 method);
1313 if (status != OK) {
1314 return status;
1315 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001316
Iliyan Malchev549e2592016-08-10 08:59:12 -07001317 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001318 } else {
1319 if (returnsValue) {
1320 out << "bool _hidl_callbackCalled = false;\n\n";
1321 }
Andreas Huber881227d2016-08-02 14:20:21 -07001322
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001323 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001324
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001325 bool first = true;
1326 for (const auto &arg : method->args()) {
1327 if (!first) {
1328 out << ", ";
1329 }
Andreas Huber881227d2016-08-02 14:20:21 -07001330
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001331 if (arg->type().resultNeedsDeref()) {
1332 out << "*";
1333 }
1334
1335 out << arg->name();
1336
1337 first = false;
1338 }
1339
1340 if (returnsValue) {
1341 if (!first) {
1342 out << ", ";
1343 }
1344
1345 out << "[&](";
1346
1347 first = true;
1348 for (const auto &arg : method->results()) {
1349 if (!first) {
1350 out << ", ";
1351 }
1352
1353 out << "const auto &" << arg->name();
1354
1355 first = false;
1356 }
1357
1358 out << ") {\n";
1359 out.indent();
1360 out << "_hidl_callbackCalled = true;\n\n";
1361
1362 out << "::android::hardware::Status::ok()"
1363 << ".writeToParcel(_hidl_reply);\n\n";
1364
Yifan Hongbf459bc2016-08-23 16:50:37 -07001365 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001366 for (const auto &arg : method->results()) {
1367 emitCppReaderWriter(
1368 out,
1369 "_hidl_reply",
1370 true /* parcelObjIsPointer */,
1371 arg,
1372 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001373 Type::ErrorMode_Ignore,
1374 false /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001375 }
1376
Yifan Hongbf459bc2016-08-23 16:50:37 -07001377 // Second DFS: resolve references
1378 for (const auto &arg : method->results()) {
1379 emitCppResolveReferences(
1380 out,
1381 "_hidl_reply",
1382 true /* parcelObjIsPointer */,
1383 arg,
1384 false /* reader */,
1385 Type::ErrorMode_Ignore,
1386 false /* addPrefixToName */);
1387 }
1388
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001389 status_t status = generateCppInstrumentationCall(
1390 out,
1391 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001392 method);
1393 if (status != OK) {
1394 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001395 }
1396
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001397 out << "_hidl_cb(*_hidl_reply);\n";
1398
1399 out.unindent();
1400 out << "}\n";
1401 }
1402
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001403 out << ");\n\n";
1404
1405 // What to do if the stub implementation has a synchronous callback
1406 // which does not get invoked? This is not a transport error but a
1407 // service error of sorts. For now, return OK to the caller, as this is
1408 // not a transport error.
1409 //
1410 // TODO(b/31365311) Figure out how to deal with this later.
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001411
1412 if (returnsValue) {
1413 out << "if (!_hidl_callbackCalled) {\n";
1414 out.indent();
1415 }
1416
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001417 out << "::android::hardware::Status::ok()"
1418 << ".writeToParcel(_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001419
1420 if (returnsValue) {
1421 out.unindent();
1422 out << "}\n\n";
1423 }
Andreas Huber881227d2016-08-02 14:20:21 -07001424 }
1425
1426 out << "break;\n";
1427
1428 return OK;
1429}
1430
Steven Moreland69e7c702016-09-09 11:16:32 -07001431status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1432 std::string ifaceName;
1433 if (!AST::isInterface(&ifaceName)) {
1434 // types.hal does not get a stub header.
1435 return OK;
1436 }
1437
1438 const Interface *iface = mRootScope->getInterface();
1439
1440 const std::string baseName = iface->getBaseName();
1441 const std::string klassName = "Bs" + baseName;
1442
1443 bool supportOneway = iface->hasOnewayMethods();
1444
1445 std::string path = outputPath;
1446 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1447 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1448 path.append(klassName);
1449 path.append(".h");
1450
1451 CHECK(Coordinator::MakeParentHierarchy(path));
1452 FILE *file = fopen(path.c_str(), "w");
1453
1454 if (file == NULL) {
1455 return -errno;
1456 }
1457
1458 Formatter out(file);
1459
1460 const std::string guard = makeHeaderGuard(klassName);
1461
1462 out << "#ifndef " << guard << "\n";
1463 out << "#define " << guard << "\n\n";
1464
1465 std::vector<std::string> packageComponents;
1466 getPackageAndVersionComponents(
1467 &packageComponents, false /* cpp_compatible */);
1468
1469 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001470
1471 generateCppPackageInclude(out, mPackage, ifaceName);
1472 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001473
1474 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001475 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001476 }
1477
1478 enterLeaveNamespace(out, true /* enter */);
1479 out << "\n";
1480
1481 out << "struct "
1482 << klassName
1483 << " : " << ifaceName
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001484 << ", HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001485
1486 out.indent();
1487 out << "explicit "
1488 << klassName
1489 << "(const sp<"
1490 << ifaceName
1491 << "> impl);\n";
1492
Yifan Hong068c5522016-10-31 14:07:25 -07001493 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1494 return generatePassthroughMethod(out, method);
1495 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001496
1497 if (err != OK) {
1498 return err;
1499 }
1500
1501 out.unindent();
1502 out << "private:\n";
1503 out.indent();
1504 out << "const sp<" << ifaceName << "> mImpl;\n";
1505
1506 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001507 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001508
1509 out << "\n";
1510
1511 out << "::android::hardware::Return<void> addOnewayTask("
1512 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001513 }
1514
1515 out.unindent();
1516
1517 out << "};\n\n";
1518
1519 enterLeaveNamespace(out, false /* enter */);
1520
1521 out << "\n#endif // " << guard << "\n";
1522
1523 return OK;
1524}
1525
Yifan Hongfe95aa22016-10-19 17:26:45 -07001526status_t AST::generateInterfaceSource(Formatter &out) const {
1527 const Interface *iface = mRootScope->getInterface();
1528
Yifan Hong2d7126b2016-10-20 15:12:57 -07001529
1530 // generate toBinder functions
1531 out << "::android::sp<::android::hardware::IBinder> I"
1532 << iface->getBaseName()
1533 << "::toBinder() {\n";
1534 out.indent();
1535 out << "if (isRemote()) {\n";
1536 out.indent();
1537 out << "return ::android::hardware::IInterface::asBinder("
1538 << "static_cast<IHw"
1539 << iface->getBaseName()
1540 << " *>(this));\n";
1541 out.unindent();
1542 out << "} else {\n";
1543 out.indent();
1544 out << "return new Bn" << iface->getBaseName() << "(this);\n";
1545 out.unindent();
1546 out << "}\n";
1547 out.unindent();
1548 out << "}\n\n";
1549
1550 // generate castFrom functions
Yifan Hongfe95aa22016-10-19 17:26:45 -07001551 if (!iface->isRootType()) {
1552 std::string childTypeExtra;
1553 std::string childTypeResult = iface->getCppResultType(&childTypeExtra);
1554 childTypeResult += childTypeExtra;
1555
1556 for (const Interface *superType : iface->superTypeChain()) {
1557 std::string superTypeExtra;
1558 out << "// static \n"
1559 << childTypeResult
1560 << " I"
1561 << iface->getBaseName()
1562 << "::castFrom("
1563 << superType->getCppArgumentType(&superTypeExtra)
1564 << " parent"
1565 << superTypeExtra
1566 << ")";
1567 out << " {\n";
1568 out.indent();
1569 out << "return ::android::hardware::castInterface<";
1570 out << "I" << iface->getBaseName() << ", "
1571 << superType->fqName().cppName() << ", "
1572 << "Bp" << iface->getBaseName()
1573 << ">(\n";
1574 out.indent();
1575 out.indent();
1576 out << "parent, \""
1577 << iface->fqName().string()
1578 << "\");\n";
1579 out.unindent();
1580 out.unindent();
1581 out.unindent();
1582 out << "}\n\n";
1583 }
1584 }
1585
1586 return OK;
1587}
1588
Steven Moreland69e7c702016-09-09 11:16:32 -07001589status_t AST::generatePassthroughSource(Formatter &out) const {
1590 const Interface *iface = mRootScope->getInterface();
1591
1592 const std::string baseName = iface->getBaseName();
1593 const std::string klassName = "Bs" + baseName;
1594
1595 out << klassName
1596 << "::"
1597 << klassName
1598 << "(const sp<"
1599 << iface->fullName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001600 << "> impl) : HidlInstrumentor(\""
1601 << iface->fqName().string()
1602 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001603 if (iface->hasOnewayMethods()) {
1604 out << "\n";
1605 out.indentBlock([&] {
1606 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1607 });
1608 }
1609 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001610
1611 if (iface->hasOnewayMethods()) {
1612 out << "::android::hardware::Return<void> "
1613 << klassName
1614 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1615 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001616 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001617 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001618 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1619 out.indent();
1620 out.indent();
1621 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1622 out.unindent();
1623 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001624 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001625 out << "}\n";
1626
Steven Morelandd366c262016-10-11 15:29:10 -07001627 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001628
1629 out.unindent();
1630 out << "}\n\n";
1631
1632
1633 }
1634
1635 return OK;
1636}
1637
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001638status_t AST::generateCppInstrumentationCall(
1639 Formatter &out,
1640 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001641 const Method *method) const {
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001642 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1643 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001644 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001645 std::string event_str = "";
1646 switch (event) {
1647 case SERVER_API_ENTRY:
1648 {
1649 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1650 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001651 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001652 << (arg->type().resultNeedsDeref() ? "" : "&")
1653 << arg->name()
1654 << ");\n";
1655 }
1656 break;
1657 }
1658 case SERVER_API_EXIT:
1659 {
1660 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001661 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001662 out << "_hidl_args.push_back((void *)&"
Steven Moreland031ccf12016-10-31 15:54:38 -07001663 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001664 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001665 }
1666 break;
1667 }
1668 case CLIENT_API_ENTRY:
1669 {
1670 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1671 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001672 out << "_hidl_args.push_back((void *)&"
1673 << arg->name()
1674 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001675 }
1676 break;
1677 }
1678 case CLIENT_API_EXIT:
1679 {
1680 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1681 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001682 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001683 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001684 << "_hidl_out_"
1685 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001686 << ");\n";
1687 }
1688 break;
1689 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001690 case PASSTHROUGH_ENTRY:
1691 {
1692 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1693 for (const auto &arg : method->args()) {
1694 out << "_hidl_args.push_back((void *)&"
1695 << arg->name()
1696 << ");\n";
1697 }
1698 break;
1699 }
1700 case PASSTHROUGH_EXIT:
1701 {
1702 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
1703 // TODO(b/32576620): passthrough return values
1704 break;
1705 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001706 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001707 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001708 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001709 return UNKNOWN_ERROR;
1710 }
1711 }
1712
Steven Moreland031ccf12016-10-31 15:54:38 -07001713 const Interface *iface = mRootScope->getInterface();
1714
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001715 out << "for (auto callback: mInstrumentationCallbacks) {\n";
1716 out.indent();
1717 out << "callback("
1718 << event_str
1719 << ", \""
1720 << mPackage.package()
1721 << "\", \""
1722 << mPackage.getPackageFullVersion()
1723 << "\", \""
1724 << iface->localName()
1725 << "\", \""
1726 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001727 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001728 out.unindent();
1729 out << "}\n";
1730 out.unindent();
1731 out << "}\n\n";
1732
1733 return OK;
1734}
1735
Andreas Huber881227d2016-08-02 14:20:21 -07001736} // namespace android
1737