blob: 52debfc0e03bd66de0a775602c4353dde4329e03 [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) {
166 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
167 }
168
Martijn Coenen7473fab2016-08-19 14:05:40 +0200169 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700170 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700171
172 if (isInterface) {
Steven Moreland0693f312016-11-09 15:06:14 -0800173 out << "#include <hidl/ServiceManagement.h>\n";
Martijn Coenen93915102016-09-01 01:35:52 +0200174 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700175 }
176
177 out << "#include <utils/NativeHandle.h>\n\n";
178
179 enterLeaveNamespace(out, true /* enter */);
180 out << "\n";
181
182 if (isInterface) {
183 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700184 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700185
186 const Interface *iface = mRootScope->getInterface();
187 const Interface *superType = iface->superType();
188
Steven Moreland40786312016-08-16 10:29:40 -0700189 if (superType == NULL) {
Yifan Hong5bd9aff2016-11-08 18:52:55 -0800190 out << " : virtual public ::android::hardware::IBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700191 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000192 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700193 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700194 }
195
196 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700197
198 out.indent();
199
Andreas Huber881227d2016-08-02 14:20:21 -0700200 }
201
202 status_t err = emitTypeDeclarations(out);
203
204 if (err != OK) {
205 return err;
206 }
207
208 if (isInterface) {
209 const Interface *iface = mRootScope->getInterface();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700210 const Interface *superType = iface->superType();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700211 const std::string baseName = iface->getBaseName();
Steven Moreland19d5c172016-10-20 19:20:25 -0700212 out << "constexpr static ::android::hardware::hidl_version version = {"
Martijn Coenena21f1492016-09-08 15:55:14 +0200213 << mPackage.getPackageMajorVersion() << ","
214 << mPackage.getPackageMinorVersion() << "};\n";
Steven Moreland19d5c172016-10-20 19:20:25 -0700215 out << "virtual const ::android::hardware::hidl_version&"
216 << "getInterfaceVersion() const {\n";
Martijn Coenena21f1492016-09-08 15:55:14 +0200217 out.indent();
218 out << "return version;\n";
219 out.unindent();
220 out << "}\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700221 out << "virtual bool isRemote() const override { return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800222
Andreas Huber881227d2016-08-02 14:20:21 -0700223 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700224 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700225
Andreas Huber881227d2016-08-02 14:20:21 -0700226 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800227 const TypedVar *elidedReturn = method->canElideCallback();
228
229 if (elidedReturn == nullptr && returnsValue) {
230 out << "using "
231 << method->name()
232 << "_cb = std::function<void("
233 << Method::GetArgSignature(method->results(),
234 true /* specify namespaces */)
235 << ")>;\n";
236 }
Andreas Huber881227d2016-08-02 14:20:21 -0700237
Andreas Huber3599d922016-08-09 10:42:57 -0700238 method->dumpAnnotations(out);
239
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700240 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700241 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700242 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700243 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700244 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700245 }
246
247 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700248 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700249 << Method::GetArgSignature(method->args(),
250 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700251
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700252 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700253 if (!method->args().empty()) {
254 out << ", ";
255 }
256
Steven Moreland67f67b42016-09-29 08:59:02 -0700257 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700258 }
259
Yifan Hong10fe0b52016-10-19 14:20:17 -0700260 out << ")";
261 if (method->isHidlReserved()) {
262 out << " override";
263 out << " {\n";
264 out.indent();
265 method->cppImpl(out);
266 out.unindent();
267 out << "\n}\n";
268 } else {
269 out << " = 0;\n";
270 }
Andreas Huber881227d2016-08-02 14:20:21 -0700271 }
Steven Moreland40786312016-08-16 10:29:40 -0700272
Yifan Hongfe95aa22016-10-19 17:26:45 -0700273 if (!iface->isRootType()) {
274 out << "// cast static functions\n";
Yifan Hong3b320f82016-11-01 15:15:54 -0700275 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700276
277 for (const Interface *superType : iface->superTypeChain()) {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700278 out << "static "
279 << childTypeResult
280 << " castFrom("
Yifan Hong3b320f82016-11-01 15:15:54 -0700281 << superType->getCppArgumentType()
Yifan Hongfe95aa22016-10-19 17:26:45 -0700282 << " parent"
Yifan Hongfe95aa22016-10-19 17:26:45 -0700283 << ");\n";
284 }
285 }
286
Steven Morelandd39133b2016-11-11 12:30:08 -0800287 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700288
Steven Moreland0693f312016-11-09 15:06:14 -0800289 out << "DECLARE_SERVICE_MANAGER_INTERACTIONS(" << baseName << ")\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800290
291 out << "private: static int hidlStaticBlock;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700292 }
293
294 if (isInterface) {
295 out.unindent();
296
Andreas Hubere3f769a2016-10-10 10:54:44 -0700297 out << "};\n\n";
298 }
299
300 err = mRootScope->emitGlobalTypeDeclarations(out);
301
302 if (err != OK) {
303 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700304 }
305
306 out << "\n";
307 enterLeaveNamespace(out, false /* enter */);
308
309 out << "\n#endif // " << guard << "\n";
310
311 return OK;
312}
313
Steven Moreland40786312016-08-16 10:29:40 -0700314status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
315 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800316 bool isInterface = AST::isInterface(&ifaceName);
317 const Interface *iface = nullptr;
318 std::string baseName{};
319 std::string klassName{};
320
321 if(isInterface) {
322 iface = mRootScope->getInterface();
323 baseName = iface->getBaseName();
324 klassName = "IHw" + baseName;
325 } else {
326 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700327 }
328
Steven Moreland40786312016-08-16 10:29:40 -0700329 std::string path = outputPath;
330 path.append(mCoordinator->convertPackageRootToPath(mPackage));
331 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
332 path.append(klassName + ".h");
333
Yifan Hong244e82d2016-11-11 11:13:57 -0800334 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700335
336 if (file == NULL) {
337 return -errno;
338 }
339
340 Formatter out(file);
341
342 const std::string guard = makeHeaderGuard(klassName);
343
344 out << "#ifndef " << guard << "\n";
345 out << "#define " << guard << "\n\n";
346
Yifan Hong244e82d2016-11-11 11:13:57 -0800347 if (isInterface) {
348 generateCppPackageInclude(out, mPackage, ifaceName);
349 } else {
350 generateCppPackageInclude(out, mPackage, "types");
351 }
Steven Moreland40786312016-08-16 10:29:40 -0700352
Steven Morelandee88eed2016-10-31 17:49:00 -0700353 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700354
355 for (const auto &item : mImportedNames) {
356 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800357 generateCppPackageInclude(out, item, "hwtypes");
358 } else {
359 generateCppPackageInclude(out, item, "Bn" + item.getInterfaceBaseName());
Steven Moreland40786312016-08-16 10:29:40 -0700360 }
Steven Moreland40786312016-08-16 10:29:40 -0700361 }
362
363 out << "\n";
364
365 out << "#include <hidl/HidlSupport.h>\n";
Martijn Coenen93915102016-09-01 01:35:52 +0200366 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700367 out << "#include <hwbinder/IBinder.h>\n";
368 out << "#include <hwbinder/IInterface.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700369
370 out << "\n";
371
372 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700373
Yifan Hong244e82d2016-11-11 11:13:57 -0800374 if (isInterface) {
375 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700376
Yifan Hong244e82d2016-11-11 11:13:57 -0800377 out << "struct "
378 << klassName
379 << " : public "
380 << ifaceName;
Steven Moreland40786312016-08-16 10:29:40 -0700381
Yifan Hong244e82d2016-11-11 11:13:57 -0800382 const Interface *superType = iface->superType();
Steven Moreland40786312016-08-16 10:29:40 -0700383
Yifan Hong244e82d2016-11-11 11:13:57 -0800384 out << ", public ::android::hardware::IInterface";
Steven Moreland40786312016-08-16 10:29:40 -0700385
Yifan Hong244e82d2016-11-11 11:13:57 -0800386 out << " {\n";
Steven Moreland40786312016-08-16 10:29:40 -0700387
Yifan Hong244e82d2016-11-11 11:13:57 -0800388 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700389
Yifan Hong244e82d2016-11-11 11:13:57 -0800390 out << "DECLARE_HWBINDER_META_INTERFACE(" << baseName << ");\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700391
Yifan Hong244e82d2016-11-11 11:13:57 -0800392 out.unindent();
393
394 out << "};\n\n";
395 }
396
397 status_t err = mRootScope->emitGlobalHwDeclarations(out);
398 if (err != OK) {
399 return err;
400 }
Steven Moreland40786312016-08-16 10:29:40 -0700401
402 enterLeaveNamespace(out, false /* enter */);
403
404 out << "\n#endif // " << guard << "\n";
405
406 return OK;
407}
408
Andreas Huber881227d2016-08-02 14:20:21 -0700409status_t AST::emitTypeDeclarations(Formatter &out) const {
410 return mRootScope->emitTypeDeclarations(out);
411}
412
Steven Morelanda7a421a2016-09-07 08:35:18 -0700413status_t AST::generateStubMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700414 const Method *method) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700415 out << "inline ";
416
Yifan Hong068c5522016-10-31 14:07:25 -0700417 method->generateCppSignature(out);
Steven Morelanda7a421a2016-09-07 08:35:18 -0700418
419 const bool returnsValue = !method->results().empty();
420 const TypedVar *elidedReturn = method->canElideCallback();
421 out << " {\n";
422 out.indent();
423 out << "return mImpl->"
424 << method->name()
425 << "(";
426 bool first = true;
427 for (const auto &arg : method->args()) {
428 if (!first) {
429 out << ", ";
430 }
431 first = false;
432 out << arg->name();
433 }
434 if (returnsValue && elidedReturn == nullptr) {
435 if (!method->args().empty()) {
436 out << ", ";
437 }
438
439 out << "_hidl_cb";
440 }
441 out << ");\n";
442 out.unindent();
443 out << "}";
444
445 out << ";\n";
446
447 return OK;
448}
449
Steven Moreland69e7c702016-09-09 11:16:32 -0700450status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700451 const Method *method) const {
452 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700453
454 out << " {\n";
455 out.indent();
456
457 const bool returnsValue = !method->results().empty();
458 const TypedVar *elidedReturn = method->canElideCallback();
459
Steven Moreland67f67b42016-09-29 08:59:02 -0700460 if (returnsValue && elidedReturn == nullptr) {
461 generateCheckNonNull(out, "_hidl_cb");
462 }
463
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700464 generateCppInstrumentationCall(
465 out,
466 InstrumentationEvent::PASSTHROUGH_ENTRY,
467 method);
468
469 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700470
471 if (method->isOneway()) {
472 out << "addOnewayTask([this";
473 for (const auto &arg : method->args()) {
474 out << ", " << arg->name();
475 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700476 out << "] {\n";
477 out.indent();
478 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700479 }
480
481 out << "mImpl->"
482 << method->name()
483 << "(";
484
485 bool first = true;
486 for (const auto &arg : method->args()) {
487 if (!first) {
488 out << ", ";
489 }
490 first = false;
491 out << arg->name();
492 }
493 if (returnsValue && elidedReturn == nullptr) {
494 if (!method->args().empty()) {
495 out << ", ";
496 }
497
498 out << "_hidl_cb";
499 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700500 out << ");\n\n";
501
502 generateCppInstrumentationCall(
503 out,
504 InstrumentationEvent::PASSTHROUGH_EXIT,
505 method);
Steven Moreland69e7c702016-09-09 11:16:32 -0700506
507 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700508 out.unindent();
509 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700510 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700511
512 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700513
514 out.unindent();
515 out << "}\n";
516
517 return OK;
518}
519
Yifan Hong068c5522016-10-31 14:07:25 -0700520status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700521
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700522 const Interface *iface = mRootScope->getInterface();
523
Yifan Hong10fe0b52016-10-19 14:20:17 -0700524 const Interface *prevIterface = nullptr;
525 for (const auto &tuple : iface->allMethodsFromRoot()) {
526 const Method *method = tuple.method();
527 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700528
Yifan Hong10fe0b52016-10-19 14:20:17 -0700529 if(prevIterface != superInterface) {
530 if (prevIterface != nullptr) {
531 out << "\n";
532 }
533 out << "// Methods from "
534 << superInterface->fullName()
535 << " follow.\n";
536 prevIterface = superInterface;
537 }
Yifan Hong068c5522016-10-31 14:07:25 -0700538 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700539
Yifan Hong10fe0b52016-10-19 14:20:17 -0700540 if (err != OK) {
541 return err;
542 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700543 }
544
Yifan Hong10fe0b52016-10-19 14:20:17 -0700545 out << "\n";
546
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700547 return OK;
548}
549
Andreas Huberb82318c2016-08-02 14:45:54 -0700550status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700551 std::string ifaceName;
552 if (!AST::isInterface(&ifaceName)) {
553 // types.hal does not get a stub header.
554 return OK;
555 }
556
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700557 const Interface *iface = mRootScope->getInterface();
558 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700559 const std::string klassName = "Bn" + baseName;
Andreas Huber881227d2016-08-02 14:20:21 -0700560
Andreas Huberb82318c2016-08-02 14:45:54 -0700561 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700562 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700563 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700564 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700565 path.append(".h");
566
Andreas Huberd2943e12016-08-05 11:59:31 -0700567 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700568 FILE *file = fopen(path.c_str(), "w");
569
570 if (file == NULL) {
571 return -errno;
572 }
573
574 Formatter out(file);
575
Steven Moreland40786312016-08-16 10:29:40 -0700576 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700577
578 out << "#ifndef " << guard << "\n";
579 out << "#define " << guard << "\n\n";
580
Steven Morelandee88eed2016-10-31 17:49:00 -0700581 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
582 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700583
584 enterLeaveNamespace(out, true /* enter */);
585 out << "\n";
586
587 out << "struct "
588 << "Bn"
589 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700590 << " : public ::android::hardware::BnInterface<I"
591 << baseName << ", IHw" << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700592 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700593
594 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700595 out << "explicit Bn"
596 << baseName
597 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
598 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700599 out << "::android::status_t onTransact(\n";
600 out.indent();
601 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700602 out << "uint32_t _hidl_code,\n";
603 out << "const ::android::hardware::Parcel &_hidl_data,\n";
604 out << "::android::hardware::Parcel *_hidl_reply,\n";
605 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700606 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700607 out.unindent();
608 out.unindent();
609
Yifan Hong068c5522016-10-31 14:07:25 -0700610 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
611 return generateStubMethod(out, method);
612 });
Steven Moreland9c387612016-09-07 09:54:26 -0700613
614 if (err != OK) {
615 return err;
616 }
617
Zhuoyao Zhangde578002016-09-07 18:24:17 -0700618
Andreas Huber881227d2016-08-02 14:20:21 -0700619 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700620 out << "};\n\n";
621
622 enterLeaveNamespace(out, false /* enter */);
623
624 out << "\n#endif // " << guard << "\n";
625
626 return OK;
627}
628
Andreas Huberb82318c2016-08-02 14:45:54 -0700629status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700630 std::string ifaceName;
631 if (!AST::isInterface(&ifaceName)) {
632 // types.hal does not get a proxy header.
633 return OK;
634 }
635
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700636 const Interface *iface = mRootScope->getInterface();
637 const std::string baseName = iface->getBaseName();
Andreas Huber881227d2016-08-02 14:20:21 -0700638
Andreas Huberb82318c2016-08-02 14:45:54 -0700639 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700640 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700641 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700642 path.append("Bp");
643 path.append(baseName);
644 path.append(".h");
645
Andreas Huberd2943e12016-08-05 11:59:31 -0700646 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700647 FILE *file = fopen(path.c_str(), "w");
648
649 if (file == NULL) {
650 return -errno;
651 }
652
653 Formatter out(file);
654
655 const std::string guard = makeHeaderGuard("Bp" + baseName);
656
657 out << "#ifndef " << guard << "\n";
658 out << "#define " << guard << "\n\n";
659
660 std::vector<std::string> packageComponents;
661 getPackageAndVersionComponents(
662 &packageComponents, false /* cpp_compatible */);
663
Steven Morelandee88eed2016-10-31 17:49:00 -0700664 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
665 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700666
667 enterLeaveNamespace(out, true /* enter */);
668 out << "\n";
669
670 out << "struct "
671 << "Bp"
672 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700673 << " : public ::android::hardware::BpInterface<IHw"
674 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700675 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700676
677 out.indent();
678
679 out << "explicit Bp"
680 << baseName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700681 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700682 << "\n\n";
683
Yifan Hong10fe0b52016-10-19 14:20:17 -0700684 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700685
Yifan Hong068c5522016-10-31 14:07:25 -0700686 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
687 method->generateCppSignature(out);
688 out << " override;\n";
689 return OK;
690 });
Steven Moreland9c387612016-09-07 09:54:26 -0700691
692 if (err != OK) {
693 return err;
694 }
Andreas Huber881227d2016-08-02 14:20:21 -0700695
696 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700697 out << "};\n\n";
698
699 enterLeaveNamespace(out, false /* enter */);
700
701 out << "\n#endif // " << guard << "\n";
702
703 return OK;
704}
705
Andreas Huberb82318c2016-08-02 14:45:54 -0700706status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700707
Andreas Huberb82318c2016-08-02 14:45:54 -0700708 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700709 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700710 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700711
712 std::string ifaceName;
713 std::string baseName;
714
Yifan Hongfe95aa22016-10-19 17:26:45 -0700715 const Interface *iface = nullptr;
716 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700717 if (!AST::isInterface(&ifaceName)) {
718 baseName = "types";
719 isInterface = false;
720 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700721 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700722 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700723 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700724 }
725
726 path.append(baseName);
727
728 if (baseName != "types") {
729 path.append("All");
730 }
731
732 path.append(".cpp");
733
Andreas Huberd2943e12016-08-05 11:59:31 -0700734 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700735 FILE *file = fopen(path.c_str(), "w");
736
737 if (file == NULL) {
738 return -errno;
739 }
740
741 Formatter out(file);
742
Martijn Coenen7b295242016-11-04 16:52:56 +0100743
744 out << "#include <cutils/trace.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 }
Andreas Huber881227d2016-08-02 14:20:21 -0700758 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700759 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800760 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700761 }
762
763 out << "\n";
764
765 enterLeaveNamespace(out, true /* enter */);
766 out << "\n";
767
768 status_t err = generateTypeSource(out, ifaceName);
769
770 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700771 const Interface *iface = mRootScope->getInterface();
Steven Moreland19d5c172016-10-20 19:20:25 -0700772 out << "constexpr ::android::hardware::hidl_version "
773 << ifaceName
774 << "::version;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700775
776 // need to be put here, generateStubSource is using this.
Steven Morelandd39133b2016-11-11 12:30:08 -0800777 out << "const char* I"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700778 << iface->getBaseName()
779 << "::descriptor(\""
780 << iface->fqName().string()
781 << "\");\n\n";
782
Yifan Hong158655a2016-11-08 12:34:07 -0800783 out << "int I"
784 << iface->getBaseName()
785 << "::hidlStaticBlock = []() -> int {\n";
786 out.indentBlock([&] {
Steven Morelandd39133b2016-11-11 12:30:08 -0800787 out << "::android::hardware::gBnConstructorMap[I"
Yifan Hong158655a2016-11-08 12:34:07 -0800788 << iface->getBaseName()
Steven Morelandd39133b2016-11-11 12:30:08 -0800789 << "::descriptor]\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800790 out.indentBlock(2, [&] {
791 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
792 out.indentBlock([&] {
793 out << "return new Bn"
794 << iface->getBaseName()
795 << "(reinterpret_cast<I"
796 << iface->getBaseName()
797 << " *>(iIntf));\n";
798 });
799 out << "};\n";
800 });
801 out << "return 1;\n";
802 });
803 out << "}();\n\n";
804
Yifan Hongfe95aa22016-10-19 17:26:45 -0700805 err = generateInterfaceSource(out);
806 }
807
808 if (err == OK && isInterface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700809 err = generateProxySource(out, baseName);
810 }
811
812 if (err == OK && isInterface) {
813 err = generateStubSource(out, baseName);
814 }
815
Steven Moreland40786312016-08-16 10:29:40 -0700816 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -0700817 err = generatePassthroughSource(out);
818 }
819
820 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -0700821 const Interface *iface = mRootScope->getInterface();
822
Steven Moreland0693f312016-11-09 15:06:14 -0800823 out << "IMPLEMENT_SERVICE_MANAGER_INTERACTIONS("
Steven Moreland9c387612016-09-07 09:54:26 -0700824 << baseName << ", "
825 << "\"" << iface->fqName().package()
Steven Moreland7e367bf2016-11-04 11:31:41 -0700826 << iface->fqName().atVersion()
827 << "\")\n";
Steven Moreland40786312016-08-16 10:29:40 -0700828 }
829
Andreas Huber881227d2016-08-02 14:20:21 -0700830 enterLeaveNamespace(out, false /* enter */);
831
832 return err;
833}
834
Steven Moreland67f67b42016-09-29 08:59:02 -0700835// static
836void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
837 out << "if (" << nonNull << " == nullptr) {\n";
838 out.indent();
839 out << "return ::android::hardware::Status::fromExceptionCode(\n";
840 out.indent();
841 out.indent();
842 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
843 out.unindent();
844 out.unindent();
845 out.unindent();
846 out << "}\n\n";
847}
848
Andreas Huber881227d2016-08-02 14:20:21 -0700849status_t AST::generateTypeSource(
850 Formatter &out, const std::string &ifaceName) const {
851 return mRootScope->emitTypeDefinitions(out, ifaceName);
852}
853
Andreas Hubere7ff2282016-08-16 13:50:03 -0700854void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -0700855 Formatter &out,
856 const std::vector<TypedVar *> &args,
857 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700858 if (args.empty()) {
859 return;
860 }
861
862 for (const auto &arg : args) {
863 const Type &type = arg->type();
864
Yifan Hong3b320f82016-11-01 15:15:54 -0700865 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700866 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700867 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700868 << ";\n";
869 }
870
871 out << "\n";
872}
873
Andreas Huber881227d2016-08-02 14:20:21 -0700874void AST::emitCppReaderWriter(
875 Formatter &out,
876 const std::string &parcelObj,
877 bool parcelObjIsPointer,
878 const TypedVar *arg,
879 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -0700880 Type::ErrorMode mode,
881 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700882 const Type &type = arg->type();
883
Andreas Huber881227d2016-08-02 14:20:21 -0700884 type.emitReaderWriter(
885 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700886 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700887 parcelObj,
888 parcelObjIsPointer,
889 isReader,
890 mode);
891}
892
Yifan Hongbf459bc2016-08-23 16:50:37 -0700893void AST::emitCppResolveReferences(
894 Formatter &out,
895 const std::string &parcelObj,
896 bool parcelObjIsPointer,
897 const TypedVar *arg,
898 bool isReader,
899 Type::ErrorMode mode,
900 bool addPrefixToName) const {
901 const Type &type = arg->type();
902 if(type.needsResolveReferences()) {
903 type.emitResolveReferences(
904 out,
905 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
906 isReader, // nameIsPointer
907 parcelObj,
908 parcelObjIsPointer,
909 isReader,
910 mode);
911 }
912}
913
Yifan Hong068c5522016-10-31 14:07:25 -0700914status_t AST::generateProxyMethodSource(Formatter &out,
915 const std::string &klassName,
916 const Method *method,
917 const Interface *superInterface) const {
918
919 method->generateCppSignature(out,
920 klassName,
921 true /* specify namespaces */);
922
923 const bool returnsValue = !method->results().empty();
924 const TypedVar *elidedReturn = method->canElideCallback();
925
Steven Moreland41c6d2e2016-11-07 12:26:54 -0800926 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700927
928 out.indent();
929
930 if (returnsValue && elidedReturn == nullptr) {
931 generateCheckNonNull(out, "_hidl_cb");
932 }
933
934 status_t status = generateCppInstrumentationCall(
935 out,
936 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -0700937 method);
938 if (status != OK) {
939 return status;
940 }
941
942 out << "::android::hardware::Parcel _hidl_data;\n";
943 out << "::android::hardware::Parcel _hidl_reply;\n";
944 out << "::android::status_t _hidl_err;\n";
945 out << "::android::hardware::Status _hidl_status;\n\n";
946
947 declareCppReaderLocals(
948 out, method->results(), true /* forResults */);
949
950 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Steven Morelandd39133b2016-11-11 12:30:08 -0800951 if (method->isHidlReserved()) {
Yifan Hong5bd9aff2016-11-08 18:52:55 -0800952 out << "::android::hardware::IBase";
Steven Morelandd39133b2016-11-11 12:30:08 -0800953 } else {
954 out << superInterface->fqName().cppNamespace()
955 << "::I"
956 << superInterface->getBaseName();
Yifan Hong068c5522016-10-31 14:07:25 -0700957 }
958 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700959 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
960
961 // First DFS: write all buffers and resolve pointers for parent
962 for (const auto &arg : method->args()) {
963 emitCppReaderWriter(
964 out,
965 "_hidl_data",
966 false /* parcelObjIsPointer */,
967 arg,
968 false /* reader */,
969 Type::ErrorMode_Goto,
970 false /* addPrefixToName */);
971 }
972
973 // Second DFS: resolve references.
974 for (const auto &arg : method->args()) {
975 emitCppResolveReferences(
976 out,
977 "_hidl_data",
978 false /* parcelObjIsPointer */,
979 arg,
980 false /* reader */,
981 Type::ErrorMode_Goto,
982 false /* addPrefixToName */);
983 }
984
985 out << "_hidl_err = remote()->transact("
986 << method->getSerialId()
987 << " /* "
988 << method->name()
989 << " */, _hidl_data, &_hidl_reply";
990
991 if (method->isOneway()) {
992 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
993 }
994 out << ");\n";
995
996 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
997
998 if (!method->isOneway()) {
999 out << "_hidl_err = _hidl_status.readFromParcel(_hidl_reply);\n";
1000 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1001 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1002
1003
1004 // First DFS: write all buffers and resolve pointers for parent
1005 for (const auto &arg : method->results()) {
1006 emitCppReaderWriter(
1007 out,
1008 "_hidl_reply",
1009 false /* parcelObjIsPointer */,
1010 arg,
1011 true /* reader */,
1012 Type::ErrorMode_Goto,
1013 true /* addPrefixToName */);
1014 }
1015
1016 // Second DFS: resolve references.
1017 for (const auto &arg : method->results()) {
1018 emitCppResolveReferences(
1019 out,
1020 "_hidl_reply",
1021 false /* parcelObjIsPointer */,
1022 arg,
1023 true /* reader */,
1024 Type::ErrorMode_Goto,
1025 true /* addPrefixToName */);
1026 }
1027
1028 if (returnsValue && elidedReturn == nullptr) {
1029 out << "_hidl_cb(";
1030
1031 bool first = true;
1032 for (const auto &arg : method->results()) {
1033 if (!first) {
1034 out << ", ";
1035 }
1036
1037 if (arg->type().resultNeedsDeref()) {
1038 out << "*";
1039 }
1040 out << "_hidl_out_" << arg->name();
1041
1042 first = false;
1043 }
1044
1045 out << ");\n\n";
1046 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001047 }
1048 status = generateCppInstrumentationCall(
1049 out,
1050 InstrumentationEvent::CLIENT_API_EXIT,
1051 method);
1052 if (status != OK) {
1053 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001054 }
1055
1056 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001057 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1058 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001059 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001060 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1061 } else {
1062 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1063 out << "return ::android::hardware::Return<void>();\n\n";
1064 }
1065
1066 out.unindent();
1067 out << "_hidl_error:\n";
1068 out.indent();
1069 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1070 out << "return ::android::hardware::Return<";
1071 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001072 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001073 } else {
1074 out << "void";
1075 }
1076 out << ">(_hidl_status);\n";
1077
1078 out.unindent();
1079 out << "}\n\n";
1080 return OK;
1081}
1082
Andreas Huber881227d2016-08-02 14:20:21 -07001083status_t AST::generateProxySource(
1084 Formatter &out, const std::string &baseName) const {
1085 const std::string klassName = "Bp" + baseName;
1086
1087 out << klassName
1088 << "::"
1089 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001090 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001091
1092 out.indent();
1093 out.indent();
1094
1095 out << ": BpInterface"
Steven Moreland40786312016-08-16 10:29:40 -07001096 << "<IHw"
Andreas Huber881227d2016-08-02 14:20:21 -07001097 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001098 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001099 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001100 << mPackage.string()
1101 << "::I"
1102 << baseName
1103 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001104
Andreas Huber881227d2016-08-02 14:20:21 -07001105 out.unindent();
1106 out.unindent();
1107 out << "}\n\n";
1108
Yifan Hong068c5522016-10-31 14:07:25 -07001109 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1110 return generateProxyMethodSource(out, klassName, method, superInterface);
1111 });
Andreas Huber881227d2016-08-02 14:20:21 -07001112
Yifan Hong068c5522016-10-31 14:07:25 -07001113 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001114}
1115
1116status_t AST::generateStubSource(
1117 Formatter &out, const std::string &baseName) const {
1118 out << "IMPLEMENT_HWBINDER_META_INTERFACE("
1119 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001120 << ", "
1121 << mPackage.cppNamespace()
Andreas Huber881227d2016-08-02 14:20:21 -07001122 << "::I"
1123 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001124 << "::descriptor);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001125
1126 const std::string klassName = "Bn" + baseName;
1127
Steven Moreland40786312016-08-16 10:29:40 -07001128 out << klassName
1129 << "::"
1130 << klassName
1131 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl)\n";
1132
1133 out.indent();
1134 out.indent();
1135
1136 out << ": BnInterface"
1137 << "<I"
1138 << baseName
1139 << ", IHw"
1140 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001141 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001142 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001143 << mPackage.string()
1144 << "::I"
1145 << baseName
1146 << "\") {\n";
Steven Moreland40786312016-08-16 10:29:40 -07001147
1148 out.unindent();
1149 out.unindent();
1150 out << "}\n\n";
1151
Andreas Huber881227d2016-08-02 14:20:21 -07001152 out << "::android::status_t " << klassName << "::onTransact(\n";
1153
1154 out.indent();
1155 out.indent();
1156
Iliyan Malchev549e2592016-08-10 08:59:12 -07001157 out << "uint32_t _hidl_code,\n"
1158 << "const ::android::hardware::Parcel &_hidl_data,\n"
1159 << "::android::hardware::Parcel *_hidl_reply,\n"
1160 << "uint32_t _hidl_flags,\n"
1161 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001162
1163 out.unindent();
1164
Iliyan Malchev549e2592016-08-10 08:59:12 -07001165 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001166 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001167 out.indent();
1168
1169 const Interface *iface = mRootScope->getInterface();
1170
Yifan Hong10fe0b52016-10-19 14:20:17 -07001171 for (const auto &tuple : iface->allMethodsFromRoot()) {
1172 const Method *method = tuple.method();
1173 const Interface *superInterface = tuple.interface();
1174 out << "case "
1175 << method->getSerialId()
1176 << " /* "
1177 << method->name()
1178 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001179
Yifan Hong10fe0b52016-10-19 14:20:17 -07001180 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001181
Yifan Hong10fe0b52016-10-19 14:20:17 -07001182 status_t err =
1183 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001184
Yifan Hong10fe0b52016-10-19 14:20:17 -07001185 if (err != OK) {
1186 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001187 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001188
1189 out.unindent();
1190 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001191 }
1192
1193 out << "default:\n{\n";
1194 out.indent();
1195
Andreas Huber8a82ff72016-08-04 10:29:39 -07001196 out << "return ::android::hardware::BnInterface<I"
Steven Moreland40786312016-08-16 10:29:40 -07001197 << baseName << ", IHw" << baseName
Andreas Huber881227d2016-08-02 14:20:21 -07001198 << ">::onTransact(\n";
1199
1200 out.indent();
1201 out.indent();
1202
Iliyan Malchev549e2592016-08-10 08:59:12 -07001203 out << "_hidl_code, _hidl_data, _hidl_reply, "
1204 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001205
1206 out.unindent();
1207 out.unindent();
1208
1209 out.unindent();
1210 out << "}\n";
1211
1212 out.unindent();
1213 out << "}\n\n";
1214
Iliyan Malchev549e2592016-08-10 08:59:12 -07001215 out << "if (_hidl_err == ::android::UNEXPECTED_NULL) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001216 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001217 out << "_hidl_err = ::android::hardware::Status::fromExceptionCode(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001218 out.indent();
1219 out.indent();
Andreas Huber8a82ff72016-08-04 10:29:39 -07001220 out << "::android::hardware::Status::EX_NULL_POINTER)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001221 out.indent();
1222 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001223 out << ".writeToParcel(_hidl_reply);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001224 out.unindent();
1225 out.unindent();
1226 out.unindent();
1227 out.unindent();
1228
1229 out.unindent();
1230 out << "}\n\n";
1231
Iliyan Malchev549e2592016-08-10 08:59:12 -07001232 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001233
1234 out.unindent();
1235 out << "}\n\n";
1236
1237 return OK;
1238}
1239
1240status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001241 Formatter &out, const Interface *iface, const Method *method) const {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001242 out << "if (!_hidl_data.enforceInterface(";
1243
Steven Morelandd39133b2016-11-11 12:30:08 -08001244 if (method->isHidlReserved()) {
Yifan Hong5bd9aff2016-11-08 18:52:55 -08001245 out << "::android::hardware::IBase";
Steven Morelandd39133b2016-11-11 12:30:08 -08001246 } else {
1247 out << iface->fqName().cppNamespace()
1248 << "::I"
1249 << iface->getBaseName();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001250 }
1251
1252 out << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001253
Andreas Huber881227d2016-08-02 14:20:21 -07001254 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001255 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001256 out << "break;\n";
1257 out.unindent();
1258 out << "}\n\n";
1259
Andreas Huber5e44a292016-09-27 14:52:39 -07001260 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001261
Yifan Hongbf459bc2016-08-23 16:50:37 -07001262 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001263 for (const auto &arg : method->args()) {
1264 emitCppReaderWriter(
1265 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001266 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001267 false /* parcelObjIsPointer */,
1268 arg,
1269 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001270 Type::ErrorMode_Break,
1271 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001272 }
1273
Yifan Hongbf459bc2016-08-23 16:50:37 -07001274 // Second DFS: resolve references
1275 for (const auto &arg : method->args()) {
1276 emitCppResolveReferences(
1277 out,
1278 "_hidl_data",
1279 false /* parcelObjIsPointer */,
1280 arg,
1281 true /* reader */,
1282 Type::ErrorMode_Break,
1283 false /* addPrefixToName */);
1284 }
1285
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001286 status_t status = generateCppInstrumentationCall(
1287 out,
1288 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001289 method);
1290 if (status != OK) {
1291 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001292 }
1293
Andreas Huber881227d2016-08-02 14:20:21 -07001294 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001295 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001296
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001297 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001298 out << elidedReturn->type().getCppResultType()
1299 << " "
1300 << elidedReturn->name()
1301 << " = "
1302 << method->name()
1303 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001304
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001305 bool first = true;
1306 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001307 if (!first) {
1308 out << ", ";
1309 }
1310
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001311 if (arg->type().resultNeedsDeref()) {
1312 out << "*";
1313 }
1314
1315 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001316
1317 first = false;
1318 }
1319
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001320 out << ");\n\n";
Andreas Huber8a82ff72016-08-04 10:29:39 -07001321 out << "::android::hardware::Status::ok()"
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001322 << ".writeToParcel(_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001323
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001324 elidedReturn->type().emitReaderWriter(
1325 out,
1326 elidedReturn->name(),
1327 "_hidl_reply",
1328 true, /* parcelObjIsPointer */
1329 false, /* isReader */
1330 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001331
Yifan Hongbf459bc2016-08-23 16:50:37 -07001332 emitCppResolveReferences(
1333 out,
1334 "_hidl_reply",
1335 true /* parcelObjIsPointer */,
1336 elidedReturn,
1337 false /* reader */,
1338 Type::ErrorMode_Ignore,
1339 false /* addPrefixToName */);
1340
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001341 status_t status = generateCppInstrumentationCall(
1342 out,
1343 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001344 method);
1345 if (status != OK) {
1346 return status;
1347 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001348
Iliyan Malchev549e2592016-08-10 08:59:12 -07001349 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001350 } else {
1351 if (returnsValue) {
1352 out << "bool _hidl_callbackCalled = false;\n\n";
1353 }
Andreas Huber881227d2016-08-02 14:20:21 -07001354
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001355 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001356
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001357 bool first = true;
1358 for (const auto &arg : method->args()) {
1359 if (!first) {
1360 out << ", ";
1361 }
Andreas Huber881227d2016-08-02 14:20:21 -07001362
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001363 if (arg->type().resultNeedsDeref()) {
1364 out << "*";
1365 }
1366
1367 out << arg->name();
1368
1369 first = false;
1370 }
1371
1372 if (returnsValue) {
1373 if (!first) {
1374 out << ", ";
1375 }
1376
1377 out << "[&](";
1378
1379 first = true;
1380 for (const auto &arg : method->results()) {
1381 if (!first) {
1382 out << ", ";
1383 }
1384
1385 out << "const auto &" << arg->name();
1386
1387 first = false;
1388 }
1389
1390 out << ") {\n";
1391 out.indent();
1392 out << "_hidl_callbackCalled = true;\n\n";
1393
1394 out << "::android::hardware::Status::ok()"
1395 << ".writeToParcel(_hidl_reply);\n\n";
1396
Yifan Hongbf459bc2016-08-23 16:50:37 -07001397 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001398 for (const auto &arg : method->results()) {
1399 emitCppReaderWriter(
1400 out,
1401 "_hidl_reply",
1402 true /* parcelObjIsPointer */,
1403 arg,
1404 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001405 Type::ErrorMode_Ignore,
1406 false /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001407 }
1408
Yifan Hongbf459bc2016-08-23 16:50:37 -07001409 // Second DFS: resolve references
1410 for (const auto &arg : method->results()) {
1411 emitCppResolveReferences(
1412 out,
1413 "_hidl_reply",
1414 true /* parcelObjIsPointer */,
1415 arg,
1416 false /* reader */,
1417 Type::ErrorMode_Ignore,
1418 false /* addPrefixToName */);
1419 }
1420
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001421 status_t status = generateCppInstrumentationCall(
1422 out,
1423 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001424 method);
1425 if (status != OK) {
1426 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001427 }
1428
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001429 out << "_hidl_cb(*_hidl_reply);\n";
1430
1431 out.unindent();
1432 out << "}\n";
1433 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001434 out << ");\n\n";
1435
1436 // What to do if the stub implementation has a synchronous callback
1437 // which does not get invoked? This is not a transport error but a
1438 // service error of sorts. For now, return OK to the caller, as this is
1439 // not a transport error.
1440 //
1441 // TODO(b/31365311) Figure out how to deal with this later.
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001442
1443 if (returnsValue) {
1444 out << "if (!_hidl_callbackCalled) {\n";
1445 out.indent();
1446 }
1447
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001448 out << "::android::hardware::Status::ok()"
1449 << ".writeToParcel(_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001450
1451 if (returnsValue) {
1452 out.unindent();
1453 out << "}\n\n";
1454 }
Andreas Huber881227d2016-08-02 14:20:21 -07001455 }
1456
1457 out << "break;\n";
1458
1459 return OK;
1460}
1461
Steven Moreland69e7c702016-09-09 11:16:32 -07001462status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1463 std::string ifaceName;
1464 if (!AST::isInterface(&ifaceName)) {
1465 // types.hal does not get a stub header.
1466 return OK;
1467 }
1468
1469 const Interface *iface = mRootScope->getInterface();
1470
1471 const std::string baseName = iface->getBaseName();
1472 const std::string klassName = "Bs" + baseName;
1473
1474 bool supportOneway = iface->hasOnewayMethods();
1475
1476 std::string path = outputPath;
1477 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1478 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1479 path.append(klassName);
1480 path.append(".h");
1481
1482 CHECK(Coordinator::MakeParentHierarchy(path));
1483 FILE *file = fopen(path.c_str(), "w");
1484
1485 if (file == NULL) {
1486 return -errno;
1487 }
1488
1489 Formatter out(file);
1490
1491 const std::string guard = makeHeaderGuard(klassName);
1492
1493 out << "#ifndef " << guard << "\n";
1494 out << "#define " << guard << "\n\n";
1495
1496 std::vector<std::string> packageComponents;
1497 getPackageAndVersionComponents(
1498 &packageComponents, false /* cpp_compatible */);
1499
1500 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001501
1502 generateCppPackageInclude(out, mPackage, ifaceName);
1503 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001504
1505 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001506 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001507 }
1508
1509 enterLeaveNamespace(out, true /* enter */);
1510 out << "\n";
1511
1512 out << "struct "
1513 << klassName
1514 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001515 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001516
1517 out.indent();
1518 out << "explicit "
1519 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001520 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001521 << ifaceName
1522 << "> impl);\n";
1523
Yifan Hong068c5522016-10-31 14:07:25 -07001524 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1525 return generatePassthroughMethod(out, method);
1526 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001527
1528 if (err != OK) {
1529 return err;
1530 }
1531
1532 out.unindent();
1533 out << "private:\n";
1534 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001535 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001536
1537 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001538 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001539
1540 out << "\n";
1541
1542 out << "::android::hardware::Return<void> addOnewayTask("
1543 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001544 }
1545
1546 out.unindent();
1547
1548 out << "};\n\n";
1549
1550 enterLeaveNamespace(out, false /* enter */);
1551
1552 out << "\n#endif // " << guard << "\n";
1553
1554 return OK;
1555}
1556
Yifan Hongfe95aa22016-10-19 17:26:45 -07001557status_t AST::generateInterfaceSource(Formatter &out) const {
1558 const Interface *iface = mRootScope->getInterface();
1559
Yifan Hong2d7126b2016-10-20 15:12:57 -07001560 // generate castFrom functions
Yifan Hongfe95aa22016-10-19 17:26:45 -07001561 if (!iface->isRootType()) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001562 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001563
1564 for (const Interface *superType : iface->superTypeChain()) {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001565 out << "// static \n"
1566 << childTypeResult
1567 << " I"
1568 << iface->getBaseName()
1569 << "::castFrom("
Yifan Hong3b320f82016-11-01 15:15:54 -07001570 << superType->getCppArgumentType()
1571 << " parent) {\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001572 out.indent();
1573 out << "return ::android::hardware::castInterface<";
1574 out << "I" << iface->getBaseName() << ", "
1575 << superType->fqName().cppName() << ", "
Yifan Hong158655a2016-11-08 12:34:07 -08001576 << "Bp" << iface->getBaseName() << ", "
1577 << superType->getHwName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001578 << ">(\n";
1579 out.indent();
1580 out.indent();
1581 out << "parent, \""
1582 << iface->fqName().string()
1583 << "\");\n";
1584 out.unindent();
1585 out.unindent();
1586 out.unindent();
1587 out << "}\n\n";
1588 }
1589 }
1590
1591 return OK;
1592}
1593
Steven Moreland69e7c702016-09-09 11:16:32 -07001594status_t AST::generatePassthroughSource(Formatter &out) const {
1595 const Interface *iface = mRootScope->getInterface();
1596
1597 const std::string baseName = iface->getBaseName();
1598 const std::string klassName = "Bs" + baseName;
1599
1600 out << klassName
1601 << "::"
1602 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001603 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001604 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001605 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001606 << iface->fqName().string()
1607 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001608 if (iface->hasOnewayMethods()) {
1609 out << "\n";
1610 out.indentBlock([&] {
1611 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1612 });
1613 }
1614 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001615
1616 if (iface->hasOnewayMethods()) {
1617 out << "::android::hardware::Return<void> "
1618 << klassName
1619 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1620 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001621 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001622 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001623 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1624 out.indent();
1625 out.indent();
1626 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1627 out.unindent();
1628 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001629 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001630 out << "}\n";
1631
Steven Morelandd366c262016-10-11 15:29:10 -07001632 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001633
1634 out.unindent();
1635 out << "}\n\n";
1636
1637
1638 }
1639
1640 return OK;
1641}
1642
Martijn Coenen7b295242016-11-04 16:52:56 +01001643status_t AST::generateCppAtraceCall(Formatter &out,
1644 InstrumentationEvent event,
1645 const Method *method) const {
1646 const Interface *iface = mRootScope->getInterface();
1647 std::string baseString = "HIDL::I" + iface->getBaseName() + "::" + method->name();
1648 switch (event) {
1649 case SERVER_API_ENTRY:
1650 {
1651 out << "atrace_begin(ATRACE_TAG_HAL, \""
1652 << baseString + "::server\");\n";
1653 break;
1654 }
1655 case CLIENT_API_ENTRY:
1656 {
1657 out << "atrace_begin(ATRACE_TAG_HAL, \""
1658 << baseString + "::client\");\n";
1659 break;
1660 }
1661 case PASSTHROUGH_ENTRY:
1662 {
1663 out << "atrace_begin(ATRACE_TAG_HAL, \""
1664 << baseString + "::passthrough\");\n";
1665 break;
1666 }
1667 case SERVER_API_EXIT:
1668 case CLIENT_API_EXIT:
1669 case PASSTHROUGH_EXIT:
1670 {
1671 out << "atrace_end(ATRACE_TAG_HAL);\n";
1672 break;
1673 }
1674 default:
1675 {
1676 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1677 return UNKNOWN_ERROR;
1678 }
1679 }
1680
1681 return OK;
1682}
1683
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001684status_t AST::generateCppInstrumentationCall(
1685 Formatter &out,
1686 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001687 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001688 status_t err = generateCppAtraceCall(out, event, method);
1689 if (err != OK) {
1690 return err;
1691 }
1692
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001693 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1694 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001695 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001696 std::string event_str = "";
1697 switch (event) {
1698 case SERVER_API_ENTRY:
1699 {
1700 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1701 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001702 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001703 << (arg->type().resultNeedsDeref() ? "" : "&")
1704 << arg->name()
1705 << ");\n";
1706 }
1707 break;
1708 }
1709 case SERVER_API_EXIT:
1710 {
1711 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001712 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001713 out << "_hidl_args.push_back((void *)&"
Steven Moreland031ccf12016-10-31 15:54:38 -07001714 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001715 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001716 }
1717 break;
1718 }
1719 case CLIENT_API_ENTRY:
1720 {
1721 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1722 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001723 out << "_hidl_args.push_back((void *)&"
1724 << arg->name()
1725 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001726 }
1727 break;
1728 }
1729 case CLIENT_API_EXIT:
1730 {
1731 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1732 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001733 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001734 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001735 << "_hidl_out_"
1736 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001737 << ");\n";
1738 }
1739 break;
1740 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001741 case PASSTHROUGH_ENTRY:
1742 {
1743 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1744 for (const auto &arg : method->args()) {
1745 out << "_hidl_args.push_back((void *)&"
1746 << arg->name()
1747 << ");\n";
1748 }
1749 break;
1750 }
1751 case PASSTHROUGH_EXIT:
1752 {
1753 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
1754 // TODO(b/32576620): passthrough return values
1755 break;
1756 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001757 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001758 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001759 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001760 return UNKNOWN_ERROR;
1761 }
1762 }
1763
Steven Moreland031ccf12016-10-31 15:54:38 -07001764 const Interface *iface = mRootScope->getInterface();
1765
Steven Moreland1ab31442016-11-03 18:37:51 -07001766 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001767 out.indent();
1768 out << "callback("
1769 << event_str
1770 << ", \""
1771 << mPackage.package()
1772 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07001773 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001774 << "\", \""
1775 << iface->localName()
1776 << "\", \""
1777 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001778 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001779 out.unindent();
1780 out << "}\n";
1781 out.unindent();
1782 out << "}\n\n";
1783
1784 return OK;
1785}
1786
Andreas Huber881227d2016-08-02 14:20:21 -07001787} // namespace android
1788