blob: 36dcad808162e14775737c20d7a3ee1089783bd8 [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Huber881227d2016-08-02 14:20:21 -070017#include "AST.h"
18
19#include "Coordinator.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070020#include "EnumType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070021#include "Interface.h"
22#include "Method.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070023#include "ScalarType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070024#include "Scope.h"
25
Andreas Huberdca261f2016-08-04 13:47:51 -070026#include <algorithm>
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070027#include <hidl-util/Formatter.h>
Steven Moreland5708edf2016-11-04 15:33:31 +000028#include <hidl-util/StringHelper.h>
Andreas Huber881227d2016-08-02 14:20:21 -070029#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070030#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070031#include <vector>
32
33namespace android {
34
Andreas Huberb82318c2016-08-02 14:45:54 -070035status_t AST::generateCpp(const std::string &outputPath) const {
36 status_t err = generateInterfaceHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070037
38 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070039 err = generateStubHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070040 }
41
42 if (err == OK) {
Steven Moreland40786312016-08-16 10:29:40 -070043 err = generateHwBinderHeader(outputPath);
44 }
45
46 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070047 err = generateProxyHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070048 }
49
50 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070051 err = generateAllSource(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070052 }
53
Steven Moreland69e7c702016-09-09 11:16:32 -070054 if (err == OK) {
55 generatePassthroughHeader(outputPath);
56 }
57
Andreas Huber881227d2016-08-02 14:20:21 -070058 return err;
59}
60
Andreas Huber737080b2016-08-02 15:38:04 -070061void AST::getPackageComponents(
62 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070063 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070064}
65
66void AST::getPackageAndVersionComponents(
67 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070068 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070069}
70
Steven Moreland5708edf2016-11-04 15:33:31 +000071std::string AST::makeHeaderGuard(const std::string &baseName,
72 bool indicateGenerated) const {
73 std::string guard;
Andreas Huber881227d2016-08-02 14:20:21 -070074
Steven Moreland5708edf2016-11-04 15:33:31 +000075 if (indicateGenerated) {
76 guard += "HIDL_GENERATED_";
77 }
78
79 guard += StringHelper::Uppercase(mPackage.tokenName());
Andreas Huber881227d2016-08-02 14:20:21 -070080 guard += "_";
Steven Moreland5708edf2016-11-04 15:33:31 +000081 guard += StringHelper::Uppercase(baseName);
82 guard += "_H";
Andreas Huber881227d2016-08-02 14:20:21 -070083
84 return guard;
85}
86
Steven Morelandee88eed2016-10-31 17:49:00 -070087// static
88void AST::generateCppPackageInclude(
89 Formatter &out,
90 const FQName &package,
91 const std::string &klass) {
92
93 out << "#include <";
94
95 std::vector<std::string> components;
96 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
97
98 for (const auto &component : components) {
99 out << component << "/";
100 }
101
102 out << klass
103 << ".h>\n";
104}
105
Andreas Huber881227d2016-08-02 14:20:21 -0700106void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
107 std::vector<std::string> packageComponents;
108 getPackageAndVersionComponents(
109 &packageComponents, true /* cpp_compatible */);
110
111 if (enter) {
112 for (const auto &component : packageComponents) {
113 out << "namespace " << component << " {\n";
114 }
Andreas Huber0e00de42016-08-03 09:56:02 -0700115
Andreas Huber2831d512016-08-15 09:33:47 -0700116 out.setNamespace(mPackage.cppNamespace() + "::");
Andreas Huber881227d2016-08-02 14:20:21 -0700117 } else {
Andreas Huber0e00de42016-08-03 09:56:02 -0700118 out.setNamespace(std::string());
119
Andreas Huber881227d2016-08-02 14:20:21 -0700120 for (auto it = packageComponents.rbegin();
121 it != packageComponents.rend();
122 ++it) {
123 out << "} // namespace " << *it << "\n";
124 }
125 }
126}
127
Andreas Huberb82318c2016-08-02 14:45:54 -0700128status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700129
Andreas Huberb82318c2016-08-02 14:45:54 -0700130 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700131 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700132 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700133
134 std::string ifaceName;
135 bool isInterface = true;
136 if (!AST::isInterface(&ifaceName)) {
137 ifaceName = "types";
138 isInterface = false;
139 }
140 path.append(ifaceName);
141 path.append(".h");
142
Andreas Huberd2943e12016-08-05 11:59:31 -0700143 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700144 FILE *file = fopen(path.c_str(), "w");
145
146 if (file == NULL) {
147 return -errno;
148 }
149
150 Formatter out(file);
151
152 const std::string guard = makeHeaderGuard(ifaceName);
153
154 out << "#ifndef " << guard << "\n";
155 out << "#define " << guard << "\n\n";
156
Andreas Huber737080b2016-08-02 15:38:04 -0700157 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700158 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700159 }
160
161 if (!mImportedNames.empty()) {
162 out << "\n";
163 }
164
Martijn Coenen7473fab2016-08-19 14:05:40 +0200165 out << "#include <hidl/HidlSupport.h>\n";
Steven Moreland19d5c172016-10-20 19:20:25 -0700166 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700167 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700168
169 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200170 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700171 }
172
173 out << "#include <utils/NativeHandle.h>\n\n";
174
175 enterLeaveNamespace(out, true /* enter */);
176 out << "\n";
177
178 if (isInterface) {
179 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700180 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700181
182 const Interface *iface = mRootScope->getInterface();
183 const Interface *superType = iface->superType();
184
Steven Moreland40786312016-08-16 10:29:40 -0700185 if (superType == NULL) {
Yifan Hong5bd9aff2016-11-08 18:52:55 -0800186 out << " : virtual public ::android::hardware::IBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700187 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000188 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700189 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700190 }
191
192 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700193
194 out.indent();
195
Andreas Huber881227d2016-08-02 14:20:21 -0700196 }
197
198 status_t err = emitTypeDeclarations(out);
199
200 if (err != OK) {
201 return err;
202 }
203
204 if (isInterface) {
205 const Interface *iface = mRootScope->getInterface();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700206 const Interface *superType = iface->superType();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700207 const std::string baseName = iface->getBaseName();
Steven Moreland19d5c172016-10-20 19:20:25 -0700208 out << "constexpr static ::android::hardware::hidl_version version = {"
Martijn Coenena21f1492016-09-08 15:55:14 +0200209 << mPackage.getPackageMajorVersion() << ","
210 << mPackage.getPackageMinorVersion() << "};\n";
Steven Moreland19d5c172016-10-20 19:20:25 -0700211 out << "virtual const ::android::hardware::hidl_version&"
212 << "getInterfaceVersion() const {\n";
Martijn Coenena21f1492016-09-08 15:55:14 +0200213 out.indent();
214 out << "return version;\n";
215 out.unindent();
216 out << "}\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700217 out << "virtual bool isRemote() const override { return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800218
Andreas Huber881227d2016-08-02 14:20:21 -0700219 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700220 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700221
Andreas Huber881227d2016-08-02 14:20:21 -0700222 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800223 const TypedVar *elidedReturn = method->canElideCallback();
224
225 if (elidedReturn == nullptr && returnsValue) {
226 out << "using "
227 << method->name()
228 << "_cb = std::function<void("
229 << Method::GetArgSignature(method->results(),
230 true /* specify namespaces */)
231 << ")>;\n";
232 }
Andreas Huber881227d2016-08-02 14:20:21 -0700233
Andreas Huber3599d922016-08-09 10:42:57 -0700234 method->dumpAnnotations(out);
235
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700236 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700237 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700238 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700239 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700240 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700241 }
242
243 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700244 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700245 << Method::GetArgSignature(method->args(),
246 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700247
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700248 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700249 if (!method->args().empty()) {
250 out << ", ";
251 }
252
Steven Moreland67f67b42016-09-29 08:59:02 -0700253 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700254 }
255
Yifan Hong10fe0b52016-10-19 14:20:17 -0700256 out << ")";
257 if (method->isHidlReserved()) {
258 out << " override";
259 out << " {\n";
260 out.indent();
261 method->cppImpl(out);
262 out.unindent();
263 out << "\n}\n";
264 } else {
265 out << " = 0;\n";
266 }
Andreas Huber881227d2016-08-02 14:20:21 -0700267 }
Steven Moreland40786312016-08-16 10:29:40 -0700268
Yifan Hongfe95aa22016-10-19 17:26:45 -0700269 if (!iface->isRootType()) {
270 out << "// cast static functions\n";
Yifan Hong3b320f82016-11-01 15:15:54 -0700271 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700272
273 for (const Interface *superType : iface->superTypeChain()) {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700274 out << "static "
275 << childTypeResult
276 << " castFrom("
Yifan Hong3b320f82016-11-01 15:15:54 -0700277 << superType->getCppArgumentType()
Yifan Hongfe95aa22016-10-19 17:26:45 -0700278 << " parent"
Yifan Hongfe95aa22016-10-19 17:26:45 -0700279 << ");\n";
280 }
281 }
282
Yifan Hong10fe0b52016-10-19 14:20:17 -0700283 out << "\nstatic const ::android::String16 descriptor;\n\n";
284
Yifan Hong158655a2016-11-08 12:34:07 -0800285 out << "DECLARE_REGISTER_AND_GET_SERVICE(" << baseName << ")\n\n";
286
287 out << "private: static int hidlStaticBlock;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700288 }
289
290 if (isInterface) {
291 out.unindent();
292
Andreas Hubere3f769a2016-10-10 10:54:44 -0700293 out << "};\n\n";
294 }
295
296 err = mRootScope->emitGlobalTypeDeclarations(out);
297
298 if (err != OK) {
299 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700300 }
301
302 out << "\n";
303 enterLeaveNamespace(out, false /* enter */);
304
305 out << "\n#endif // " << guard << "\n";
306
307 return OK;
308}
309
Steven Moreland40786312016-08-16 10:29:40 -0700310status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
311 std::string ifaceName;
312 if(!AST::isInterface(&ifaceName)) {
313 // types.hal does not get an HwBinder header.
314 return OK;
315 }
316
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700317 const Interface *iface = mRootScope->getInterface();
318 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700319
320 const std::string klassName = "IHw" + baseName;
321
322 std::string path = outputPath;
323 path.append(mCoordinator->convertPackageRootToPath(mPackage));
324 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
325 path.append(klassName + ".h");
326
327 FILE* file = fopen(path.c_str(), "w");
328
329 if (file == NULL) {
330 return -errno;
331 }
332
333 Formatter out(file);
334
335 const std::string guard = makeHeaderGuard(klassName);
336
337 out << "#ifndef " << guard << "\n";
338 out << "#define " << guard << "\n\n";
339
Steven Morelandee88eed2016-10-31 17:49:00 -0700340 generateCppPackageInclude(out, mPackage, ifaceName);
Steven Moreland40786312016-08-16 10:29:40 -0700341
Steven Morelandee88eed2016-10-31 17:49:00 -0700342 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700343
344 for (const auto &item : mImportedNames) {
345 if (item.name() == "types") {
346 continue;
347 }
348
Steven Morelandee88eed2016-10-31 17:49:00 -0700349 generateCppPackageInclude(out, item, "Bn" + item.getInterfaceBaseName());
Steven Moreland40786312016-08-16 10:29:40 -0700350 }
351
352 out << "\n";
353
354 out << "#include <hidl/HidlSupport.h>\n";
Martijn Coenen93915102016-09-01 01:35:52 +0200355 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700356 out << "#include <hwbinder/IBinder.h>\n";
357 out << "#include <hwbinder/IInterface.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700358
359 out << "\n";
360
361 enterLeaveNamespace(out, true /* enter */);
362 out << "\n";
363
364 out << "struct "
365 << klassName
366 << " : public "
367 << ifaceName;
368
Steven Moreland40786312016-08-16 10:29:40 -0700369 const Interface *superType = iface->superType();
370
371 out << ", public ::android::hardware::IInterface";
372
373 out << " {\n";
374
375 out.indent();
376
377 out << "DECLARE_HWBINDER_META_INTERFACE(" << baseName << ");\n\n";
378
Steven Moreland40786312016-08-16 10:29:40 -0700379 out.unindent();
380
381 out << "};\n\n";
382
383 enterLeaveNamespace(out, false /* enter */);
384
385 out << "\n#endif // " << guard << "\n";
386
387 return OK;
388}
389
Andreas Huber881227d2016-08-02 14:20:21 -0700390status_t AST::emitTypeDeclarations(Formatter &out) const {
391 return mRootScope->emitTypeDeclarations(out);
392}
393
Steven Morelanda7a421a2016-09-07 08:35:18 -0700394status_t AST::generateStubMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700395 const Method *method) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700396 out << "inline ";
397
Yifan Hong068c5522016-10-31 14:07:25 -0700398 method->generateCppSignature(out);
Steven Morelanda7a421a2016-09-07 08:35:18 -0700399
400 const bool returnsValue = !method->results().empty();
401 const TypedVar *elidedReturn = method->canElideCallback();
402 out << " {\n";
403 out.indent();
404 out << "return mImpl->"
405 << method->name()
406 << "(";
407 bool first = true;
408 for (const auto &arg : method->args()) {
409 if (!first) {
410 out << ", ";
411 }
412 first = false;
413 out << arg->name();
414 }
415 if (returnsValue && elidedReturn == nullptr) {
416 if (!method->args().empty()) {
417 out << ", ";
418 }
419
420 out << "_hidl_cb";
421 }
422 out << ");\n";
423 out.unindent();
424 out << "}";
425
426 out << ";\n";
427
428 return OK;
429}
430
Steven Moreland69e7c702016-09-09 11:16:32 -0700431status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700432 const Method *method) const {
433 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700434
435 out << " {\n";
436 out.indent();
437
438 const bool returnsValue = !method->results().empty();
439 const TypedVar *elidedReturn = method->canElideCallback();
440
Steven Moreland67f67b42016-09-29 08:59:02 -0700441 if (returnsValue && elidedReturn == nullptr) {
442 generateCheckNonNull(out, "_hidl_cb");
443 }
444
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700445 generateCppInstrumentationCall(
446 out,
447 InstrumentationEvent::PASSTHROUGH_ENTRY,
448 method);
449
450 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700451
452 if (method->isOneway()) {
453 out << "addOnewayTask([this";
454 for (const auto &arg : method->args()) {
455 out << ", " << arg->name();
456 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700457 out << "] {\n";
458 out.indent();
459 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700460 }
461
462 out << "mImpl->"
463 << method->name()
464 << "(";
465
466 bool first = true;
467 for (const auto &arg : method->args()) {
468 if (!first) {
469 out << ", ";
470 }
471 first = false;
472 out << arg->name();
473 }
474 if (returnsValue && elidedReturn == nullptr) {
475 if (!method->args().empty()) {
476 out << ", ";
477 }
478
479 out << "_hidl_cb";
480 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700481 out << ");\n\n";
482
483 generateCppInstrumentationCall(
484 out,
485 InstrumentationEvent::PASSTHROUGH_EXIT,
486 method);
Steven Moreland69e7c702016-09-09 11:16:32 -0700487
488 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700489 out.unindent();
490 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700491 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700492
493 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700494
495 out.unindent();
496 out << "}\n";
497
498 return OK;
499}
500
Yifan Hong068c5522016-10-31 14:07:25 -0700501status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700502
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700503 const Interface *iface = mRootScope->getInterface();
504
Yifan Hong10fe0b52016-10-19 14:20:17 -0700505 const Interface *prevIterface = nullptr;
506 for (const auto &tuple : iface->allMethodsFromRoot()) {
507 const Method *method = tuple.method();
508 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700509
Yifan Hong10fe0b52016-10-19 14:20:17 -0700510 if(prevIterface != superInterface) {
511 if (prevIterface != nullptr) {
512 out << "\n";
513 }
514 out << "// Methods from "
515 << superInterface->fullName()
516 << " follow.\n";
517 prevIterface = superInterface;
518 }
Yifan Hong068c5522016-10-31 14:07:25 -0700519 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700520
Yifan Hong10fe0b52016-10-19 14:20:17 -0700521 if (err != OK) {
522 return err;
523 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700524 }
525
Yifan Hong10fe0b52016-10-19 14:20:17 -0700526 out << "\n";
527
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700528 return OK;
529}
530
Andreas Huberb82318c2016-08-02 14:45:54 -0700531status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700532 std::string ifaceName;
533 if (!AST::isInterface(&ifaceName)) {
534 // types.hal does not get a stub header.
535 return OK;
536 }
537
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700538 const Interface *iface = mRootScope->getInterface();
539 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700540 const std::string klassName = "Bn" + baseName;
Andreas Huber881227d2016-08-02 14:20:21 -0700541
Andreas Huberb82318c2016-08-02 14:45:54 -0700542 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700543 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700544 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700545 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700546 path.append(".h");
547
Andreas Huberd2943e12016-08-05 11:59:31 -0700548 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700549 FILE *file = fopen(path.c_str(), "w");
550
551 if (file == NULL) {
552 return -errno;
553 }
554
555 Formatter out(file);
556
Steven Moreland40786312016-08-16 10:29:40 -0700557 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700558
559 out << "#ifndef " << guard << "\n";
560 out << "#define " << guard << "\n\n";
561
Steven Morelandee88eed2016-10-31 17:49:00 -0700562 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
563 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700564
565 enterLeaveNamespace(out, true /* enter */);
566 out << "\n";
567
568 out << "struct "
569 << "Bn"
570 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700571 << " : public ::android::hardware::BnInterface<I"
572 << baseName << ", IHw" << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700573 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700574
575 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700576 out << "explicit Bn"
577 << baseName
578 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
579 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700580 out << "::android::status_t onTransact(\n";
581 out.indent();
582 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700583 out << "uint32_t _hidl_code,\n";
584 out << "const ::android::hardware::Parcel &_hidl_data,\n";
585 out << "::android::hardware::Parcel *_hidl_reply,\n";
586 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700587 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700588 out.unindent();
589 out.unindent();
590
Yifan Hong068c5522016-10-31 14:07:25 -0700591 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
592 return generateStubMethod(out, method);
593 });
Steven Moreland9c387612016-09-07 09:54:26 -0700594
595 if (err != OK) {
596 return err;
597 }
598
Zhuoyao Zhangde578002016-09-07 18:24:17 -0700599
Andreas Huber881227d2016-08-02 14:20:21 -0700600 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700601 out << "};\n\n";
602
603 enterLeaveNamespace(out, false /* enter */);
604
605 out << "\n#endif // " << guard << "\n";
606
607 return OK;
608}
609
Andreas Huberb82318c2016-08-02 14:45:54 -0700610status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700611 std::string ifaceName;
612 if (!AST::isInterface(&ifaceName)) {
613 // types.hal does not get a proxy header.
614 return OK;
615 }
616
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700617 const Interface *iface = mRootScope->getInterface();
618 const std::string baseName = iface->getBaseName();
Andreas Huber881227d2016-08-02 14:20:21 -0700619
Andreas Huberb82318c2016-08-02 14:45:54 -0700620 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700621 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700622 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700623 path.append("Bp");
624 path.append(baseName);
625 path.append(".h");
626
Andreas Huberd2943e12016-08-05 11:59:31 -0700627 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700628 FILE *file = fopen(path.c_str(), "w");
629
630 if (file == NULL) {
631 return -errno;
632 }
633
634 Formatter out(file);
635
636 const std::string guard = makeHeaderGuard("Bp" + baseName);
637
638 out << "#ifndef " << guard << "\n";
639 out << "#define " << guard << "\n\n";
640
641 std::vector<std::string> packageComponents;
642 getPackageAndVersionComponents(
643 &packageComponents, false /* cpp_compatible */);
644
Steven Morelandee88eed2016-10-31 17:49:00 -0700645 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
646 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700647
648 enterLeaveNamespace(out, true /* enter */);
649 out << "\n";
650
651 out << "struct "
652 << "Bp"
653 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700654 << " : public ::android::hardware::BpInterface<IHw"
655 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700656 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700657
658 out.indent();
659
660 out << "explicit Bp"
661 << baseName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700662 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700663 << "\n\n";
664
Yifan Hong10fe0b52016-10-19 14:20:17 -0700665 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700666
Yifan Hong068c5522016-10-31 14:07:25 -0700667 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
668 method->generateCppSignature(out);
669 out << " override;\n";
670 return OK;
671 });
Steven Moreland9c387612016-09-07 09:54:26 -0700672
673 if (err != OK) {
674 return err;
675 }
Andreas Huber881227d2016-08-02 14:20:21 -0700676
677 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700678 out << "};\n\n";
679
680 enterLeaveNamespace(out, false /* enter */);
681
682 out << "\n#endif // " << guard << "\n";
683
684 return OK;
685}
686
Andreas Huberb82318c2016-08-02 14:45:54 -0700687status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700688
Andreas Huberb82318c2016-08-02 14:45:54 -0700689 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700690 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700691 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700692
693 std::string ifaceName;
694 std::string baseName;
695
Yifan Hongfe95aa22016-10-19 17:26:45 -0700696 const Interface *iface = nullptr;
697 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700698 if (!AST::isInterface(&ifaceName)) {
699 baseName = "types";
700 isInterface = false;
701 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700702 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700703 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700704 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700705 }
706
707 path.append(baseName);
708
709 if (baseName != "types") {
710 path.append("All");
711 }
712
713 path.append(".cpp");
714
Andreas Huberd2943e12016-08-05 11:59:31 -0700715 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700716 FILE *file = fopen(path.c_str(), "w");
717
718 if (file == NULL) {
719 return -errno;
720 }
721
722 Formatter out(file);
723
Andreas Huber881227d2016-08-02 14:20:21 -0700724 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700725 // This is a no-op for IServiceManager itself.
726 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
727
Steven Morelandee88eed2016-10-31 17:49:00 -0700728 generateCppPackageInclude(out, mPackage, "Bp" + baseName);
729 generateCppPackageInclude(out, mPackage, "Bn" + baseName);
730 generateCppPackageInclude(out, mPackage, "Bs" + baseName);
Yifan Hongfe95aa22016-10-19 17:26:45 -0700731
732 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700733 generateCppPackageInclude(out,
734 superType->fqName(),
735 "Bp" + superType->getBaseName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700736 }
Andreas Huber881227d2016-08-02 14:20:21 -0700737 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700738 generateCppPackageInclude(out, mPackage, "types");
Andreas Huber881227d2016-08-02 14:20:21 -0700739 }
740
741 out << "\n";
742
743 enterLeaveNamespace(out, true /* enter */);
744 out << "\n";
745
746 status_t err = generateTypeSource(out, ifaceName);
747
748 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700749 const Interface *iface = mRootScope->getInterface();
Steven Moreland19d5c172016-10-20 19:20:25 -0700750 out << "constexpr ::android::hardware::hidl_version "
751 << ifaceName
752 << "::version;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700753
754 // need to be put here, generateStubSource is using this.
755 out << "const ::android::String16 I"
756 << iface->getBaseName()
757 << "::descriptor(\""
758 << iface->fqName().string()
759 << "\");\n\n";
760
Yifan Hong158655a2016-11-08 12:34:07 -0800761 out << "int I"
762 << iface->getBaseName()
763 << "::hidlStaticBlock = []() -> int {\n";
764 out.indentBlock([&] {
765 out << "::android::hardware::gBnConstructorMap[::android::String16::std_string(I"
766 << iface->getBaseName()
767 << "::descriptor)]\n";
768 out.indentBlock(2, [&] {
769 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
770 out.indentBlock([&] {
771 out << "return new Bn"
772 << iface->getBaseName()
773 << "(reinterpret_cast<I"
774 << iface->getBaseName()
775 << " *>(iIntf));\n";
776 });
777 out << "};\n";
778 });
779 out << "return 1;\n";
780 });
781 out << "}();\n\n";
782
Yifan Hongfe95aa22016-10-19 17:26:45 -0700783 err = generateInterfaceSource(out);
784 }
785
786 if (err == OK && isInterface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700787 err = generateProxySource(out, baseName);
788 }
789
790 if (err == OK && isInterface) {
791 err = generateStubSource(out, baseName);
792 }
793
Steven Moreland40786312016-08-16 10:29:40 -0700794 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -0700795 err = generatePassthroughSource(out);
796 }
797
798 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -0700799 const Interface *iface = mRootScope->getInterface();
800
801 out << "IMPLEMENT_REGISTER_AND_GET_SERVICE("
802 << baseName << ", "
803 << "\"" << iface->fqName().package()
Steven Moreland7e367bf2016-11-04 11:31:41 -0700804 << iface->fqName().atVersion()
805 << "\")\n";
Steven Moreland40786312016-08-16 10:29:40 -0700806 }
807
Andreas Huber881227d2016-08-02 14:20:21 -0700808 enterLeaveNamespace(out, false /* enter */);
809
810 return err;
811}
812
Steven Moreland67f67b42016-09-29 08:59:02 -0700813// static
814void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
815 out << "if (" << nonNull << " == nullptr) {\n";
816 out.indent();
817 out << "return ::android::hardware::Status::fromExceptionCode(\n";
818 out.indent();
819 out.indent();
820 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
821 out.unindent();
822 out.unindent();
823 out.unindent();
824 out << "}\n\n";
825}
826
Andreas Huber881227d2016-08-02 14:20:21 -0700827status_t AST::generateTypeSource(
828 Formatter &out, const std::string &ifaceName) const {
829 return mRootScope->emitTypeDefinitions(out, ifaceName);
830}
831
Andreas Hubere7ff2282016-08-16 13:50:03 -0700832void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -0700833 Formatter &out,
834 const std::vector<TypedVar *> &args,
835 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700836 if (args.empty()) {
837 return;
838 }
839
840 for (const auto &arg : args) {
841 const Type &type = arg->type();
842
Yifan Hong3b320f82016-11-01 15:15:54 -0700843 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700844 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700845 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700846 << ";\n";
847 }
848
849 out << "\n";
850}
851
Andreas Huber881227d2016-08-02 14:20:21 -0700852void AST::emitCppReaderWriter(
853 Formatter &out,
854 const std::string &parcelObj,
855 bool parcelObjIsPointer,
856 const TypedVar *arg,
857 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -0700858 Type::ErrorMode mode,
859 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700860 const Type &type = arg->type();
861
Andreas Huber881227d2016-08-02 14:20:21 -0700862 type.emitReaderWriter(
863 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700864 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700865 parcelObj,
866 parcelObjIsPointer,
867 isReader,
868 mode);
869}
870
Yifan Hongbf459bc2016-08-23 16:50:37 -0700871void AST::emitCppResolveReferences(
872 Formatter &out,
873 const std::string &parcelObj,
874 bool parcelObjIsPointer,
875 const TypedVar *arg,
876 bool isReader,
877 Type::ErrorMode mode,
878 bool addPrefixToName) const {
879 const Type &type = arg->type();
880 if(type.needsResolveReferences()) {
881 type.emitResolveReferences(
882 out,
883 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
884 isReader, // nameIsPointer
885 parcelObj,
886 parcelObjIsPointer,
887 isReader,
888 mode);
889 }
890}
891
Yifan Hong068c5522016-10-31 14:07:25 -0700892status_t AST::generateProxyMethodSource(Formatter &out,
893 const std::string &klassName,
894 const Method *method,
895 const Interface *superInterface) const {
896
897 method->generateCppSignature(out,
898 klassName,
899 true /* specify namespaces */);
900
901 const bool returnsValue = !method->results().empty();
902 const TypedVar *elidedReturn = method->canElideCallback();
903
Steven Moreland41c6d2e2016-11-07 12:26:54 -0800904 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700905
906 out.indent();
907
908 if (returnsValue && elidedReturn == nullptr) {
909 generateCheckNonNull(out, "_hidl_cb");
910 }
911
912 status_t status = generateCppInstrumentationCall(
913 out,
914 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -0700915 method);
916 if (status != OK) {
917 return status;
918 }
919
920 out << "::android::hardware::Parcel _hidl_data;\n";
921 out << "::android::hardware::Parcel _hidl_reply;\n";
922 out << "::android::status_t _hidl_err;\n";
923 out << "::android::hardware::Status _hidl_status;\n\n";
924
925 declareCppReaderLocals(
926 out, method->results(), true /* forResults */);
927
928 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
929 if (!method->isHidlReserved()) {
930 out << superInterface->fqName().cppNamespace()
931 << "::IHw"
932 << superInterface->getBaseName();
933 } else {
Yifan Hong5bd9aff2016-11-08 18:52:55 -0800934 out << "::android::hardware::IBase";
Yifan Hong068c5522016-10-31 14:07:25 -0700935 }
936 out << "::descriptor);\n";
937
938 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
939
940 // First DFS: write all buffers and resolve pointers for parent
941 for (const auto &arg : method->args()) {
942 emitCppReaderWriter(
943 out,
944 "_hidl_data",
945 false /* parcelObjIsPointer */,
946 arg,
947 false /* reader */,
948 Type::ErrorMode_Goto,
949 false /* addPrefixToName */);
950 }
951
952 // Second DFS: resolve references.
953 for (const auto &arg : method->args()) {
954 emitCppResolveReferences(
955 out,
956 "_hidl_data",
957 false /* parcelObjIsPointer */,
958 arg,
959 false /* reader */,
960 Type::ErrorMode_Goto,
961 false /* addPrefixToName */);
962 }
963
964 out << "_hidl_err = remote()->transact("
965 << method->getSerialId()
966 << " /* "
967 << method->name()
968 << " */, _hidl_data, &_hidl_reply";
969
970 if (method->isOneway()) {
971 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
972 }
973 out << ");\n";
974
975 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
976
977 if (!method->isOneway()) {
978 out << "_hidl_err = _hidl_status.readFromParcel(_hidl_reply);\n";
979 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
980 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
981
982
983 // First DFS: write all buffers and resolve pointers for parent
984 for (const auto &arg : method->results()) {
985 emitCppReaderWriter(
986 out,
987 "_hidl_reply",
988 false /* parcelObjIsPointer */,
989 arg,
990 true /* reader */,
991 Type::ErrorMode_Goto,
992 true /* addPrefixToName */);
993 }
994
995 // Second DFS: resolve references.
996 for (const auto &arg : method->results()) {
997 emitCppResolveReferences(
998 out,
999 "_hidl_reply",
1000 false /* parcelObjIsPointer */,
1001 arg,
1002 true /* reader */,
1003 Type::ErrorMode_Goto,
1004 true /* addPrefixToName */);
1005 }
1006
1007 if (returnsValue && elidedReturn == nullptr) {
1008 out << "_hidl_cb(";
1009
1010 bool first = true;
1011 for (const auto &arg : method->results()) {
1012 if (!first) {
1013 out << ", ";
1014 }
1015
1016 if (arg->type().resultNeedsDeref()) {
1017 out << "*";
1018 }
1019 out << "_hidl_out_" << arg->name();
1020
1021 first = false;
1022 }
1023
1024 out << ");\n\n";
1025 }
1026 status_t status = generateCppInstrumentationCall(
1027 out,
1028 InstrumentationEvent::CLIENT_API_EXIT,
Yifan Hong068c5522016-10-31 14:07:25 -07001029 method);
1030 if (status != OK) {
1031 return status;
1032 }
1033 }
1034
1035 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001036 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1037 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001038 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001039 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1040 } else {
1041 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1042 out << "return ::android::hardware::Return<void>();\n\n";
1043 }
1044
1045 out.unindent();
1046 out << "_hidl_error:\n";
1047 out.indent();
1048 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1049 out << "return ::android::hardware::Return<";
1050 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001051 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001052 } else {
1053 out << "void";
1054 }
1055 out << ">(_hidl_status);\n";
1056
1057 out.unindent();
1058 out << "}\n\n";
1059 return OK;
1060}
1061
Andreas Huber881227d2016-08-02 14:20:21 -07001062status_t AST::generateProxySource(
1063 Formatter &out, const std::string &baseName) const {
1064 const std::string klassName = "Bp" + baseName;
1065
1066 out << klassName
1067 << "::"
1068 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001069 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001070
1071 out.indent();
1072 out.indent();
1073
1074 out << ": BpInterface"
Steven Moreland40786312016-08-16 10:29:40 -07001075 << "<IHw"
Andreas Huber881227d2016-08-02 14:20:21 -07001076 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001077 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001078 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001079 << mPackage.string()
1080 << "::I"
1081 << baseName
1082 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001083
Andreas Huber881227d2016-08-02 14:20:21 -07001084 out.unindent();
1085 out.unindent();
1086 out << "}\n\n";
1087
Yifan Hong068c5522016-10-31 14:07:25 -07001088 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1089 return generateProxyMethodSource(out, klassName, method, superInterface);
1090 });
Andreas Huber881227d2016-08-02 14:20:21 -07001091
Yifan Hong068c5522016-10-31 14:07:25 -07001092 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001093}
1094
1095status_t AST::generateStubSource(
1096 Formatter &out, const std::string &baseName) const {
1097 out << "IMPLEMENT_HWBINDER_META_INTERFACE("
1098 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001099 << ", "
1100 << mPackage.cppNamespace()
Andreas Huber881227d2016-08-02 14:20:21 -07001101 << "::I"
1102 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001103 << "::descriptor);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001104
1105 const std::string klassName = "Bn" + baseName;
1106
Steven Moreland40786312016-08-16 10:29:40 -07001107 out << klassName
1108 << "::"
1109 << klassName
1110 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl)\n";
1111
1112 out.indent();
1113 out.indent();
1114
1115 out << ": BnInterface"
1116 << "<I"
1117 << baseName
1118 << ", IHw"
1119 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001120 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001121 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001122 << mPackage.string()
1123 << "::I"
1124 << baseName
1125 << "\") {\n";
Steven Moreland40786312016-08-16 10:29:40 -07001126
1127 out.unindent();
1128 out.unindent();
1129 out << "}\n\n";
1130
Andreas Huber881227d2016-08-02 14:20:21 -07001131 out << "::android::status_t " << klassName << "::onTransact(\n";
1132
1133 out.indent();
1134 out.indent();
1135
Iliyan Malchev549e2592016-08-10 08:59:12 -07001136 out << "uint32_t _hidl_code,\n"
1137 << "const ::android::hardware::Parcel &_hidl_data,\n"
1138 << "::android::hardware::Parcel *_hidl_reply,\n"
1139 << "uint32_t _hidl_flags,\n"
1140 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001141
1142 out.unindent();
1143
Iliyan Malchev549e2592016-08-10 08:59:12 -07001144 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001145 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001146 out.indent();
1147
1148 const Interface *iface = mRootScope->getInterface();
1149
Yifan Hong10fe0b52016-10-19 14:20:17 -07001150 for (const auto &tuple : iface->allMethodsFromRoot()) {
1151 const Method *method = tuple.method();
1152 const Interface *superInterface = tuple.interface();
1153 out << "case "
1154 << method->getSerialId()
1155 << " /* "
1156 << method->name()
1157 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001158
Yifan Hong10fe0b52016-10-19 14:20:17 -07001159 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001160
Yifan Hong10fe0b52016-10-19 14:20:17 -07001161 status_t err =
1162 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001163
Yifan Hong10fe0b52016-10-19 14:20:17 -07001164 if (err != OK) {
1165 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001166 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001167
1168 out.unindent();
1169 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001170 }
1171
1172 out << "default:\n{\n";
1173 out.indent();
1174
Andreas Huber8a82ff72016-08-04 10:29:39 -07001175 out << "return ::android::hardware::BnInterface<I"
Steven Moreland40786312016-08-16 10:29:40 -07001176 << baseName << ", IHw" << baseName
Andreas Huber881227d2016-08-02 14:20:21 -07001177 << ">::onTransact(\n";
1178
1179 out.indent();
1180 out.indent();
1181
Iliyan Malchev549e2592016-08-10 08:59:12 -07001182 out << "_hidl_code, _hidl_data, _hidl_reply, "
1183 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001184
1185 out.unindent();
1186 out.unindent();
1187
1188 out.unindent();
1189 out << "}\n";
1190
1191 out.unindent();
1192 out << "}\n\n";
1193
Iliyan Malchev549e2592016-08-10 08:59:12 -07001194 out << "if (_hidl_err == ::android::UNEXPECTED_NULL) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001195 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001196 out << "_hidl_err = ::android::hardware::Status::fromExceptionCode(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001197 out.indent();
1198 out.indent();
Andreas Huber8a82ff72016-08-04 10:29:39 -07001199 out << "::android::hardware::Status::EX_NULL_POINTER)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001200 out.indent();
1201 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001202 out << ".writeToParcel(_hidl_reply);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001203 out.unindent();
1204 out.unindent();
1205 out.unindent();
1206 out.unindent();
1207
1208 out.unindent();
1209 out << "}\n\n";
1210
Iliyan Malchev549e2592016-08-10 08:59:12 -07001211 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001212
1213 out.unindent();
1214 out << "}\n\n";
1215
1216 return OK;
1217}
1218
1219status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001220 Formatter &out, const Interface *iface, const Method *method) const {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001221 out << "if (!_hidl_data.enforceInterface(";
1222
1223 if (!method->isHidlReserved()) {
1224 out << iface->fqName().cppNamespace()
1225 << "::IHw"
1226 << iface->getBaseName();
1227 } else {
Yifan Hong5bd9aff2016-11-08 18:52:55 -08001228 out << "::android::hardware::IBase";
Yifan Hong10fe0b52016-10-19 14:20:17 -07001229 }
1230
1231 out << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001232
Andreas Huber881227d2016-08-02 14:20:21 -07001233 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001234 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001235 out << "break;\n";
1236 out.unindent();
1237 out << "}\n\n";
1238
Andreas Huber5e44a292016-09-27 14:52:39 -07001239 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001240
Yifan Hongbf459bc2016-08-23 16:50:37 -07001241 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001242 for (const auto &arg : method->args()) {
1243 emitCppReaderWriter(
1244 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001245 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001246 false /* parcelObjIsPointer */,
1247 arg,
1248 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001249 Type::ErrorMode_Break,
1250 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001251 }
1252
Yifan Hongbf459bc2016-08-23 16:50:37 -07001253 // Second DFS: resolve references
1254 for (const auto &arg : method->args()) {
1255 emitCppResolveReferences(
1256 out,
1257 "_hidl_data",
1258 false /* parcelObjIsPointer */,
1259 arg,
1260 true /* reader */,
1261 Type::ErrorMode_Break,
1262 false /* addPrefixToName */);
1263 }
1264
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001265 status_t status = generateCppInstrumentationCall(
1266 out,
1267 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001268 method);
1269 if (status != OK) {
1270 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001271 }
1272
Andreas Huber881227d2016-08-02 14:20:21 -07001273 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001274 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001275
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001276 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001277 out << elidedReturn->type().getCppResultType()
1278 << " "
1279 << elidedReturn->name()
1280 << " = "
1281 << method->name()
1282 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001283
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001284 bool first = true;
1285 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001286 if (!first) {
1287 out << ", ";
1288 }
1289
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001290 if (arg->type().resultNeedsDeref()) {
1291 out << "*";
1292 }
1293
1294 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001295
1296 first = false;
1297 }
1298
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001299 out << ");\n\n";
Andreas Huber8a82ff72016-08-04 10:29:39 -07001300 out << "::android::hardware::Status::ok()"
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001301 << ".writeToParcel(_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001302
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001303 elidedReturn->type().emitReaderWriter(
1304 out,
1305 elidedReturn->name(),
1306 "_hidl_reply",
1307 true, /* parcelObjIsPointer */
1308 false, /* isReader */
1309 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001310
Yifan Hongbf459bc2016-08-23 16:50:37 -07001311 emitCppResolveReferences(
1312 out,
1313 "_hidl_reply",
1314 true /* parcelObjIsPointer */,
1315 elidedReturn,
1316 false /* reader */,
1317 Type::ErrorMode_Ignore,
1318 false /* addPrefixToName */);
1319
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001320 status_t status = generateCppInstrumentationCall(
1321 out,
1322 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001323 method);
1324 if (status != OK) {
1325 return status;
1326 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001327
Iliyan Malchev549e2592016-08-10 08:59:12 -07001328 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001329 } else {
1330 if (returnsValue) {
1331 out << "bool _hidl_callbackCalled = false;\n\n";
1332 }
Andreas Huber881227d2016-08-02 14:20:21 -07001333
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001334 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001335
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001336 bool first = true;
1337 for (const auto &arg : method->args()) {
1338 if (!first) {
1339 out << ", ";
1340 }
Andreas Huber881227d2016-08-02 14:20:21 -07001341
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001342 if (arg->type().resultNeedsDeref()) {
1343 out << "*";
1344 }
1345
1346 out << arg->name();
1347
1348 first = false;
1349 }
1350
1351 if (returnsValue) {
1352 if (!first) {
1353 out << ", ";
1354 }
1355
1356 out << "[&](";
1357
1358 first = true;
1359 for (const auto &arg : method->results()) {
1360 if (!first) {
1361 out << ", ";
1362 }
1363
1364 out << "const auto &" << arg->name();
1365
1366 first = false;
1367 }
1368
1369 out << ") {\n";
1370 out.indent();
1371 out << "_hidl_callbackCalled = true;\n\n";
1372
1373 out << "::android::hardware::Status::ok()"
1374 << ".writeToParcel(_hidl_reply);\n\n";
1375
Yifan Hongbf459bc2016-08-23 16:50:37 -07001376 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001377 for (const auto &arg : method->results()) {
1378 emitCppReaderWriter(
1379 out,
1380 "_hidl_reply",
1381 true /* parcelObjIsPointer */,
1382 arg,
1383 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001384 Type::ErrorMode_Ignore,
1385 false /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001386 }
1387
Yifan Hongbf459bc2016-08-23 16:50:37 -07001388 // Second DFS: resolve references
1389 for (const auto &arg : method->results()) {
1390 emitCppResolveReferences(
1391 out,
1392 "_hidl_reply",
1393 true /* parcelObjIsPointer */,
1394 arg,
1395 false /* reader */,
1396 Type::ErrorMode_Ignore,
1397 false /* addPrefixToName */);
1398 }
1399
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001400 status_t status = generateCppInstrumentationCall(
1401 out,
1402 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001403 method);
1404 if (status != OK) {
1405 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001406 }
1407
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001408 out << "_hidl_cb(*_hidl_reply);\n";
1409
1410 out.unindent();
1411 out << "}\n";
1412 }
1413
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001414 out << ");\n\n";
1415
1416 // What to do if the stub implementation has a synchronous callback
1417 // which does not get invoked? This is not a transport error but a
1418 // service error of sorts. For now, return OK to the caller, as this is
1419 // not a transport error.
1420 //
1421 // TODO(b/31365311) Figure out how to deal with this later.
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001422
1423 if (returnsValue) {
1424 out << "if (!_hidl_callbackCalled) {\n";
1425 out.indent();
1426 }
1427
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001428 out << "::android::hardware::Status::ok()"
1429 << ".writeToParcel(_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001430
1431 if (returnsValue) {
1432 out.unindent();
1433 out << "}\n\n";
1434 }
Andreas Huber881227d2016-08-02 14:20:21 -07001435 }
1436
1437 out << "break;\n";
1438
1439 return OK;
1440}
1441
Steven Moreland69e7c702016-09-09 11:16:32 -07001442status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1443 std::string ifaceName;
1444 if (!AST::isInterface(&ifaceName)) {
1445 // types.hal does not get a stub header.
1446 return OK;
1447 }
1448
1449 const Interface *iface = mRootScope->getInterface();
1450
1451 const std::string baseName = iface->getBaseName();
1452 const std::string klassName = "Bs" + baseName;
1453
1454 bool supportOneway = iface->hasOnewayMethods();
1455
1456 std::string path = outputPath;
1457 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1458 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1459 path.append(klassName);
1460 path.append(".h");
1461
1462 CHECK(Coordinator::MakeParentHierarchy(path));
1463 FILE *file = fopen(path.c_str(), "w");
1464
1465 if (file == NULL) {
1466 return -errno;
1467 }
1468
1469 Formatter out(file);
1470
1471 const std::string guard = makeHeaderGuard(klassName);
1472
1473 out << "#ifndef " << guard << "\n";
1474 out << "#define " << guard << "\n\n";
1475
1476 std::vector<std::string> packageComponents;
1477 getPackageAndVersionComponents(
1478 &packageComponents, false /* cpp_compatible */);
1479
1480 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001481
1482 generateCppPackageInclude(out, mPackage, ifaceName);
1483 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001484
1485 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001486 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001487 }
1488
1489 enterLeaveNamespace(out, true /* enter */);
1490 out << "\n";
1491
1492 out << "struct "
1493 << klassName
1494 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001495 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001496
1497 out.indent();
1498 out << "explicit "
1499 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001500 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001501 << ifaceName
1502 << "> impl);\n";
1503
Yifan Hong068c5522016-10-31 14:07:25 -07001504 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1505 return generatePassthroughMethod(out, method);
1506 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001507
1508 if (err != OK) {
1509 return err;
1510 }
1511
1512 out.unindent();
1513 out << "private:\n";
1514 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001515 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001516
1517 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001518 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001519
1520 out << "\n";
1521
1522 out << "::android::hardware::Return<void> addOnewayTask("
1523 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001524 }
1525
1526 out.unindent();
1527
1528 out << "};\n\n";
1529
1530 enterLeaveNamespace(out, false /* enter */);
1531
1532 out << "\n#endif // " << guard << "\n";
1533
1534 return OK;
1535}
1536
Yifan Hongfe95aa22016-10-19 17:26:45 -07001537status_t AST::generateInterfaceSource(Formatter &out) const {
1538 const Interface *iface = mRootScope->getInterface();
1539
Yifan Hong2d7126b2016-10-20 15:12:57 -07001540 // generate castFrom functions
Yifan Hongfe95aa22016-10-19 17:26:45 -07001541 if (!iface->isRootType()) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001542 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001543
1544 for (const Interface *superType : iface->superTypeChain()) {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001545 out << "// static \n"
1546 << childTypeResult
1547 << " I"
1548 << iface->getBaseName()
1549 << "::castFrom("
Yifan Hong3b320f82016-11-01 15:15:54 -07001550 << superType->getCppArgumentType()
1551 << " parent) {\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001552 out.indent();
1553 out << "return ::android::hardware::castInterface<";
1554 out << "I" << iface->getBaseName() << ", "
1555 << superType->fqName().cppName() << ", "
Yifan Hong158655a2016-11-08 12:34:07 -08001556 << "Bp" << iface->getBaseName() << ", "
1557 << superType->getHwName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001558 << ">(\n";
1559 out.indent();
1560 out.indent();
1561 out << "parent, \""
1562 << iface->fqName().string()
1563 << "\");\n";
1564 out.unindent();
1565 out.unindent();
1566 out.unindent();
1567 out << "}\n\n";
1568 }
1569 }
1570
1571 return OK;
1572}
1573
Steven Moreland69e7c702016-09-09 11:16:32 -07001574status_t AST::generatePassthroughSource(Formatter &out) const {
1575 const Interface *iface = mRootScope->getInterface();
1576
1577 const std::string baseName = iface->getBaseName();
1578 const std::string klassName = "Bs" + baseName;
1579
1580 out << klassName
1581 << "::"
1582 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001583 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001584 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001585 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001586 << iface->fqName().string()
1587 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001588 if (iface->hasOnewayMethods()) {
1589 out << "\n";
1590 out.indentBlock([&] {
1591 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1592 });
1593 }
1594 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001595
1596 if (iface->hasOnewayMethods()) {
1597 out << "::android::hardware::Return<void> "
1598 << klassName
1599 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1600 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001601 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001602 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001603 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1604 out.indent();
1605 out.indent();
1606 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1607 out.unindent();
1608 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001609 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001610 out << "}\n";
1611
Steven Morelandd366c262016-10-11 15:29:10 -07001612 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001613
1614 out.unindent();
1615 out << "}\n\n";
1616
1617
1618 }
1619
1620 return OK;
1621}
1622
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001623status_t AST::generateCppInstrumentationCall(
1624 Formatter &out,
1625 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001626 const Method *method) const {
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001627 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1628 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001629 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001630 std::string event_str = "";
1631 switch (event) {
1632 case SERVER_API_ENTRY:
1633 {
1634 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1635 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001636 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001637 << (arg->type().resultNeedsDeref() ? "" : "&")
1638 << arg->name()
1639 << ");\n";
1640 }
1641 break;
1642 }
1643 case SERVER_API_EXIT:
1644 {
1645 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001646 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001647 out << "_hidl_args.push_back((void *)&"
Steven Moreland031ccf12016-10-31 15:54:38 -07001648 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001649 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001650 }
1651 break;
1652 }
1653 case CLIENT_API_ENTRY:
1654 {
1655 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1656 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001657 out << "_hidl_args.push_back((void *)&"
1658 << arg->name()
1659 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001660 }
1661 break;
1662 }
1663 case CLIENT_API_EXIT:
1664 {
1665 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1666 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001667 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001668 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001669 << "_hidl_out_"
1670 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001671 << ");\n";
1672 }
1673 break;
1674 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001675 case PASSTHROUGH_ENTRY:
1676 {
1677 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1678 for (const auto &arg : method->args()) {
1679 out << "_hidl_args.push_back((void *)&"
1680 << arg->name()
1681 << ");\n";
1682 }
1683 break;
1684 }
1685 case PASSTHROUGH_EXIT:
1686 {
1687 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
1688 // TODO(b/32576620): passthrough return values
1689 break;
1690 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001691 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001692 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001693 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001694 return UNKNOWN_ERROR;
1695 }
1696 }
1697
Steven Moreland031ccf12016-10-31 15:54:38 -07001698 const Interface *iface = mRootScope->getInterface();
1699
Steven Moreland1ab31442016-11-03 18:37:51 -07001700 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001701 out.indent();
1702 out << "callback("
1703 << event_str
1704 << ", \""
1705 << mPackage.package()
1706 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07001707 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001708 << "\", \""
1709 << iface->localName()
1710 << "\", \""
1711 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001712 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001713 out.unindent();
1714 out << "}\n";
1715 out.unindent();
1716 out << "}\n\n";
1717
1718 return OK;
1719}
1720
Andreas Huber881227d2016-08-02 14:20:21 -07001721} // namespace android
1722