blob: f17025c8758aada20476de264933a638c95274bd [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 Moreland19d5c172016-10-20 19:20:25 -0700160 out << "#include <hidl/ServiceManagement.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) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700180 out << " : virtual public ::android::hardware::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();
Steven Moreland19d5c172016-10-20 19:20:25 -0700202 out << "constexpr static ::android::hardware::hidl_version version = {"
Martijn Coenena21f1492016-09-08 15:55:14 +0200203 << mPackage.getPackageMajorVersion() << ","
204 << mPackage.getPackageMinorVersion() << "};\n";
Steven Moreland19d5c172016-10-20 19:20:25 -0700205 out << "virtual const ::android::hardware::hidl_version&"
206 << "getInterfaceVersion() const {\n";
Martijn Coenena21f1492016-09-08 15:55:14 +0200207 out.indent();
208 out << "return version;\n";
209 out.unindent();
210 out << "}\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700211 out << "virtual bool isRemote() const override { return false; }\n\n";
Yifan Hong2d7126b2016-10-20 15:12:57 -0700212 out << "virtual ::android::sp<::android::hardware::IBinder> "
213 << "toBinder() override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700214 bool haveCallbacks = false;
215 for (const auto &method : iface->methods()) {
216 const bool returnsValue = !method->results().empty();
217
218 if (!returnsValue) {
219 continue;
220 }
221
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700222 if (method->canElideCallback() != nullptr) {
223 continue;
224 }
225
Andreas Huber881227d2016-08-02 14:20:21 -0700226 haveCallbacks = true;
227
228 out << "using "
229 << method->name()
230 << "_cb = std::function<void("
Steven Moreland979e0992016-09-07 09:18:08 -0700231 << Method::GetArgSignature(method->results(),
232 true /* specify namespaces */)
Andreas Huber881227d2016-08-02 14:20:21 -0700233 << ")>;\n";
234 }
235
236 if (haveCallbacks) {
237 out << "\n";
238 }
239
240 for (const auto &method : iface->methods()) {
241 const bool returnsValue = !method->results().empty();
242
Andreas Huber3599d922016-08-09 10:42:57 -0700243 method->dumpAnnotations(out);
244
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700245 const TypedVar *elidedReturn = method->canElideCallback();
246 if (elidedReturn) {
247 std::string extra;
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700248 out << "virtual ::android::hardware::Return<";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700249 out << elidedReturn->type().getCppResultType(&extra) << "> ";
250 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700251 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700252 }
253
254 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700255 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700256 << Method::GetArgSignature(method->args(),
257 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700258
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700259 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700260 if (!method->args().empty()) {
261 out << ", ";
262 }
263
Steven Moreland67f67b42016-09-29 08:59:02 -0700264 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700265 }
266
Yifan Hong10fe0b52016-10-19 14:20:17 -0700267 out << ")";
268 if (method->isHidlReserved()) {
269 out << " override";
270 out << " {\n";
271 out.indent();
272 method->cppImpl(out);
273 out.unindent();
274 out << "\n}\n";
275 } else {
276 out << " = 0;\n";
277 }
Andreas Huber881227d2016-08-02 14:20:21 -0700278 }
Steven Moreland40786312016-08-16 10:29:40 -0700279
Yifan Hongfe95aa22016-10-19 17:26:45 -0700280 if (!iface->isRootType()) {
281 out << "// cast static functions\n";
282 std::string childTypeExtra;
283 std::string childTypeResult = iface->getCppResultType(&childTypeExtra);
284 childTypeResult += childTypeExtra;
285
286 for (const Interface *superType : iface->superTypeChain()) {
287 std::string superTypeExtra;
288 out << "static "
289 << childTypeResult
290 << " castFrom("
291 << superType->getCppArgumentType(&superTypeExtra)
292 << " parent"
293 << superTypeExtra
294 << ");\n";
295 }
296 }
297
Yifan Hong10fe0b52016-10-19 14:20:17 -0700298 out << "\nstatic const ::android::String16 descriptor;\n\n";
299
Steven Moreland40786312016-08-16 10:29:40 -0700300 out << "DECLARE_REGISTER_AND_GET_SERVICE(" << baseName << ")\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700301 }
302
303 if (isInterface) {
304 out.unindent();
305
Andreas Hubere3f769a2016-10-10 10:54:44 -0700306 out << "};\n\n";
307 }
308
309 err = mRootScope->emitGlobalTypeDeclarations(out);
310
311 if (err != OK) {
312 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700313 }
314
315 out << "\n";
316 enterLeaveNamespace(out, false /* enter */);
317
318 out << "\n#endif // " << guard << "\n";
319
320 return OK;
321}
322
Steven Moreland40786312016-08-16 10:29:40 -0700323status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
324 std::string ifaceName;
325 if(!AST::isInterface(&ifaceName)) {
326 // types.hal does not get an HwBinder header.
327 return OK;
328 }
329
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700330 const Interface *iface = mRootScope->getInterface();
331 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700332
333 const std::string klassName = "IHw" + baseName;
334
335 std::string path = outputPath;
336 path.append(mCoordinator->convertPackageRootToPath(mPackage));
337 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
338 path.append(klassName + ".h");
339
340 FILE* file = fopen(path.c_str(), "w");
341
342 if (file == NULL) {
343 return -errno;
344 }
345
346 Formatter out(file);
347
348 const std::string guard = makeHeaderGuard(klassName);
349
350 out << "#ifndef " << guard << "\n";
351 out << "#define " << guard << "\n\n";
352
Steven Morelandee88eed2016-10-31 17:49:00 -0700353 generateCppPackageInclude(out, mPackage, ifaceName);
Steven Moreland40786312016-08-16 10:29:40 -0700354
Steven Morelandee88eed2016-10-31 17:49:00 -0700355 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700356
357 for (const auto &item : mImportedNames) {
358 if (item.name() == "types") {
359 continue;
360 }
361
Steven Morelandee88eed2016-10-31 17:49:00 -0700362 generateCppPackageInclude(out, item, "Bn" + item.getInterfaceBaseName());
Steven Moreland40786312016-08-16 10:29:40 -0700363 }
364
365 out << "\n";
366
367 out << "#include <hidl/HidlSupport.h>\n";
Martijn Coenen93915102016-09-01 01:35:52 +0200368 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700369 out << "#include <hwbinder/IBinder.h>\n";
370 out << "#include <hwbinder/IInterface.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700371
372 out << "\n";
373
374 enterLeaveNamespace(out, true /* enter */);
375 out << "\n";
376
377 out << "struct "
378 << klassName
379 << " : public "
380 << ifaceName;
381
Steven Moreland40786312016-08-16 10:29:40 -0700382 const Interface *superType = iface->superType();
383
384 out << ", public ::android::hardware::IInterface";
385
386 out << " {\n";
387
388 out.indent();
389
390 out << "DECLARE_HWBINDER_META_INTERFACE(" << baseName << ");\n\n";
391
Steven Moreland40786312016-08-16 10:29:40 -0700392 out.unindent();
393
394 out << "};\n\n";
395
396 enterLeaveNamespace(out, false /* enter */);
397
398 out << "\n#endif // " << guard << "\n";
399
400 return OK;
401}
402
Andreas Huber881227d2016-08-02 14:20:21 -0700403status_t AST::emitTypeDeclarations(Formatter &out) const {
404 return mRootScope->emitTypeDeclarations(out);
405}
406
Steven Morelanda7a421a2016-09-07 08:35:18 -0700407status_t AST::generateStubMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700408 const Method *method) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700409 out << "inline ";
410
Yifan Hong068c5522016-10-31 14:07:25 -0700411 method->generateCppSignature(out);
Steven Morelanda7a421a2016-09-07 08:35:18 -0700412
413 const bool returnsValue = !method->results().empty();
414 const TypedVar *elidedReturn = method->canElideCallback();
415 out << " {\n";
416 out.indent();
417 out << "return mImpl->"
418 << method->name()
419 << "(";
420 bool first = true;
421 for (const auto &arg : method->args()) {
422 if (!first) {
423 out << ", ";
424 }
425 first = false;
426 out << arg->name();
427 }
428 if (returnsValue && elidedReturn == nullptr) {
429 if (!method->args().empty()) {
430 out << ", ";
431 }
432
433 out << "_hidl_cb";
434 }
435 out << ");\n";
436 out.unindent();
437 out << "}";
438
439 out << ";\n";
440
441 return OK;
442}
443
Steven Moreland69e7c702016-09-09 11:16:32 -0700444status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700445 const Method *method) const {
446 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700447
448 out << " {\n";
449 out.indent();
450
451 const bool returnsValue = !method->results().empty();
452 const TypedVar *elidedReturn = method->canElideCallback();
453
Steven Moreland67f67b42016-09-29 08:59:02 -0700454 if (returnsValue && elidedReturn == nullptr) {
455 generateCheckNonNull(out, "_hidl_cb");
456 }
457
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700458 generateCppInstrumentationCall(
459 out,
460 InstrumentationEvent::PASSTHROUGH_ENTRY,
461 method);
462
463 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700464
465 if (method->isOneway()) {
466 out << "addOnewayTask([this";
467 for (const auto &arg : method->args()) {
468 out << ", " << arg->name();
469 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700470 out << "] {\n";
471 out.indent();
472 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700473 }
474
475 out << "mImpl->"
476 << method->name()
477 << "(";
478
479 bool first = true;
480 for (const auto &arg : method->args()) {
481 if (!first) {
482 out << ", ";
483 }
484 first = false;
485 out << arg->name();
486 }
487 if (returnsValue && elidedReturn == nullptr) {
488 if (!method->args().empty()) {
489 out << ", ";
490 }
491
492 out << "_hidl_cb";
493 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700494 out << ");\n\n";
495
496 generateCppInstrumentationCall(
497 out,
498 InstrumentationEvent::PASSTHROUGH_EXIT,
499 method);
Steven Moreland69e7c702016-09-09 11:16:32 -0700500
501 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700502 out.unindent();
503 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700504 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700505
506 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700507
508 out.unindent();
509 out << "}\n";
510
511 return OK;
512}
513
Yifan Hong068c5522016-10-31 14:07:25 -0700514status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700515
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700516 const Interface *iface = mRootScope->getInterface();
517
Yifan Hong10fe0b52016-10-19 14:20:17 -0700518 const Interface *prevIterface = nullptr;
519 for (const auto &tuple : iface->allMethodsFromRoot()) {
520 const Method *method = tuple.method();
521 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700522
Yifan Hong10fe0b52016-10-19 14:20:17 -0700523 if(prevIterface != superInterface) {
524 if (prevIterface != nullptr) {
525 out << "\n";
526 }
527 out << "// Methods from "
528 << superInterface->fullName()
529 << " follow.\n";
530 prevIterface = superInterface;
531 }
Yifan Hong068c5522016-10-31 14:07:25 -0700532 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700533
Yifan Hong10fe0b52016-10-19 14:20:17 -0700534 if (err != OK) {
535 return err;
536 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700537 }
538
Yifan Hong10fe0b52016-10-19 14:20:17 -0700539 out << "\n";
540
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700541 return OK;
542}
543
Andreas Huberb82318c2016-08-02 14:45:54 -0700544status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700545 std::string ifaceName;
546 if (!AST::isInterface(&ifaceName)) {
547 // types.hal does not get a stub header.
548 return OK;
549 }
550
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700551 const Interface *iface = mRootScope->getInterface();
552 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700553 const std::string klassName = "Bn" + baseName;
Andreas Huber881227d2016-08-02 14:20:21 -0700554
Andreas Huberb82318c2016-08-02 14:45:54 -0700555 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700556 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700557 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700558 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700559 path.append(".h");
560
Andreas Huberd2943e12016-08-05 11:59:31 -0700561 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700562 FILE *file = fopen(path.c_str(), "w");
563
564 if (file == NULL) {
565 return -errno;
566 }
567
568 Formatter out(file);
569
Steven Moreland40786312016-08-16 10:29:40 -0700570 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700571
572 out << "#ifndef " << guard << "\n";
573 out << "#define " << guard << "\n\n";
574
Steven Morelandee88eed2016-10-31 17:49:00 -0700575 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
576 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700577
578 enterLeaveNamespace(out, true /* enter */);
579 out << "\n";
580
581 out << "struct "
582 << "Bn"
583 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700584 << " : public ::android::hardware::BnInterface<I"
585 << baseName << ", IHw" << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700586 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700587
588 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700589 out << "explicit Bn"
590 << baseName
591 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
592 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700593 out << "::android::status_t onTransact(\n";
594 out.indent();
595 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700596 out << "uint32_t _hidl_code,\n";
597 out << "const ::android::hardware::Parcel &_hidl_data,\n";
598 out << "::android::hardware::Parcel *_hidl_reply,\n";
599 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700600 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700601 out.unindent();
602 out.unindent();
603
Yifan Hong068c5522016-10-31 14:07:25 -0700604 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
605 return generateStubMethod(out, method);
606 });
Steven Moreland9c387612016-09-07 09:54:26 -0700607
608 if (err != OK) {
609 return err;
610 }
611
Zhuoyao Zhangde578002016-09-07 18:24:17 -0700612
Andreas Huber881227d2016-08-02 14:20:21 -0700613 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700614 out << "};\n\n";
615
616 enterLeaveNamespace(out, false /* enter */);
617
618 out << "\n#endif // " << guard << "\n";
619
620 return OK;
621}
622
Andreas Huberb82318c2016-08-02 14:45:54 -0700623status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700624 std::string ifaceName;
625 if (!AST::isInterface(&ifaceName)) {
626 // types.hal does not get a proxy header.
627 return OK;
628 }
629
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700630 const Interface *iface = mRootScope->getInterface();
631 const std::string baseName = iface->getBaseName();
Andreas Huber881227d2016-08-02 14:20:21 -0700632
Andreas Huberb82318c2016-08-02 14:45:54 -0700633 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700634 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700635 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700636 path.append("Bp");
637 path.append(baseName);
638 path.append(".h");
639
Andreas Huberd2943e12016-08-05 11:59:31 -0700640 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700641 FILE *file = fopen(path.c_str(), "w");
642
643 if (file == NULL) {
644 return -errno;
645 }
646
647 Formatter out(file);
648
649 const std::string guard = makeHeaderGuard("Bp" + baseName);
650
651 out << "#ifndef " << guard << "\n";
652 out << "#define " << guard << "\n\n";
653
654 std::vector<std::string> packageComponents;
655 getPackageAndVersionComponents(
656 &packageComponents, false /* cpp_compatible */);
657
Steven Morelandee88eed2016-10-31 17:49:00 -0700658 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
659 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700660
661 enterLeaveNamespace(out, true /* enter */);
662 out << "\n";
663
664 out << "struct "
665 << "Bp"
666 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700667 << " : public ::android::hardware::BpInterface<IHw"
668 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700669 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700670
671 out.indent();
672
673 out << "explicit Bp"
674 << baseName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700675 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700676 << "\n\n";
677
Yifan Hong10fe0b52016-10-19 14:20:17 -0700678 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700679
Yifan Hong068c5522016-10-31 14:07:25 -0700680 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
681 method->generateCppSignature(out);
682 out << " override;\n";
683 return OK;
684 });
Steven Moreland9c387612016-09-07 09:54:26 -0700685
686 if (err != OK) {
687 return err;
688 }
Andreas Huber881227d2016-08-02 14:20:21 -0700689
690 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700691 out << "};\n\n";
692
693 enterLeaveNamespace(out, false /* enter */);
694
695 out << "\n#endif // " << guard << "\n";
696
697 return OK;
698}
699
Andreas Huberb82318c2016-08-02 14:45:54 -0700700status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700701
Andreas Huberb82318c2016-08-02 14:45:54 -0700702 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700703 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700704 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700705
706 std::string ifaceName;
707 std::string baseName;
708
Yifan Hongfe95aa22016-10-19 17:26:45 -0700709 const Interface *iface = nullptr;
710 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700711 if (!AST::isInterface(&ifaceName)) {
712 baseName = "types";
713 isInterface = false;
714 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700715 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700716 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700717 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700718 }
719
720 path.append(baseName);
721
722 if (baseName != "types") {
723 path.append("All");
724 }
725
726 path.append(".cpp");
727
Andreas Huberd2943e12016-08-05 11:59:31 -0700728 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700729 FILE *file = fopen(path.c_str(), "w");
730
731 if (file == NULL) {
732 return -errno;
733 }
734
735 Formatter out(file);
736
Andreas Huber881227d2016-08-02 14:20:21 -0700737 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700738 // This is a no-op for IServiceManager itself.
739 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
740
Steven Morelandee88eed2016-10-31 17:49:00 -0700741 generateCppPackageInclude(out, mPackage, "Bp" + baseName);
742 generateCppPackageInclude(out, mPackage, "Bn" + baseName);
743 generateCppPackageInclude(out, mPackage, "Bs" + baseName);
Yifan Hongfe95aa22016-10-19 17:26:45 -0700744
745 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700746 generateCppPackageInclude(out,
747 superType->fqName(),
748 "Bp" + superType->getBaseName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700749 }
Andreas Huber881227d2016-08-02 14:20:21 -0700750 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700751 generateCppPackageInclude(out, mPackage, "types");
Andreas Huber881227d2016-08-02 14:20:21 -0700752 }
753
754 out << "\n";
755
756 enterLeaveNamespace(out, true /* enter */);
757 out << "\n";
758
759 status_t err = generateTypeSource(out, ifaceName);
760
761 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700762 const Interface *iface = mRootScope->getInterface();
Steven Moreland19d5c172016-10-20 19:20:25 -0700763 out << "constexpr ::android::hardware::hidl_version "
764 << ifaceName
765 << "::version;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700766
767 // need to be put here, generateStubSource is using this.
768 out << "const ::android::String16 I"
769 << iface->getBaseName()
770 << "::descriptor(\""
771 << iface->fqName().string()
772 << "\");\n\n";
773
Yifan Hongfe95aa22016-10-19 17:26:45 -0700774 err = generateInterfaceSource(out);
775 }
776
777 if (err == OK && isInterface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700778 err = generateProxySource(out, baseName);
779 }
780
781 if (err == OK && isInterface) {
782 err = generateStubSource(out, baseName);
783 }
784
Steven Moreland40786312016-08-16 10:29:40 -0700785 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -0700786 err = generatePassthroughSource(out);
787 }
788
789 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -0700790 const Interface *iface = mRootScope->getInterface();
791
792 out << "IMPLEMENT_REGISTER_AND_GET_SERVICE("
793 << baseName << ", "
794 << "\"" << iface->fqName().package()
Yifan Hong90ea87f2016-11-01 14:25:47 -0700795 << iface->fqName().atVersion() << "-impl.so\""
Steven Moreland9c387612016-09-07 09:54:26 -0700796 << ")\n";
Steven Moreland40786312016-08-16 10:29:40 -0700797 }
798
Andreas Huber881227d2016-08-02 14:20:21 -0700799 enterLeaveNamespace(out, false /* enter */);
800
801 return err;
802}
803
Steven Moreland67f67b42016-09-29 08:59:02 -0700804// static
805void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
806 out << "if (" << nonNull << " == nullptr) {\n";
807 out.indent();
808 out << "return ::android::hardware::Status::fromExceptionCode(\n";
809 out.indent();
810 out.indent();
811 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
812 out.unindent();
813 out.unindent();
814 out.unindent();
815 out << "}\n\n";
816}
817
Andreas Huber881227d2016-08-02 14:20:21 -0700818status_t AST::generateTypeSource(
819 Formatter &out, const std::string &ifaceName) const {
820 return mRootScope->emitTypeDefinitions(out, ifaceName);
821}
822
Andreas Hubere7ff2282016-08-16 13:50:03 -0700823void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -0700824 Formatter &out,
825 const std::vector<TypedVar *> &args,
826 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700827 if (args.empty()) {
828 return;
829 }
830
831 for (const auto &arg : args) {
832 const Type &type = arg->type();
833
834 std::string extra;
835 out << type.getCppResultType(&extra)
836 << " "
Andreas Huber5e44a292016-09-27 14:52:39 -0700837 << (forResults ? "_hidl_out_" : "")
Andreas Hubere7ff2282016-08-16 13:50:03 -0700838 << arg->name()
839 << extra
840 << ";\n";
841 }
842
843 out << "\n";
844}
845
Andreas Huber881227d2016-08-02 14:20:21 -0700846void AST::emitCppReaderWriter(
847 Formatter &out,
848 const std::string &parcelObj,
849 bool parcelObjIsPointer,
850 const TypedVar *arg,
851 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -0700852 Type::ErrorMode mode,
853 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700854 const Type &type = arg->type();
855
Andreas Huber881227d2016-08-02 14:20:21 -0700856 type.emitReaderWriter(
857 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700858 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700859 parcelObj,
860 parcelObjIsPointer,
861 isReader,
862 mode);
863}
864
Yifan Hongbf459bc2016-08-23 16:50:37 -0700865void AST::emitCppResolveReferences(
866 Formatter &out,
867 const std::string &parcelObj,
868 bool parcelObjIsPointer,
869 const TypedVar *arg,
870 bool isReader,
871 Type::ErrorMode mode,
872 bool addPrefixToName) const {
873 const Type &type = arg->type();
874 if(type.needsResolveReferences()) {
875 type.emitResolveReferences(
876 out,
877 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
878 isReader, // nameIsPointer
879 parcelObj,
880 parcelObjIsPointer,
881 isReader,
882 mode);
883 }
884}
885
Yifan Hong068c5522016-10-31 14:07:25 -0700886status_t AST::generateProxyMethodSource(Formatter &out,
887 const std::string &klassName,
888 const Method *method,
889 const Interface *superInterface) const {
890
891 method->generateCppSignature(out,
892 klassName,
893 true /* specify namespaces */);
894
895 const bool returnsValue = !method->results().empty();
896 const TypedVar *elidedReturn = method->canElideCallback();
897
898 out << "{\n";
899
900 out.indent();
901
902 if (returnsValue && elidedReturn == nullptr) {
903 generateCheckNonNull(out, "_hidl_cb");
904 }
905
906 status_t status = generateCppInstrumentationCall(
907 out,
908 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -0700909 method);
910 if (status != OK) {
911 return status;
912 }
913
914 out << "::android::hardware::Parcel _hidl_data;\n";
915 out << "::android::hardware::Parcel _hidl_reply;\n";
916 out << "::android::status_t _hidl_err;\n";
917 out << "::android::hardware::Status _hidl_status;\n\n";
918
919 declareCppReaderLocals(
920 out, method->results(), true /* forResults */);
921
922 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
923 if (!method->isHidlReserved()) {
924 out << superInterface->fqName().cppNamespace()
925 << "::IHw"
926 << superInterface->getBaseName();
927 } else {
928 out << "::android::hardware::IHidlInterfaceBase";
929 }
930 out << "::descriptor);\n";
931
932 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
933
934 // First DFS: write all buffers and resolve pointers for parent
935 for (const auto &arg : method->args()) {
936 emitCppReaderWriter(
937 out,
938 "_hidl_data",
939 false /* parcelObjIsPointer */,
940 arg,
941 false /* reader */,
942 Type::ErrorMode_Goto,
943 false /* addPrefixToName */);
944 }
945
946 // Second DFS: resolve references.
947 for (const auto &arg : method->args()) {
948 emitCppResolveReferences(
949 out,
950 "_hidl_data",
951 false /* parcelObjIsPointer */,
952 arg,
953 false /* reader */,
954 Type::ErrorMode_Goto,
955 false /* addPrefixToName */);
956 }
957
958 out << "_hidl_err = remote()->transact("
959 << method->getSerialId()
960 << " /* "
961 << method->name()
962 << " */, _hidl_data, &_hidl_reply";
963
964 if (method->isOneway()) {
965 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
966 }
967 out << ");\n";
968
969 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
970
971 if (!method->isOneway()) {
972 out << "_hidl_err = _hidl_status.readFromParcel(_hidl_reply);\n";
973 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
974 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
975
976
977 // First DFS: write all buffers and resolve pointers for parent
978 for (const auto &arg : method->results()) {
979 emitCppReaderWriter(
980 out,
981 "_hidl_reply",
982 false /* parcelObjIsPointer */,
983 arg,
984 true /* reader */,
985 Type::ErrorMode_Goto,
986 true /* addPrefixToName */);
987 }
988
989 // Second DFS: resolve references.
990 for (const auto &arg : method->results()) {
991 emitCppResolveReferences(
992 out,
993 "_hidl_reply",
994 false /* parcelObjIsPointer */,
995 arg,
996 true /* reader */,
997 Type::ErrorMode_Goto,
998 true /* addPrefixToName */);
999 }
1000
1001 if (returnsValue && elidedReturn == nullptr) {
1002 out << "_hidl_cb(";
1003
1004 bool first = true;
1005 for (const auto &arg : method->results()) {
1006 if (!first) {
1007 out << ", ";
1008 }
1009
1010 if (arg->type().resultNeedsDeref()) {
1011 out << "*";
1012 }
1013 out << "_hidl_out_" << arg->name();
1014
1015 first = false;
1016 }
1017
1018 out << ");\n\n";
1019 }
1020 status_t status = generateCppInstrumentationCall(
1021 out,
1022 InstrumentationEvent::CLIENT_API_EXIT,
Yifan Hong068c5522016-10-31 14:07:25 -07001023 method);
1024 if (status != OK) {
1025 return status;
1026 }
1027 }
1028
1029 if (elidedReturn != nullptr) {
1030 std::string extra;
1031 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1032 out << "return ::android::hardware::Return<";
1033 out << elidedReturn->type().getCppResultType(&extra)
1034 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1035 } else {
1036 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1037 out << "return ::android::hardware::Return<void>();\n\n";
1038 }
1039
1040 out.unindent();
1041 out << "_hidl_error:\n";
1042 out.indent();
1043 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1044 out << "return ::android::hardware::Return<";
1045 if (elidedReturn != nullptr) {
1046 std::string extra;
1047 out << method->results().at(0)->type().getCppResultType(&extra);
1048 } else {
1049 out << "void";
1050 }
1051 out << ">(_hidl_status);\n";
1052
1053 out.unindent();
1054 out << "}\n\n";
1055 return OK;
1056}
1057
Andreas Huber881227d2016-08-02 14:20:21 -07001058status_t AST::generateProxySource(
1059 Formatter &out, const std::string &baseName) const {
1060 const std::string klassName = "Bp" + baseName;
1061
1062 out << klassName
1063 << "::"
1064 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001065 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001066
1067 out.indent();
1068 out.indent();
1069
1070 out << ": BpInterface"
Steven Moreland40786312016-08-16 10:29:40 -07001071 << "<IHw"
Andreas Huber881227d2016-08-02 14:20:21 -07001072 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001073 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001074 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001075 << mPackage.string()
1076 << "::I"
1077 << baseName
1078 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001079
Andreas Huber881227d2016-08-02 14:20:21 -07001080 out.unindent();
1081 out.unindent();
1082 out << "}\n\n";
1083
Yifan Hong068c5522016-10-31 14:07:25 -07001084 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1085 return generateProxyMethodSource(out, klassName, method, superInterface);
1086 });
Andreas Huber881227d2016-08-02 14:20:21 -07001087
Yifan Hong068c5522016-10-31 14:07:25 -07001088 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001089}
1090
1091status_t AST::generateStubSource(
1092 Formatter &out, const std::string &baseName) const {
1093 out << "IMPLEMENT_HWBINDER_META_INTERFACE("
1094 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001095 << ", "
1096 << mPackage.cppNamespace()
Andreas Huber881227d2016-08-02 14:20:21 -07001097 << "::I"
1098 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001099 << "::descriptor);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001100
1101 const std::string klassName = "Bn" + baseName;
1102
Steven Moreland40786312016-08-16 10:29:40 -07001103 out << klassName
1104 << "::"
1105 << klassName
1106 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl)\n";
1107
1108 out.indent();
1109 out.indent();
1110
1111 out << ": BnInterface"
1112 << "<I"
1113 << baseName
1114 << ", IHw"
1115 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001116 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001117 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001118 << mPackage.string()
1119 << "::I"
1120 << baseName
1121 << "\") {\n";
Steven Moreland40786312016-08-16 10:29:40 -07001122
1123 out.unindent();
1124 out.unindent();
1125 out << "}\n\n";
1126
Andreas Huber881227d2016-08-02 14:20:21 -07001127 out << "::android::status_t " << klassName << "::onTransact(\n";
1128
1129 out.indent();
1130 out.indent();
1131
Iliyan Malchev549e2592016-08-10 08:59:12 -07001132 out << "uint32_t _hidl_code,\n"
1133 << "const ::android::hardware::Parcel &_hidl_data,\n"
1134 << "::android::hardware::Parcel *_hidl_reply,\n"
1135 << "uint32_t _hidl_flags,\n"
1136 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001137
1138 out.unindent();
1139
Iliyan Malchev549e2592016-08-10 08:59:12 -07001140 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001141 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001142 out.indent();
1143
1144 const Interface *iface = mRootScope->getInterface();
1145
Yifan Hong10fe0b52016-10-19 14:20:17 -07001146 for (const auto &tuple : iface->allMethodsFromRoot()) {
1147 const Method *method = tuple.method();
1148 const Interface *superInterface = tuple.interface();
1149 out << "case "
1150 << method->getSerialId()
1151 << " /* "
1152 << method->name()
1153 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001154
Yifan Hong10fe0b52016-10-19 14:20:17 -07001155 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001156
Yifan Hong10fe0b52016-10-19 14:20:17 -07001157 status_t err =
1158 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001159
Yifan Hong10fe0b52016-10-19 14:20:17 -07001160 if (err != OK) {
1161 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001162 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001163
1164 out.unindent();
1165 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001166 }
1167
1168 out << "default:\n{\n";
1169 out.indent();
1170
Andreas Huber8a82ff72016-08-04 10:29:39 -07001171 out << "return ::android::hardware::BnInterface<I"
Steven Moreland40786312016-08-16 10:29:40 -07001172 << baseName << ", IHw" << baseName
Andreas Huber881227d2016-08-02 14:20:21 -07001173 << ">::onTransact(\n";
1174
1175 out.indent();
1176 out.indent();
1177
Iliyan Malchev549e2592016-08-10 08:59:12 -07001178 out << "_hidl_code, _hidl_data, _hidl_reply, "
1179 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001180
1181 out.unindent();
1182 out.unindent();
1183
1184 out.unindent();
1185 out << "}\n";
1186
1187 out.unindent();
1188 out << "}\n\n";
1189
Iliyan Malchev549e2592016-08-10 08:59:12 -07001190 out << "if (_hidl_err == ::android::UNEXPECTED_NULL) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001191 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001192 out << "_hidl_err = ::android::hardware::Status::fromExceptionCode(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001193 out.indent();
1194 out.indent();
Andreas Huber8a82ff72016-08-04 10:29:39 -07001195 out << "::android::hardware::Status::EX_NULL_POINTER)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001196 out.indent();
1197 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001198 out << ".writeToParcel(_hidl_reply);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001199 out.unindent();
1200 out.unindent();
1201 out.unindent();
1202 out.unindent();
1203
1204 out.unindent();
1205 out << "}\n\n";
1206
Iliyan Malchev549e2592016-08-10 08:59:12 -07001207 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001208
1209 out.unindent();
1210 out << "}\n\n";
1211
1212 return OK;
1213}
1214
1215status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001216 Formatter &out, const Interface *iface, const Method *method) const {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001217 out << "if (!_hidl_data.enforceInterface(";
1218
1219 if (!method->isHidlReserved()) {
1220 out << iface->fqName().cppNamespace()
1221 << "::IHw"
1222 << iface->getBaseName();
1223 } else {
1224 out << "::android::hardware::IHidlInterfaceBase";
1225 }
1226
1227 out << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001228
Andreas Huber881227d2016-08-02 14:20:21 -07001229 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001230 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001231 out << "break;\n";
1232 out.unindent();
1233 out << "}\n\n";
1234
Andreas Huber5e44a292016-09-27 14:52:39 -07001235 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001236
Yifan Hongbf459bc2016-08-23 16:50:37 -07001237 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001238 for (const auto &arg : method->args()) {
1239 emitCppReaderWriter(
1240 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001241 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001242 false /* parcelObjIsPointer */,
1243 arg,
1244 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001245 Type::ErrorMode_Break,
1246 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001247 }
1248
Yifan Hongbf459bc2016-08-23 16:50:37 -07001249 // Second DFS: resolve references
1250 for (const auto &arg : method->args()) {
1251 emitCppResolveReferences(
1252 out,
1253 "_hidl_data",
1254 false /* parcelObjIsPointer */,
1255 arg,
1256 true /* reader */,
1257 Type::ErrorMode_Break,
1258 false /* addPrefixToName */);
1259 }
1260
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001261 status_t status = generateCppInstrumentationCall(
1262 out,
1263 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001264 method);
1265 if (status != OK) {
1266 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001267 }
1268
Andreas Huber881227d2016-08-02 14:20:21 -07001269 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001270 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001271
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001272 if (elidedReturn != nullptr) {
1273 std::string extra;
Andreas Huber881227d2016-08-02 14:20:21 -07001274
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001275 out << elidedReturn->type().getCppResultType(&extra) << " ";
1276 out << elidedReturn->name() << " = ";
1277 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001278
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001279 bool first = true;
1280 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001281 if (!first) {
1282 out << ", ";
1283 }
1284
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001285 if (arg->type().resultNeedsDeref()) {
1286 out << "*";
1287 }
1288
1289 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001290
1291 first = false;
1292 }
1293
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001294 out << ");\n\n";
Andreas Huber8a82ff72016-08-04 10:29:39 -07001295 out << "::android::hardware::Status::ok()"
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001296 << ".writeToParcel(_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001297
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001298 elidedReturn->type().emitReaderWriter(
1299 out,
1300 elidedReturn->name(),
1301 "_hidl_reply",
1302 true, /* parcelObjIsPointer */
1303 false, /* isReader */
1304 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001305
Yifan Hongbf459bc2016-08-23 16:50:37 -07001306 emitCppResolveReferences(
1307 out,
1308 "_hidl_reply",
1309 true /* parcelObjIsPointer */,
1310 elidedReturn,
1311 false /* reader */,
1312 Type::ErrorMode_Ignore,
1313 false /* addPrefixToName */);
1314
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001315 status_t status = generateCppInstrumentationCall(
1316 out,
1317 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001318 method);
1319 if (status != OK) {
1320 return status;
1321 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001322
Iliyan Malchev549e2592016-08-10 08:59:12 -07001323 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001324 } else {
1325 if (returnsValue) {
1326 out << "bool _hidl_callbackCalled = false;\n\n";
1327 }
Andreas Huber881227d2016-08-02 14:20:21 -07001328
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001329 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001330
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001331 bool first = true;
1332 for (const auto &arg : method->args()) {
1333 if (!first) {
1334 out << ", ";
1335 }
Andreas Huber881227d2016-08-02 14:20:21 -07001336
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001337 if (arg->type().resultNeedsDeref()) {
1338 out << "*";
1339 }
1340
1341 out << arg->name();
1342
1343 first = false;
1344 }
1345
1346 if (returnsValue) {
1347 if (!first) {
1348 out << ", ";
1349 }
1350
1351 out << "[&](";
1352
1353 first = true;
1354 for (const auto &arg : method->results()) {
1355 if (!first) {
1356 out << ", ";
1357 }
1358
1359 out << "const auto &" << arg->name();
1360
1361 first = false;
1362 }
1363
1364 out << ") {\n";
1365 out.indent();
1366 out << "_hidl_callbackCalled = true;\n\n";
1367
1368 out << "::android::hardware::Status::ok()"
1369 << ".writeToParcel(_hidl_reply);\n\n";
1370
Yifan Hongbf459bc2016-08-23 16:50:37 -07001371 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001372 for (const auto &arg : method->results()) {
1373 emitCppReaderWriter(
1374 out,
1375 "_hidl_reply",
1376 true /* parcelObjIsPointer */,
1377 arg,
1378 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001379 Type::ErrorMode_Ignore,
1380 false /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001381 }
1382
Yifan Hongbf459bc2016-08-23 16:50:37 -07001383 // Second DFS: resolve references
1384 for (const auto &arg : method->results()) {
1385 emitCppResolveReferences(
1386 out,
1387 "_hidl_reply",
1388 true /* parcelObjIsPointer */,
1389 arg,
1390 false /* reader */,
1391 Type::ErrorMode_Ignore,
1392 false /* addPrefixToName */);
1393 }
1394
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001395 status_t status = generateCppInstrumentationCall(
1396 out,
1397 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001398 method);
1399 if (status != OK) {
1400 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001401 }
1402
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001403 out << "_hidl_cb(*_hidl_reply);\n";
1404
1405 out.unindent();
1406 out << "}\n";
1407 }
1408
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001409 out << ");\n\n";
1410
1411 // What to do if the stub implementation has a synchronous callback
1412 // which does not get invoked? This is not a transport error but a
1413 // service error of sorts. For now, return OK to the caller, as this is
1414 // not a transport error.
1415 //
1416 // TODO(b/31365311) Figure out how to deal with this later.
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001417
1418 if (returnsValue) {
1419 out << "if (!_hidl_callbackCalled) {\n";
1420 out.indent();
1421 }
1422
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001423 out << "::android::hardware::Status::ok()"
1424 << ".writeToParcel(_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001425
1426 if (returnsValue) {
1427 out.unindent();
1428 out << "}\n\n";
1429 }
Andreas Huber881227d2016-08-02 14:20:21 -07001430 }
1431
1432 out << "break;\n";
1433
1434 return OK;
1435}
1436
Steven Moreland69e7c702016-09-09 11:16:32 -07001437status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1438 std::string ifaceName;
1439 if (!AST::isInterface(&ifaceName)) {
1440 // types.hal does not get a stub header.
1441 return OK;
1442 }
1443
1444 const Interface *iface = mRootScope->getInterface();
1445
1446 const std::string baseName = iface->getBaseName();
1447 const std::string klassName = "Bs" + baseName;
1448
1449 bool supportOneway = iface->hasOnewayMethods();
1450
1451 std::string path = outputPath;
1452 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1453 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1454 path.append(klassName);
1455 path.append(".h");
1456
1457 CHECK(Coordinator::MakeParentHierarchy(path));
1458 FILE *file = fopen(path.c_str(), "w");
1459
1460 if (file == NULL) {
1461 return -errno;
1462 }
1463
1464 Formatter out(file);
1465
1466 const std::string guard = makeHeaderGuard(klassName);
1467
1468 out << "#ifndef " << guard << "\n";
1469 out << "#define " << guard << "\n\n";
1470
1471 std::vector<std::string> packageComponents;
1472 getPackageAndVersionComponents(
1473 &packageComponents, false /* cpp_compatible */);
1474
1475 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001476
1477 generateCppPackageInclude(out, mPackage, ifaceName);
1478 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001479
1480 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001481 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001482 }
1483
1484 enterLeaveNamespace(out, true /* enter */);
1485 out << "\n";
1486
1487 out << "struct "
1488 << klassName
1489 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001490 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001491
1492 out.indent();
1493 out << "explicit "
1494 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001495 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001496 << ifaceName
1497 << "> impl);\n";
1498
Yifan Hong068c5522016-10-31 14:07:25 -07001499 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1500 return generatePassthroughMethod(out, method);
1501 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001502
1503 if (err != OK) {
1504 return err;
1505 }
1506
1507 out.unindent();
1508 out << "private:\n";
1509 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001510 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001511
1512 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001513 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001514
1515 out << "\n";
1516
1517 out << "::android::hardware::Return<void> addOnewayTask("
1518 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001519 }
1520
1521 out.unindent();
1522
1523 out << "};\n\n";
1524
1525 enterLeaveNamespace(out, false /* enter */);
1526
1527 out << "\n#endif // " << guard << "\n";
1528
1529 return OK;
1530}
1531
Yifan Hongfe95aa22016-10-19 17:26:45 -07001532status_t AST::generateInterfaceSource(Formatter &out) const {
1533 const Interface *iface = mRootScope->getInterface();
1534
Yifan Hong2d7126b2016-10-20 15:12:57 -07001535
1536 // generate toBinder functions
1537 out << "::android::sp<::android::hardware::IBinder> I"
1538 << iface->getBaseName()
1539 << "::toBinder() {\n";
1540 out.indent();
1541 out << "if (isRemote()) {\n";
1542 out.indent();
1543 out << "return ::android::hardware::IInterface::asBinder("
1544 << "static_cast<IHw"
1545 << iface->getBaseName()
1546 << " *>(this));\n";
1547 out.unindent();
1548 out << "} else {\n";
1549 out.indent();
1550 out << "return new Bn" << iface->getBaseName() << "(this);\n";
1551 out.unindent();
1552 out << "}\n";
1553 out.unindent();
1554 out << "}\n\n";
1555
1556 // generate castFrom functions
Yifan Hongfe95aa22016-10-19 17:26:45 -07001557 if (!iface->isRootType()) {
1558 std::string childTypeExtra;
1559 std::string childTypeResult = iface->getCppResultType(&childTypeExtra);
1560 childTypeResult += childTypeExtra;
1561
1562 for (const Interface *superType : iface->superTypeChain()) {
1563 std::string superTypeExtra;
1564 out << "// static \n"
1565 << childTypeResult
1566 << " I"
1567 << iface->getBaseName()
1568 << "::castFrom("
1569 << superType->getCppArgumentType(&superTypeExtra)
1570 << " parent"
1571 << superTypeExtra
1572 << ")";
1573 out << " {\n";
1574 out.indent();
1575 out << "return ::android::hardware::castInterface<";
1576 out << "I" << iface->getBaseName() << ", "
1577 << superType->fqName().cppName() << ", "
1578 << "Bp" << iface->getBaseName()
1579 << ">(\n";
1580 out.indent();
1581 out.indent();
1582 out << "parent, \""
1583 << iface->fqName().string()
1584 << "\");\n";
1585 out.unindent();
1586 out.unindent();
1587 out.unindent();
1588 out << "}\n\n";
1589 }
1590 }
1591
1592 return OK;
1593}
1594
Steven Moreland69e7c702016-09-09 11:16:32 -07001595status_t AST::generatePassthroughSource(Formatter &out) const {
1596 const Interface *iface = mRootScope->getInterface();
1597
1598 const std::string baseName = iface->getBaseName();
1599 const std::string klassName = "Bs" + baseName;
1600
1601 out << klassName
1602 << "::"
1603 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001604 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001605 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001606 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001607 << iface->fqName().string()
1608 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001609 if (iface->hasOnewayMethods()) {
1610 out << "\n";
1611 out.indentBlock([&] {
1612 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1613 });
1614 }
1615 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001616
1617 if (iface->hasOnewayMethods()) {
1618 out << "::android::hardware::Return<void> "
1619 << klassName
1620 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1621 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001622 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001623 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001624 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1625 out.indent();
1626 out.indent();
1627 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1628 out.unindent();
1629 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001630 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001631 out << "}\n";
1632
Steven Morelandd366c262016-10-11 15:29:10 -07001633 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001634
1635 out.unindent();
1636 out << "}\n\n";
1637
1638
1639 }
1640
1641 return OK;
1642}
1643
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001644status_t AST::generateCppInstrumentationCall(
1645 Formatter &out,
1646 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001647 const Method *method) const {
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001648 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1649 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001650 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001651 std::string event_str = "";
1652 switch (event) {
1653 case SERVER_API_ENTRY:
1654 {
1655 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1656 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001657 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001658 << (arg->type().resultNeedsDeref() ? "" : "&")
1659 << arg->name()
1660 << ");\n";
1661 }
1662 break;
1663 }
1664 case SERVER_API_EXIT:
1665 {
1666 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001667 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001668 out << "_hidl_args.push_back((void *)&"
Steven Moreland031ccf12016-10-31 15:54:38 -07001669 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001670 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001671 }
1672 break;
1673 }
1674 case CLIENT_API_ENTRY:
1675 {
1676 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1677 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001678 out << "_hidl_args.push_back((void *)&"
1679 << arg->name()
1680 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001681 }
1682 break;
1683 }
1684 case CLIENT_API_EXIT:
1685 {
1686 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1687 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001688 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001689 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001690 << "_hidl_out_"
1691 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001692 << ");\n";
1693 }
1694 break;
1695 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001696 case PASSTHROUGH_ENTRY:
1697 {
1698 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1699 for (const auto &arg : method->args()) {
1700 out << "_hidl_args.push_back((void *)&"
1701 << arg->name()
1702 << ");\n";
1703 }
1704 break;
1705 }
1706 case PASSTHROUGH_EXIT:
1707 {
1708 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
1709 // TODO(b/32576620): passthrough return values
1710 break;
1711 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001712 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001713 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001714 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001715 return UNKNOWN_ERROR;
1716 }
1717 }
1718
Steven Moreland031ccf12016-10-31 15:54:38 -07001719 const Interface *iface = mRootScope->getInterface();
1720
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001721 out << "for (auto callback: mInstrumentationCallbacks) {\n";
1722 out.indent();
1723 out << "callback("
1724 << event_str
1725 << ", \""
1726 << mPackage.package()
1727 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07001728 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001729 << "\", \""
1730 << iface->localName()
1731 << "\", \""
1732 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001733 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001734 out.unindent();
1735 out << "}\n";
1736 out.unindent();
1737 out << "}\n\n";
1738
1739 return OK;
1740}
1741
Andreas Huber881227d2016-08-02 14:20:21 -07001742} // namespace android
1743