blob: 01aeaf95122f5a331f2d992b947dac6429dda8c4 [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
Steven Moreland0693f312016-11-09 15:06:14 -0800165 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800166 if (isIBase()) {
167 out << "// skipped #include IServiceNotification.h\n\n";
168 } else {
169 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
170 }
Steven Moreland0693f312016-11-09 15:06:14 -0800171 }
172
Yifan Hongc8934042016-11-17 17:10:52 -0800173 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700174 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700175
176 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200177 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700178 }
179
Martijn Coenenaf712c02016-11-16 15:26:27 +0100180 out << "#include <utils/NativeHandle.h>\n";
181 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700182
183 enterLeaveNamespace(out, true /* enter */);
184 out << "\n";
185
186 if (isInterface) {
187 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700188 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700189
190 const Interface *iface = mRootScope->getInterface();
191 const Interface *superType = iface->superType();
192
Steven Moreland40786312016-08-16 10:29:40 -0700193 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800194 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700195 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000196 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700197 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700198 }
199
200 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700201
202 out.indent();
203
Andreas Huber881227d2016-08-02 14:20:21 -0700204 }
205
206 status_t err = emitTypeDeclarations(out);
207
208 if (err != OK) {
209 return err;
210 }
211
212 if (isInterface) {
213 const Interface *iface = mRootScope->getInterface();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700214 const Interface *superType = iface->superType();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700215 const std::string baseName = iface->getBaseName();
Steven Moreland19d5c172016-10-20 19:20:25 -0700216 out << "constexpr static ::android::hardware::hidl_version version = {"
Martijn Coenena21f1492016-09-08 15:55:14 +0200217 << mPackage.getPackageMajorVersion() << ","
218 << mPackage.getPackageMinorVersion() << "};\n";
Steven Moreland19d5c172016-10-20 19:20:25 -0700219 out << "virtual const ::android::hardware::hidl_version&"
220 << "getInterfaceVersion() const {\n";
Martijn Coenena21f1492016-09-08 15:55:14 +0200221 out.indent();
222 out << "return version;\n";
223 out.unindent();
224 out << "}\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800225 out << "virtual bool isRemote() const ";
226 if (!isIBase()) {
227 out << "override ";
228 }
229 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800230
Andreas Huber881227d2016-08-02 14:20:21 -0700231 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700232 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700233
Andreas Huber881227d2016-08-02 14:20:21 -0700234 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800235 const TypedVar *elidedReturn = method->canElideCallback();
236
237 if (elidedReturn == nullptr && returnsValue) {
238 out << "using "
239 << method->name()
240 << "_cb = std::function<void("
241 << Method::GetArgSignature(method->results(),
242 true /* specify namespaces */)
243 << ")>;\n";
244 }
Andreas Huber881227d2016-08-02 14:20:21 -0700245
Andreas Huber3599d922016-08-09 10:42:57 -0700246 method->dumpAnnotations(out);
247
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700248 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700249 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700250 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700251 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700252 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700253 }
254
255 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700256 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700257 << Method::GetArgSignature(method->args(),
258 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700259
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700260 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700261 if (!method->args().empty()) {
262 out << ", ";
263 }
264
Steven Moreland67f67b42016-09-29 08:59:02 -0700265 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700266 }
267
Yifan Hong10fe0b52016-10-19 14:20:17 -0700268 out << ")";
269 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800270 if (!isIBase()) {
271 out << " override";
272 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700273 out << " {\n";
274 out.indent();
275 method->cppImpl(out);
276 out.unindent();
277 out << "\n}\n";
278 } else {
279 out << " = 0;\n";
280 }
Andreas Huber881227d2016-08-02 14:20:21 -0700281 }
Steven Moreland40786312016-08-16 10:29:40 -0700282
Yifan Hong3d746092016-12-07 14:26:33 -0800283 out << "// cast static functions\n";
284 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700285
Yifan Hong3d746092016-12-07 14:26:33 -0800286 for (const Interface *superType : iface->typeChain()) {
287 out << "static "
288 << childTypeResult
289 << " castFrom("
290 << superType->getCppArgumentType()
291 << " parent"
292 << ");\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700293 }
294
Steven Morelandd39133b2016-11-11 12:30:08 -0800295 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700296
Yifan Hongc8934042016-11-17 17:10:52 -0800297 if (isIBase()) {
298 out << "// skipped DECLARE_SERVICE_MANAGER_INTERACTIONS\n\n";
299 } else {
300 out << "DECLARE_SERVICE_MANAGER_INTERACTIONS(" << baseName << ")\n\n";
301 }
Yifan Hong158655a2016-11-08 12:34:07 -0800302
303 out << "private: static int hidlStaticBlock;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700304 }
305
306 if (isInterface) {
307 out.unindent();
308
Andreas Hubere3f769a2016-10-10 10:54:44 -0700309 out << "};\n\n";
310 }
311
312 err = mRootScope->emitGlobalTypeDeclarations(out);
313
314 if (err != OK) {
315 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700316 }
317
318 out << "\n";
319 enterLeaveNamespace(out, false /* enter */);
320
321 out << "\n#endif // " << guard << "\n";
322
323 return OK;
324}
325
Steven Moreland40786312016-08-16 10:29:40 -0700326status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
327 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800328 bool isInterface = AST::isInterface(&ifaceName);
329 const Interface *iface = nullptr;
330 std::string baseName{};
331 std::string klassName{};
332
333 if(isInterface) {
334 iface = mRootScope->getInterface();
335 baseName = iface->getBaseName();
336 klassName = "IHw" + baseName;
337 } else {
338 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700339 }
340
Steven Moreland40786312016-08-16 10:29:40 -0700341 std::string path = outputPath;
342 path.append(mCoordinator->convertPackageRootToPath(mPackage));
343 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
344 path.append(klassName + ".h");
345
Yifan Hong244e82d2016-11-11 11:13:57 -0800346 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700347
348 if (file == NULL) {
349 return -errno;
350 }
351
352 Formatter out(file);
353
354 const std::string guard = makeHeaderGuard(klassName);
355
356 out << "#ifndef " << guard << "\n";
357 out << "#define " << guard << "\n\n";
358
Yifan Hong244e82d2016-11-11 11:13:57 -0800359 if (isInterface) {
360 generateCppPackageInclude(out, mPackage, ifaceName);
361 } else {
362 generateCppPackageInclude(out, mPackage, "types");
363 }
Steven Moreland40786312016-08-16 10:29:40 -0700364
Steven Morelandee88eed2016-10-31 17:49:00 -0700365 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700366
367 for (const auto &item : mImportedNames) {
368 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800369 generateCppPackageInclude(out, item, "hwtypes");
370 } else {
371 generateCppPackageInclude(out, item, "Bn" + item.getInterfaceBaseName());
Martijn Coenena63e0ad2016-12-07 17:29:00 +0100372 generateCppPackageInclude(out, item, "Bp" + item.getInterfaceBaseName());
Steven Moreland40786312016-08-16 10:29:40 -0700373 }
Steven Moreland40786312016-08-16 10:29:40 -0700374 }
375
376 out << "\n";
377
Martijn Coenen93915102016-09-01 01:35:52 +0200378 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700379 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100380 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700381
382 out << "\n";
383
384 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700385
Yifan Hong244e82d2016-11-11 11:13:57 -0800386 status_t err = mRootScope->emitGlobalHwDeclarations(out);
387 if (err != OK) {
388 return err;
389 }
Steven Moreland40786312016-08-16 10:29:40 -0700390
391 enterLeaveNamespace(out, false /* enter */);
392
393 out << "\n#endif // " << guard << "\n";
394
395 return OK;
396}
397
Andreas Huber881227d2016-08-02 14:20:21 -0700398status_t AST::emitTypeDeclarations(Formatter &out) const {
399 return mRootScope->emitTypeDeclarations(out);
400}
401
Steven Moreland69e7c702016-09-09 11:16:32 -0700402status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700403 const Method *method) const {
404 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700405
406 out << " {\n";
407 out.indent();
408
409 const bool returnsValue = !method->results().empty();
410 const TypedVar *elidedReturn = method->canElideCallback();
411
Steven Moreland67f67b42016-09-29 08:59:02 -0700412 if (returnsValue && elidedReturn == nullptr) {
413 generateCheckNonNull(out, "_hidl_cb");
414 }
415
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700416 generateCppInstrumentationCall(
417 out,
418 InstrumentationEvent::PASSTHROUGH_ENTRY,
419 method);
420
421 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700422
423 if (method->isOneway()) {
424 out << "addOnewayTask([this";
425 for (const auto &arg : method->args()) {
426 out << ", " << arg->name();
427 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700428 out << "] {\n";
429 out.indent();
430 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700431 }
432
433 out << "mImpl->"
434 << method->name()
435 << "(";
436
437 bool first = true;
438 for (const auto &arg : method->args()) {
439 if (!first) {
440 out << ", ";
441 }
442 first = false;
443 out << arg->name();
444 }
445 if (returnsValue && elidedReturn == nullptr) {
446 if (!method->args().empty()) {
447 out << ", ";
448 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800449 out << "[&](";
450 first = true;
451 for (const auto &arg : method->results()) {
452 if (!first) {
453 out << ", ";
454 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700455
Yifan Honga47eef32016-12-12 10:38:54 -0800456 out << "const auto &_hidl_out_" << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800457
458 first = false;
459 }
460
461 out << ") {\n";
462 out.indent();
463 status_t status = generateCppInstrumentationCall(
464 out,
465 InstrumentationEvent::PASSTHROUGH_EXIT,
466 method);
467 if (status != OK) {
468 return status;
469 }
470
471 out << "_hidl_cb(";
472 first = true;
473 for (const auto &arg : method->results()) {
474 if (!first) {
475 out << ", ";
476 }
477
Yifan Honga47eef32016-12-12 10:38:54 -0800478 out << "_hidl_out_" << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800479
480 first = false;
481 }
482 out << ");\n";
483 out.unindent();
484 out << "});\n\n";
485 } else {
486 out << ");\n\n";
487 if (elidedReturn != nullptr) {
488 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800489 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800490 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000491 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800492 }
493 status_t status = generateCppInstrumentationCall(
494 out,
495 InstrumentationEvent::PASSTHROUGH_EXIT,
496 method);
497 if (status != OK) {
498 return status;
499 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700500 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700501
502 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700503 out.unindent();
504 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700505 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700506
507 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700508
509 out.unindent();
510 out << "}\n";
511
512 return OK;
513}
514
Yifan Hong068c5522016-10-31 14:07:25 -0700515status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700516
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700517 const Interface *iface = mRootScope->getInterface();
518
Yifan Hong10fe0b52016-10-19 14:20:17 -0700519 const Interface *prevIterface = nullptr;
520 for (const auto &tuple : iface->allMethodsFromRoot()) {
521 const Method *method = tuple.method();
522 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700523
Yifan Hong10fe0b52016-10-19 14:20:17 -0700524 if(prevIterface != superInterface) {
525 if (prevIterface != nullptr) {
526 out << "\n";
527 }
528 out << "// Methods from "
529 << superInterface->fullName()
530 << " follow.\n";
531 prevIterface = superInterface;
532 }
Yifan Hong068c5522016-10-31 14:07:25 -0700533 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700534
Yifan Hong10fe0b52016-10-19 14:20:17 -0700535 if (err != OK) {
536 return err;
537 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700538 }
539
Yifan Hong10fe0b52016-10-19 14:20:17 -0700540 out << "\n";
541
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700542 return OK;
543}
544
Andreas Huberb82318c2016-08-02 14:45:54 -0700545status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700546 std::string ifaceName;
547 if (!AST::isInterface(&ifaceName)) {
548 // types.hal does not get a stub header.
549 return OK;
550 }
551
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700552 const Interface *iface = mRootScope->getInterface();
553 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700554 const std::string klassName = "Bn" + baseName;
Andreas Huber881227d2016-08-02 14:20:21 -0700555
Andreas Huberb82318c2016-08-02 14:45:54 -0700556 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700557 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700558 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700559 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700560 path.append(".h");
561
Andreas Huberd2943e12016-08-05 11:59:31 -0700562 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700563 FILE *file = fopen(path.c_str(), "w");
564
565 if (file == NULL) {
566 return -errno;
567 }
568
569 Formatter out(file);
570
Steven Moreland40786312016-08-16 10:29:40 -0700571 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700572
573 out << "#ifndef " << guard << "\n";
574 out << "#define " << guard << "\n\n";
575
Steven Morelandee88eed2016-10-31 17:49:00 -0700576 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
577 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700578
579 enterLeaveNamespace(out, true /* enter */);
580 out << "\n";
581
582 out << "struct "
583 << "Bn"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100584 << baseName;
585 if (iface->isIBase()) {
586 out << " : public ::android::hardware::BBinder";
587 out << ", public ::android::hardware::HidlInstrumentor {\n";
588 } else {
589 out << " : public ::android::hidl::base::V1_0::BnBase {\n";
590 }
Andreas Huber881227d2016-08-02 14:20:21 -0700591
592 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700593 out << "explicit Bn"
594 << baseName
595 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100596 << "\n";
597 out << "explicit Bn"
598 << baseName
599 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
600 << " const std::string& prefix);"
Steven Moreland40786312016-08-16 10:29:40 -0700601 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700602 out << "::android::status_t onTransact(\n";
603 out.indent();
604 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700605 out << "uint32_t _hidl_code,\n";
606 out << "const ::android::hardware::Parcel &_hidl_data,\n";
607 out << "::android::hardware::Parcel *_hidl_reply,\n";
608 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700609 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700610 out.unindent();
611 out.unindent();
612
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100613 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
614 out.unindent();
615 out << "private:\n";
616 out.indent();
617 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700618 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700619 out << "};\n\n";
620
621 enterLeaveNamespace(out, false /* enter */);
622
623 out << "\n#endif // " << guard << "\n";
624
625 return OK;
626}
627
Andreas Huberb82318c2016-08-02 14:45:54 -0700628status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700629 std::string ifaceName;
630 if (!AST::isInterface(&ifaceName)) {
631 // types.hal does not get a proxy header.
632 return OK;
633 }
634
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700635 const Interface *iface = mRootScope->getInterface();
636 const std::string baseName = iface->getBaseName();
Andreas Huber881227d2016-08-02 14:20:21 -0700637
Andreas Huberb82318c2016-08-02 14:45:54 -0700638 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700639 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700640 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700641 path.append("Bp");
642 path.append(baseName);
643 path.append(".h");
644
Andreas Huberd2943e12016-08-05 11:59:31 -0700645 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700646 FILE *file = fopen(path.c_str(), "w");
647
648 if (file == NULL) {
649 return -errno;
650 }
651
652 Formatter out(file);
653
654 const std::string guard = makeHeaderGuard("Bp" + baseName);
655
656 out << "#ifndef " << guard << "\n";
657 out << "#define " << guard << "\n\n";
658
659 std::vector<std::string> packageComponents;
660 getPackageAndVersionComponents(
661 &packageComponents, false /* cpp_compatible */);
662
Steven Morelandee88eed2016-10-31 17:49:00 -0700663 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
664 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700665
666 enterLeaveNamespace(out, true /* enter */);
667 out << "\n";
668
669 out << "struct "
670 << "Bp"
671 << baseName
Martijn Coenena63e0ad2016-12-07 17:29:00 +0100672 << " : public ::android::hardware::BpInterface<I"
Steven Moreland40786312016-08-16 10:29:40 -0700673 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700674 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700675
676 out.indent();
677
678 out << "explicit Bp"
679 << baseName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700680 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700681 << "\n\n";
682
Yifan Hong10fe0b52016-10-19 14:20:17 -0700683 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700684
Yifan Hong068c5522016-10-31 14:07:25 -0700685 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
686 method->generateCppSignature(out);
687 out << " override;\n";
688 return OK;
689 });
Steven Moreland9c387612016-09-07 09:54:26 -0700690
691 if (err != OK) {
692 return err;
693 }
Andreas Huber881227d2016-08-02 14:20:21 -0700694
695 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700696 out << "};\n\n";
697
698 enterLeaveNamespace(out, false /* enter */);
699
700 out << "\n#endif // " << guard << "\n";
701
702 return OK;
703}
704
Andreas Huberb82318c2016-08-02 14:45:54 -0700705status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700706
Andreas Huberb82318c2016-08-02 14:45:54 -0700707 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700708 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700709 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700710
711 std::string ifaceName;
712 std::string baseName;
713
Yifan Hongfe95aa22016-10-19 17:26:45 -0700714 const Interface *iface = nullptr;
715 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700716 if (!AST::isInterface(&ifaceName)) {
717 baseName = "types";
718 isInterface = false;
719 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700720 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700721 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700722 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700723 }
724
725 path.append(baseName);
726
727 if (baseName != "types") {
728 path.append("All");
729 }
730
731 path.append(".cpp");
732
Andreas Huberd2943e12016-08-05 11:59:31 -0700733 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700734 FILE *file = fopen(path.c_str(), "w");
735
736 if (file == NULL) {
737 return -errno;
738 }
739
740 Formatter out(file);
741
Steven Moreland05cd4232016-11-21 16:01:12 -0800742 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100743 out << "#include <cutils/trace.h>\n";
744 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700745 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700746 // This is a no-op for IServiceManager itself.
747 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
748
Steven Morelandee88eed2016-10-31 17:49:00 -0700749 generateCppPackageInclude(out, mPackage, "Bp" + baseName);
750 generateCppPackageInclude(out, mPackage, "Bn" + baseName);
751 generateCppPackageInclude(out, mPackage, "Bs" + baseName);
Yifan Hongfe95aa22016-10-19 17:26:45 -0700752
753 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700754 generateCppPackageInclude(out,
755 superType->fqName(),
756 "Bp" + superType->getBaseName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700757 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800758
759 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700760 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700761 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800762 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700763 }
764
765 out << "\n";
766
767 enterLeaveNamespace(out, true /* enter */);
768 out << "\n";
769
770 status_t err = generateTypeSource(out, ifaceName);
771
772 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700773 const Interface *iface = mRootScope->getInterface();
Steven Moreland19d5c172016-10-20 19:20:25 -0700774 out << "constexpr ::android::hardware::hidl_version "
775 << ifaceName
776 << "::version;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700777
778 // need to be put here, generateStubSource is using this.
Steven Morelandd39133b2016-11-11 12:30:08 -0800779 out << "const char* I"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700780 << iface->getBaseName()
781 << "::descriptor(\""
782 << iface->fqName().string()
783 << "\");\n\n";
784
Yifan Hong158655a2016-11-08 12:34:07 -0800785 out << "int I"
786 << iface->getBaseName()
787 << "::hidlStaticBlock = []() -> int {\n";
788 out.indentBlock([&] {
Steven Morelandd39133b2016-11-11 12:30:08 -0800789 out << "::android::hardware::gBnConstructorMap[I"
Yifan Hong158655a2016-11-08 12:34:07 -0800790 << iface->getBaseName()
Steven Morelandd39133b2016-11-11 12:30:08 -0800791 << "::descriptor]\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800792 out.indentBlock(2, [&] {
793 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
794 out.indentBlock([&] {
795 out << "return new Bn"
796 << iface->getBaseName()
797 << "(reinterpret_cast<I"
798 << iface->getBaseName()
799 << " *>(iIntf));\n";
800 });
801 out << "};\n";
802 });
803 out << "return 1;\n";
804 });
805 out << "}();\n\n";
806
Yifan Hongfe95aa22016-10-19 17:26:45 -0700807 err = generateInterfaceSource(out);
808 }
809
810 if (err == OK && isInterface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700811 err = generateProxySource(out, baseName);
812 }
813
814 if (err == OK && isInterface) {
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100815 err = generateStubSource(out, iface, baseName);
Andreas Huber881227d2016-08-02 14:20:21 -0700816 }
817
Steven Moreland40786312016-08-16 10:29:40 -0700818 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -0700819 err = generatePassthroughSource(out);
820 }
821
822 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -0700823 const Interface *iface = mRootScope->getInterface();
824
Yifan Hongc8934042016-11-17 17:10:52 -0800825 if (isIBase()) {
826 out << "// skipped IMPLEMENT_SERVICE_MANAGER_INTERACTIONS\n";
827 } else {
828 out << "IMPLEMENT_SERVICE_MANAGER_INTERACTIONS("
829 << baseName << ", "
830 << "\"" << iface->fqName().package()
831 << iface->fqName().atVersion()
832 << "\")\n";
833 }
Steven Moreland40786312016-08-16 10:29:40 -0700834 }
835
Andreas Huber881227d2016-08-02 14:20:21 -0700836 enterLeaveNamespace(out, false /* enter */);
837
838 return err;
839}
840
Steven Moreland67f67b42016-09-29 08:59:02 -0700841// static
842void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
843 out << "if (" << nonNull << " == nullptr) {\n";
844 out.indent();
845 out << "return ::android::hardware::Status::fromExceptionCode(\n";
846 out.indent();
847 out.indent();
848 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
849 out.unindent();
850 out.unindent();
851 out.unindent();
852 out << "}\n\n";
853}
854
Andreas Huber881227d2016-08-02 14:20:21 -0700855status_t AST::generateTypeSource(
856 Formatter &out, const std::string &ifaceName) const {
857 return mRootScope->emitTypeDefinitions(out, ifaceName);
858}
859
Andreas Hubere7ff2282016-08-16 13:50:03 -0700860void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -0700861 Formatter &out,
862 const std::vector<TypedVar *> &args,
863 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700864 if (args.empty()) {
865 return;
866 }
867
868 for (const auto &arg : args) {
869 const Type &type = arg->type();
870
Yifan Hong3b320f82016-11-01 15:15:54 -0700871 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700872 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700873 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700874 << ";\n";
875 }
876
877 out << "\n";
878}
879
Andreas Huber881227d2016-08-02 14:20:21 -0700880void AST::emitCppReaderWriter(
881 Formatter &out,
882 const std::string &parcelObj,
883 bool parcelObjIsPointer,
884 const TypedVar *arg,
885 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -0700886 Type::ErrorMode mode,
887 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700888 const Type &type = arg->type();
889
Andreas Huber881227d2016-08-02 14:20:21 -0700890 type.emitReaderWriter(
891 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700892 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700893 parcelObj,
894 parcelObjIsPointer,
895 isReader,
896 mode);
897}
898
Yifan Hongbf459bc2016-08-23 16:50:37 -0700899void AST::emitCppResolveReferences(
900 Formatter &out,
901 const std::string &parcelObj,
902 bool parcelObjIsPointer,
903 const TypedVar *arg,
904 bool isReader,
905 Type::ErrorMode mode,
906 bool addPrefixToName) const {
907 const Type &type = arg->type();
908 if(type.needsResolveReferences()) {
909 type.emitResolveReferences(
910 out,
911 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
912 isReader, // nameIsPointer
913 parcelObj,
914 parcelObjIsPointer,
915 isReader,
916 mode);
917 }
918}
919
Yifan Hong068c5522016-10-31 14:07:25 -0700920status_t AST::generateProxyMethodSource(Formatter &out,
921 const std::string &klassName,
922 const Method *method,
923 const Interface *superInterface) const {
924
925 method->generateCppSignature(out,
926 klassName,
927 true /* specify namespaces */);
928
929 const bool returnsValue = !method->results().empty();
930 const TypedVar *elidedReturn = method->canElideCallback();
931
Steven Moreland41c6d2e2016-11-07 12:26:54 -0800932 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700933
934 out.indent();
935
936 if (returnsValue && elidedReturn == nullptr) {
937 generateCheckNonNull(out, "_hidl_cb");
938 }
939
940 status_t status = generateCppInstrumentationCall(
941 out,
942 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -0700943 method);
944 if (status != OK) {
945 return status;
946 }
947
948 out << "::android::hardware::Parcel _hidl_data;\n";
949 out << "::android::hardware::Parcel _hidl_reply;\n";
950 out << "::android::status_t _hidl_err;\n";
951 out << "::android::hardware::Status _hidl_status;\n\n";
952
953 declareCppReaderLocals(
954 out, method->results(), true /* forResults */);
955
956 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongc8934042016-11-17 17:10:52 -0800957 out << superInterface->fqName().cppNamespace()
958 << "::I"
959 << superInterface->getBaseName();
Yifan Hong068c5522016-10-31 14:07:25 -0700960 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700961 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
962
963 // First DFS: write all buffers and resolve pointers for parent
964 for (const auto &arg : method->args()) {
965 emitCppReaderWriter(
966 out,
967 "_hidl_data",
968 false /* parcelObjIsPointer */,
969 arg,
970 false /* reader */,
971 Type::ErrorMode_Goto,
972 false /* addPrefixToName */);
973 }
974
975 // Second DFS: resolve references.
976 for (const auto &arg : method->args()) {
977 emitCppResolveReferences(
978 out,
979 "_hidl_data",
980 false /* parcelObjIsPointer */,
981 arg,
982 false /* reader */,
983 Type::ErrorMode_Goto,
984 false /* addPrefixToName */);
985 }
986
987 out << "_hidl_err = remote()->transact("
988 << method->getSerialId()
989 << " /* "
990 << method->name()
991 << " */, _hidl_data, &_hidl_reply";
992
993 if (method->isOneway()) {
994 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
995 }
996 out << ");\n";
997
998 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
999
1000 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001001 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001002 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1003 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1004
1005
1006 // First DFS: write all buffers and resolve pointers for parent
1007 for (const auto &arg : method->results()) {
1008 emitCppReaderWriter(
1009 out,
1010 "_hidl_reply",
1011 false /* parcelObjIsPointer */,
1012 arg,
1013 true /* reader */,
1014 Type::ErrorMode_Goto,
1015 true /* addPrefixToName */);
1016 }
1017
1018 // Second DFS: resolve references.
1019 for (const auto &arg : method->results()) {
1020 emitCppResolveReferences(
1021 out,
1022 "_hidl_reply",
1023 false /* parcelObjIsPointer */,
1024 arg,
1025 true /* reader */,
1026 Type::ErrorMode_Goto,
1027 true /* addPrefixToName */);
1028 }
1029
1030 if (returnsValue && elidedReturn == nullptr) {
1031 out << "_hidl_cb(";
1032
1033 bool first = true;
1034 for (const auto &arg : method->results()) {
1035 if (!first) {
1036 out << ", ";
1037 }
1038
1039 if (arg->type().resultNeedsDeref()) {
1040 out << "*";
1041 }
1042 out << "_hidl_out_" << arg->name();
1043
1044 first = false;
1045 }
1046
1047 out << ");\n\n";
1048 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001049 }
1050 status = generateCppInstrumentationCall(
1051 out,
1052 InstrumentationEvent::CLIENT_API_EXIT,
1053 method);
1054 if (status != OK) {
1055 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001056 }
1057
1058 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001059 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1060 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001061 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001062 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1063 } else {
1064 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1065 out << "return ::android::hardware::Return<void>();\n\n";
1066 }
1067
1068 out.unindent();
1069 out << "_hidl_error:\n";
1070 out.indent();
1071 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1072 out << "return ::android::hardware::Return<";
1073 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001074 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001075 } else {
1076 out << "void";
1077 }
1078 out << ">(_hidl_status);\n";
1079
1080 out.unindent();
1081 out << "}\n\n";
1082 return OK;
1083}
1084
Andreas Huber881227d2016-08-02 14:20:21 -07001085status_t AST::generateProxySource(
1086 Formatter &out, const std::string &baseName) const {
1087 const std::string klassName = "Bp" + baseName;
1088
1089 out << klassName
1090 << "::"
1091 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001092 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001093
1094 out.indent();
1095 out.indent();
1096
1097 out << ": BpInterface"
Martijn Coenena63e0ad2016-12-07 17:29:00 +01001098 << "<I"
Andreas Huber881227d2016-08-02 14:20:21 -07001099 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001100 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001101 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001102 << mPackage.string()
1103 << "::I"
1104 << baseName
1105 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001106
Andreas Huber881227d2016-08-02 14:20:21 -07001107 out.unindent();
1108 out.unindent();
1109 out << "}\n\n";
1110
Yifan Hong068c5522016-10-31 14:07:25 -07001111 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1112 return generateProxyMethodSource(out, klassName, method, superInterface);
1113 });
Andreas Huber881227d2016-08-02 14:20:21 -07001114
Yifan Hong068c5522016-10-31 14:07:25 -07001115 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001116}
1117
1118status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001119 Formatter &out,
1120 const Interface *iface,
1121 const std::string &baseName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001122 const std::string klassName = "Bn" + baseName;
1123
Steven Moreland40786312016-08-16 10:29:40 -07001124 out << klassName
1125 << "::"
1126 << klassName
1127 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl)\n";
1128
1129 out.indent();
1130 out.indent();
1131
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001132 if (iface->isIBase()) {
1133 out << ": ::android::hardware::HidlInstrumentor(\"";
1134 } else {
1135 out << ": ::android::hidl::base::V1_0::BnBase(_hidl_impl, \"";
1136 }
1137
1138 out << mPackage.string()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001139 << "::I"
1140 << baseName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001141 << "\") { \n";
1142 out.indent();
1143 out << "_hidl_mImpl = _hidl_impl;\n";
1144 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001145
1146 out.unindent();
1147 out.unindent();
1148 out << "}\n\n";
1149
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001150 if (iface->isIBase()) {
1151 // BnBase has a constructor to initialize the HidlInstrumentor
1152 // class properly.
1153 out << klassName
1154 << "::"
1155 << klassName
1156 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl,"
1157 << " const std::string &prefix)\n";
1158
1159 out.indent();
1160 out.indent();
1161
1162 out << ": ::android::hardware::HidlInstrumentor(prefix) { \n";
1163 out.indent();
1164 out << "_hidl_mImpl = _hidl_impl;\n";
1165 out.unindent();
1166
1167 out.unindent();
1168 out.unindent();
1169 out << "}\n\n";
1170 }
1171
1172
Andreas Huber881227d2016-08-02 14:20:21 -07001173 out << "::android::status_t " << klassName << "::onTransact(\n";
1174
1175 out.indent();
1176 out.indent();
1177
Iliyan Malchev549e2592016-08-10 08:59:12 -07001178 out << "uint32_t _hidl_code,\n"
1179 << "const ::android::hardware::Parcel &_hidl_data,\n"
1180 << "::android::hardware::Parcel *_hidl_reply,\n"
1181 << "uint32_t _hidl_flags,\n"
1182 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001183
1184 out.unindent();
1185
Iliyan Malchev549e2592016-08-10 08:59:12 -07001186 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001187 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001188 out.indent();
1189
Yifan Hong10fe0b52016-10-19 14:20:17 -07001190 for (const auto &tuple : iface->allMethodsFromRoot()) {
1191 const Method *method = tuple.method();
1192 const Interface *superInterface = tuple.interface();
1193 out << "case "
1194 << method->getSerialId()
1195 << " /* "
1196 << method->name()
1197 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001198
Yifan Hong10fe0b52016-10-19 14:20:17 -07001199 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001200
Yifan Hong10fe0b52016-10-19 14:20:17 -07001201 status_t err =
1202 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001203
Yifan Hong10fe0b52016-10-19 14:20:17 -07001204 if (err != OK) {
1205 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001206 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001207
1208 out.unindent();
1209 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001210 }
1211
1212 out << "default:\n{\n";
1213 out.indent();
1214
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001215 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001216
1217 out.indent();
1218 out.indent();
1219
Iliyan Malchev549e2592016-08-10 08:59:12 -07001220 out << "_hidl_code, _hidl_data, _hidl_reply, "
1221 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001222
1223 out.unindent();
1224 out.unindent();
1225
1226 out.unindent();
1227 out << "}\n";
1228
1229 out.unindent();
1230 out << "}\n\n";
1231
Iliyan Malchev549e2592016-08-10 08:59:12 -07001232 out << "if (_hidl_err == ::android::UNEXPECTED_NULL) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001233 out.indent();
Yifan Hong859e53f2016-11-14 19:08:24 -08001234 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001235 out.indent();
1236 out.indent();
Yifan Hong859e53f2016-11-14 19:08:24 -08001237 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1238 out << "_hidl_reply);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001239 out.unindent();
1240 out.unindent();
1241
1242 out.unindent();
1243 out << "}\n\n";
1244
Iliyan Malchev549e2592016-08-10 08:59:12 -07001245 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001246
1247 out.unindent();
1248 out << "}\n\n";
1249
1250 return OK;
1251}
1252
1253status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001254 Formatter &out, const Interface *iface, const Method *method) const {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001255 out << "if (!_hidl_data.enforceInterface(";
1256
Yifan Hongc8934042016-11-17 17:10:52 -08001257 out << iface->fqName().cppNamespace()
1258 << "::I"
1259 << iface->getBaseName();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001260
1261 out << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001262
Andreas Huber881227d2016-08-02 14:20:21 -07001263 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001264 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001265 out << "break;\n";
1266 out.unindent();
1267 out << "}\n\n";
1268
Andreas Huber5e44a292016-09-27 14:52:39 -07001269 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001270
Yifan Hongbf459bc2016-08-23 16:50:37 -07001271 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001272 for (const auto &arg : method->args()) {
1273 emitCppReaderWriter(
1274 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001275 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001276 false /* parcelObjIsPointer */,
1277 arg,
1278 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001279 Type::ErrorMode_Break,
1280 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001281 }
1282
Yifan Hongbf459bc2016-08-23 16:50:37 -07001283 // Second DFS: resolve references
1284 for (const auto &arg : method->args()) {
1285 emitCppResolveReferences(
1286 out,
1287 "_hidl_data",
1288 false /* parcelObjIsPointer */,
1289 arg,
1290 true /* reader */,
1291 Type::ErrorMode_Break,
1292 false /* addPrefixToName */);
1293 }
1294
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001295 status_t status = generateCppInstrumentationCall(
1296 out,
1297 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001298 method);
1299 if (status != OK) {
1300 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001301 }
1302
Andreas Huber881227d2016-08-02 14:20:21 -07001303 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001304 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001305
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001306 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001307 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001308 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001309 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001310 << " = "
1311 << "_hidl_mImpl->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001312 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001313
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001314 bool first = true;
1315 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001316 if (!first) {
1317 out << ", ";
1318 }
1319
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001320 if (arg->type().resultNeedsDeref()) {
1321 out << "*";
1322 }
1323
1324 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001325
1326 first = false;
1327 }
1328
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001329 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001330 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1331 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001332
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001333 elidedReturn->type().emitReaderWriter(
1334 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001335 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001336 "_hidl_reply",
1337 true, /* parcelObjIsPointer */
1338 false, /* isReader */
1339 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001340
Yifan Hongbf459bc2016-08-23 16:50:37 -07001341 emitCppResolveReferences(
1342 out,
1343 "_hidl_reply",
1344 true /* parcelObjIsPointer */,
1345 elidedReturn,
1346 false /* reader */,
1347 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001348 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001349
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001350 status_t status = generateCppInstrumentationCall(
1351 out,
1352 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001353 method);
1354 if (status != OK) {
1355 return status;
1356 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001357
Iliyan Malchev549e2592016-08-10 08:59:12 -07001358 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001359 } else {
1360 if (returnsValue) {
1361 out << "bool _hidl_callbackCalled = false;\n\n";
1362 }
Andreas Huber881227d2016-08-02 14:20:21 -07001363
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001364 out << "_hidl_mImpl->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001365
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001366 bool first = true;
1367 for (const auto &arg : method->args()) {
1368 if (!first) {
1369 out << ", ";
1370 }
Andreas Huber881227d2016-08-02 14:20:21 -07001371
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001372 if (arg->type().resultNeedsDeref()) {
1373 out << "*";
1374 }
1375
1376 out << arg->name();
1377
1378 first = false;
1379 }
1380
1381 if (returnsValue) {
1382 if (!first) {
1383 out << ", ";
1384 }
1385
1386 out << "[&](";
1387
1388 first = true;
1389 for (const auto &arg : method->results()) {
1390 if (!first) {
1391 out << ", ";
1392 }
1393
Yifan Honga47eef32016-12-12 10:38:54 -08001394 out << "const auto &_hidl_out_" << arg->name();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001395
1396 first = false;
1397 }
1398
1399 out << ") {\n";
1400 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001401 out << "if (_hidl_callbackCalled) {\n";
1402 out.indent();
1403 out << "LOG_ALWAYS_FATAL(\""
1404 << method->name()
1405 << ": _hidl_cb called a second time, but must be called once.\");\n";
1406 out.unindent();
1407 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001408 out << "_hidl_callbackCalled = true;\n\n";
1409
Yifan Hong859e53f2016-11-14 19:08:24 -08001410 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1411 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001412
Yifan Hongbf459bc2016-08-23 16:50:37 -07001413 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001414 for (const auto &arg : method->results()) {
1415 emitCppReaderWriter(
1416 out,
1417 "_hidl_reply",
1418 true /* parcelObjIsPointer */,
1419 arg,
1420 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001421 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001422 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001423 }
1424
Yifan Hongbf459bc2016-08-23 16:50:37 -07001425 // Second DFS: resolve references
1426 for (const auto &arg : method->results()) {
1427 emitCppResolveReferences(
1428 out,
1429 "_hidl_reply",
1430 true /* parcelObjIsPointer */,
1431 arg,
1432 false /* reader */,
1433 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001434 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001435 }
1436
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001437 status_t status = generateCppInstrumentationCall(
1438 out,
1439 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001440 method);
1441 if (status != OK) {
1442 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001443 }
1444
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001445 out << "_hidl_cb(*_hidl_reply);\n";
1446
1447 out.unindent();
1448 out << "}\n";
1449 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001450 out << ");\n\n";
1451
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001452 if (returnsValue) {
1453 out << "if (!_hidl_callbackCalled) {\n";
1454 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001455 out << "LOG_ALWAYS_FATAL(\""
1456 << method->name()
1457 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001458 out.unindent();
1459 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001460 } else {
1461 out << "::android::hardware::writeToParcel("
1462 << "::android::hardware::Status::ok(), "
1463 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001464 }
Andreas Huber881227d2016-08-02 14:20:21 -07001465 }
1466
1467 out << "break;\n";
1468
1469 return OK;
1470}
1471
Steven Moreland69e7c702016-09-09 11:16:32 -07001472status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1473 std::string ifaceName;
1474 if (!AST::isInterface(&ifaceName)) {
1475 // types.hal does not get a stub header.
1476 return OK;
1477 }
1478
1479 const Interface *iface = mRootScope->getInterface();
1480
1481 const std::string baseName = iface->getBaseName();
1482 const std::string klassName = "Bs" + baseName;
1483
1484 bool supportOneway = iface->hasOnewayMethods();
1485
1486 std::string path = outputPath;
1487 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1488 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1489 path.append(klassName);
1490 path.append(".h");
1491
1492 CHECK(Coordinator::MakeParentHierarchy(path));
1493 FILE *file = fopen(path.c_str(), "w");
1494
1495 if (file == NULL) {
1496 return -errno;
1497 }
1498
1499 Formatter out(file);
1500
1501 const std::string guard = makeHeaderGuard(klassName);
1502
1503 out << "#ifndef " << guard << "\n";
1504 out << "#define " << guard << "\n\n";
1505
1506 std::vector<std::string> packageComponents;
1507 getPackageAndVersionComponents(
1508 &packageComponents, false /* cpp_compatible */);
1509
1510 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001511
1512 generateCppPackageInclude(out, mPackage, ifaceName);
1513 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001514
1515 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001516 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001517 }
1518
1519 enterLeaveNamespace(out, true /* enter */);
1520 out << "\n";
1521
1522 out << "struct "
1523 << klassName
1524 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001525 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001526
1527 out.indent();
1528 out << "explicit "
1529 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001530 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001531 << ifaceName
1532 << "> impl);\n";
1533
Yifan Hong068c5522016-10-31 14:07:25 -07001534 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1535 return generatePassthroughMethod(out, method);
1536 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001537
1538 if (err != OK) {
1539 return err;
1540 }
1541
1542 out.unindent();
1543 out << "private:\n";
1544 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001545 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001546
1547 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001548 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001549
1550 out << "\n";
1551
1552 out << "::android::hardware::Return<void> addOnewayTask("
1553 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001554 }
1555
1556 out.unindent();
1557
1558 out << "};\n\n";
1559
1560 enterLeaveNamespace(out, false /* enter */);
1561
1562 out << "\n#endif // " << guard << "\n";
1563
1564 return OK;
1565}
1566
Yifan Hongfe95aa22016-10-19 17:26:45 -07001567status_t AST::generateInterfaceSource(Formatter &out) const {
1568 const Interface *iface = mRootScope->getInterface();
1569
Yifan Hong2d7126b2016-10-20 15:12:57 -07001570 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001571 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001572
Yifan Hong3d746092016-12-07 14:26:33 -08001573 for (const Interface *superType : iface->typeChain()) {
1574 out << "// static \n"
1575 << childTypeResult
1576 << " I"
1577 << iface->getBaseName()
1578 << "::castFrom("
1579 << superType->getCppArgumentType()
1580 << " parent) {\n";
1581 out.indent();
1582 if (iface == superType) {
1583 out << "return parent;\n";
1584 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001585 out << "return ::android::hardware::castInterface<";
1586 out << "I" << iface->getBaseName() << ", "
1587 << superType->fqName().cppName() << ", "
Martijn Coenena63e0ad2016-12-07 17:29:00 +01001588 << iface->getProxyName().cppLocalName() << ", "
1589 << superType->getProxyName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001590 << ">(\n";
1591 out.indent();
1592 out.indent();
1593 out << "parent, \""
1594 << iface->fqName().string()
1595 << "\");\n";
1596 out.unindent();
1597 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001598 }
Yifan Hong3d746092016-12-07 14:26:33 -08001599 out.unindent();
1600 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001601 }
1602
1603 return OK;
1604}
1605
Steven Moreland69e7c702016-09-09 11:16:32 -07001606status_t AST::generatePassthroughSource(Formatter &out) const {
1607 const Interface *iface = mRootScope->getInterface();
1608
1609 const std::string baseName = iface->getBaseName();
1610 const std::string klassName = "Bs" + baseName;
1611
1612 out << klassName
1613 << "::"
1614 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001615 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001616 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001617 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001618 << iface->fqName().string()
1619 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001620 if (iface->hasOnewayMethods()) {
1621 out << "\n";
1622 out.indentBlock([&] {
1623 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1624 });
1625 }
1626 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001627
1628 if (iface->hasOnewayMethods()) {
1629 out << "::android::hardware::Return<void> "
1630 << klassName
1631 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1632 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001633 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001634 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001635 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1636 out.indent();
1637 out.indent();
1638 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1639 out.unindent();
1640 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001641 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001642 out << "}\n";
1643
Steven Morelandd366c262016-10-11 15:29:10 -07001644 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001645
1646 out.unindent();
1647 out << "}\n\n";
1648
1649
1650 }
1651
1652 return OK;
1653}
1654
Martijn Coenen7b295242016-11-04 16:52:56 +01001655status_t AST::generateCppAtraceCall(Formatter &out,
1656 InstrumentationEvent event,
1657 const Method *method) const {
1658 const Interface *iface = mRootScope->getInterface();
1659 std::string baseString = "HIDL::I" + iface->getBaseName() + "::" + method->name();
1660 switch (event) {
1661 case SERVER_API_ENTRY:
1662 {
1663 out << "atrace_begin(ATRACE_TAG_HAL, \""
1664 << baseString + "::server\");\n";
1665 break;
1666 }
1667 case CLIENT_API_ENTRY:
1668 {
1669 out << "atrace_begin(ATRACE_TAG_HAL, \""
1670 << baseString + "::client\");\n";
1671 break;
1672 }
1673 case PASSTHROUGH_ENTRY:
1674 {
1675 out << "atrace_begin(ATRACE_TAG_HAL, \""
1676 << baseString + "::passthrough\");\n";
1677 break;
1678 }
1679 case SERVER_API_EXIT:
1680 case CLIENT_API_EXIT:
1681 case PASSTHROUGH_EXIT:
1682 {
1683 out << "atrace_end(ATRACE_TAG_HAL);\n";
1684 break;
1685 }
1686 default:
1687 {
1688 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1689 return UNKNOWN_ERROR;
1690 }
1691 }
1692
1693 return OK;
1694}
1695
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001696status_t AST::generateCppInstrumentationCall(
1697 Formatter &out,
1698 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001699 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001700 status_t err = generateCppAtraceCall(out, event, method);
1701 if (err != OK) {
1702 return err;
1703 }
1704
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001705 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1706 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001707 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001708 std::string event_str = "";
1709 switch (event) {
1710 case SERVER_API_ENTRY:
1711 {
1712 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1713 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001714 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001715 << (arg->type().resultNeedsDeref() ? "" : "&")
1716 << arg->name()
1717 << ");\n";
1718 }
1719 break;
1720 }
1721 case SERVER_API_EXIT:
1722 {
1723 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001724 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001725 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001726 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001727 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001728 }
1729 break;
1730 }
1731 case CLIENT_API_ENTRY:
1732 {
1733 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1734 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001735 out << "_hidl_args.push_back((void *)&"
1736 << arg->name()
1737 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001738 }
1739 break;
1740 }
1741 case CLIENT_API_EXIT:
1742 {
1743 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1744 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001745 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001746 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001747 << "_hidl_out_"
1748 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001749 << ");\n";
1750 }
1751 break;
1752 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001753 case PASSTHROUGH_ENTRY:
1754 {
1755 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1756 for (const auto &arg : method->args()) {
1757 out << "_hidl_args.push_back((void *)&"
1758 << arg->name()
1759 << ");\n";
1760 }
1761 break;
1762 }
1763 case PASSTHROUGH_EXIT:
1764 {
1765 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001766 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001767 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001768 << arg->name()
1769 << ");\n";
1770 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001771 break;
1772 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001773 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001774 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001775 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001776 return UNKNOWN_ERROR;
1777 }
1778 }
1779
Steven Moreland031ccf12016-10-31 15:54:38 -07001780 const Interface *iface = mRootScope->getInterface();
1781
Steven Moreland1ab31442016-11-03 18:37:51 -07001782 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001783 out.indent();
1784 out << "callback("
1785 << event_str
1786 << ", \""
1787 << mPackage.package()
1788 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07001789 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001790 << "\", \""
1791 << iface->localName()
1792 << "\", \""
1793 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001794 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001795 out.unindent();
1796 out << "}\n";
1797 out.unindent();
1798 out << "}\n\n";
1799
1800 return OK;
1801}
1802
Andreas Huber881227d2016-08-02 14:20:21 -07001803} // namespace android
1804