blob: b659f7b1f3eadf9222a64383e1936bd637415ed7 [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
Andreas Huber881227d2016-08-02 14:20:21 -0700743 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700744 // This is a no-op for IServiceManager itself.
745 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
746
Steven Morelandee88eed2016-10-31 17:49:00 -0700747 generateCppPackageInclude(out, mPackage, "Bp" + baseName);
748 generateCppPackageInclude(out, mPackage, "Bn" + baseName);
749 generateCppPackageInclude(out, mPackage, "Bs" + baseName);
Yifan Hongfe95aa22016-10-19 17:26:45 -0700750
751 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700752 generateCppPackageInclude(out,
753 superType->fqName(),
754 "Bp" + superType->getBaseName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700755 }
Andreas Huber881227d2016-08-02 14:20:21 -0700756 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700757 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800758 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700759 }
760
761 out << "\n";
762
763 enterLeaveNamespace(out, true /* enter */);
764 out << "\n";
765
766 status_t err = generateTypeSource(out, ifaceName);
767
768 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700769 const Interface *iface = mRootScope->getInterface();
Steven Moreland19d5c172016-10-20 19:20:25 -0700770 out << "constexpr ::android::hardware::hidl_version "
771 << ifaceName
772 << "::version;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700773
774 // need to be put here, generateStubSource is using this.
Steven Morelandd39133b2016-11-11 12:30:08 -0800775 out << "const char* I"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700776 << iface->getBaseName()
777 << "::descriptor(\""
778 << iface->fqName().string()
779 << "\");\n\n";
780
Yifan Hong158655a2016-11-08 12:34:07 -0800781 out << "int I"
782 << iface->getBaseName()
783 << "::hidlStaticBlock = []() -> int {\n";
784 out.indentBlock([&] {
Steven Morelandd39133b2016-11-11 12:30:08 -0800785 out << "::android::hardware::gBnConstructorMap[I"
Yifan Hong158655a2016-11-08 12:34:07 -0800786 << iface->getBaseName()
Steven Morelandd39133b2016-11-11 12:30:08 -0800787 << "::descriptor]\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800788 out.indentBlock(2, [&] {
789 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
790 out.indentBlock([&] {
791 out << "return new Bn"
792 << iface->getBaseName()
793 << "(reinterpret_cast<I"
794 << iface->getBaseName()
795 << " *>(iIntf));\n";
796 });
797 out << "};\n";
798 });
799 out << "return 1;\n";
800 });
801 out << "}();\n\n";
802
Yifan Hongfe95aa22016-10-19 17:26:45 -0700803 err = generateInterfaceSource(out);
804 }
805
806 if (err == OK && isInterface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700807 err = generateProxySource(out, baseName);
808 }
809
810 if (err == OK && isInterface) {
811 err = generateStubSource(out, baseName);
812 }
813
Steven Moreland40786312016-08-16 10:29:40 -0700814 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -0700815 err = generatePassthroughSource(out);
816 }
817
818 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -0700819 const Interface *iface = mRootScope->getInterface();
820
Steven Moreland0693f312016-11-09 15:06:14 -0800821 out << "IMPLEMENT_SERVICE_MANAGER_INTERACTIONS("
Steven Moreland9c387612016-09-07 09:54:26 -0700822 << baseName << ", "
823 << "\"" << iface->fqName().package()
Steven Moreland7e367bf2016-11-04 11:31:41 -0700824 << iface->fqName().atVersion()
825 << "\")\n";
Steven Moreland40786312016-08-16 10:29:40 -0700826 }
827
Andreas Huber881227d2016-08-02 14:20:21 -0700828 enterLeaveNamespace(out, false /* enter */);
829
830 return err;
831}
832
Steven Moreland67f67b42016-09-29 08:59:02 -0700833// static
834void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
835 out << "if (" << nonNull << " == nullptr) {\n";
836 out.indent();
837 out << "return ::android::hardware::Status::fromExceptionCode(\n";
838 out.indent();
839 out.indent();
840 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
841 out.unindent();
842 out.unindent();
843 out.unindent();
844 out << "}\n\n";
845}
846
Andreas Huber881227d2016-08-02 14:20:21 -0700847status_t AST::generateTypeSource(
848 Formatter &out, const std::string &ifaceName) const {
849 return mRootScope->emitTypeDefinitions(out, ifaceName);
850}
851
Andreas Hubere7ff2282016-08-16 13:50:03 -0700852void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -0700853 Formatter &out,
854 const std::vector<TypedVar *> &args,
855 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700856 if (args.empty()) {
857 return;
858 }
859
860 for (const auto &arg : args) {
861 const Type &type = arg->type();
862
Yifan Hong3b320f82016-11-01 15:15:54 -0700863 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700864 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700865 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700866 << ";\n";
867 }
868
869 out << "\n";
870}
871
Andreas Huber881227d2016-08-02 14:20:21 -0700872void AST::emitCppReaderWriter(
873 Formatter &out,
874 const std::string &parcelObj,
875 bool parcelObjIsPointer,
876 const TypedVar *arg,
877 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -0700878 Type::ErrorMode mode,
879 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700880 const Type &type = arg->type();
881
Andreas Huber881227d2016-08-02 14:20:21 -0700882 type.emitReaderWriter(
883 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700884 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700885 parcelObj,
886 parcelObjIsPointer,
887 isReader,
888 mode);
889}
890
Yifan Hongbf459bc2016-08-23 16:50:37 -0700891void AST::emitCppResolveReferences(
892 Formatter &out,
893 const std::string &parcelObj,
894 bool parcelObjIsPointer,
895 const TypedVar *arg,
896 bool isReader,
897 Type::ErrorMode mode,
898 bool addPrefixToName) const {
899 const Type &type = arg->type();
900 if(type.needsResolveReferences()) {
901 type.emitResolveReferences(
902 out,
903 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
904 isReader, // nameIsPointer
905 parcelObj,
906 parcelObjIsPointer,
907 isReader,
908 mode);
909 }
910}
911
Yifan Hong068c5522016-10-31 14:07:25 -0700912status_t AST::generateProxyMethodSource(Formatter &out,
913 const std::string &klassName,
914 const Method *method,
915 const Interface *superInterface) const {
916
917 method->generateCppSignature(out,
918 klassName,
919 true /* specify namespaces */);
920
921 const bool returnsValue = !method->results().empty();
922 const TypedVar *elidedReturn = method->canElideCallback();
923
Steven Moreland41c6d2e2016-11-07 12:26:54 -0800924 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700925
926 out.indent();
927
928 if (returnsValue && elidedReturn == nullptr) {
929 generateCheckNonNull(out, "_hidl_cb");
930 }
931
932 status_t status = generateCppInstrumentationCall(
933 out,
934 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -0700935 method);
936 if (status != OK) {
937 return status;
938 }
939
940 out << "::android::hardware::Parcel _hidl_data;\n";
941 out << "::android::hardware::Parcel _hidl_reply;\n";
942 out << "::android::status_t _hidl_err;\n";
943 out << "::android::hardware::Status _hidl_status;\n\n";
944
945 declareCppReaderLocals(
946 out, method->results(), true /* forResults */);
947
948 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Steven Morelandd39133b2016-11-11 12:30:08 -0800949 if (method->isHidlReserved()) {
Yifan Hong5bd9aff2016-11-08 18:52:55 -0800950 out << "::android::hardware::IBase";
Steven Morelandd39133b2016-11-11 12:30:08 -0800951 } else {
952 out << superInterface->fqName().cppNamespace()
953 << "::I"
954 << superInterface->getBaseName();
Yifan Hong068c5522016-10-31 14:07:25 -0700955 }
956 out << "::descriptor);\n";
957
958 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
959
960 // First DFS: write all buffers and resolve pointers for parent
961 for (const auto &arg : method->args()) {
962 emitCppReaderWriter(
963 out,
964 "_hidl_data",
965 false /* parcelObjIsPointer */,
966 arg,
967 false /* reader */,
968 Type::ErrorMode_Goto,
969 false /* addPrefixToName */);
970 }
971
972 // Second DFS: resolve references.
973 for (const auto &arg : method->args()) {
974 emitCppResolveReferences(
975 out,
976 "_hidl_data",
977 false /* parcelObjIsPointer */,
978 arg,
979 false /* reader */,
980 Type::ErrorMode_Goto,
981 false /* addPrefixToName */);
982 }
983
984 out << "_hidl_err = remote()->transact("
985 << method->getSerialId()
986 << " /* "
987 << method->name()
988 << " */, _hidl_data, &_hidl_reply";
989
990 if (method->isOneway()) {
991 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
992 }
993 out << ");\n";
994
995 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
996
997 if (!method->isOneway()) {
998 out << "_hidl_err = _hidl_status.readFromParcel(_hidl_reply);\n";
999 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1000 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1001
1002
1003 // First DFS: write all buffers and resolve pointers for parent
1004 for (const auto &arg : method->results()) {
1005 emitCppReaderWriter(
1006 out,
1007 "_hidl_reply",
1008 false /* parcelObjIsPointer */,
1009 arg,
1010 true /* reader */,
1011 Type::ErrorMode_Goto,
1012 true /* addPrefixToName */);
1013 }
1014
1015 // Second DFS: resolve references.
1016 for (const auto &arg : method->results()) {
1017 emitCppResolveReferences(
1018 out,
1019 "_hidl_reply",
1020 false /* parcelObjIsPointer */,
1021 arg,
1022 true /* reader */,
1023 Type::ErrorMode_Goto,
1024 true /* addPrefixToName */);
1025 }
1026
1027 if (returnsValue && elidedReturn == nullptr) {
1028 out << "_hidl_cb(";
1029
1030 bool first = true;
1031 for (const auto &arg : method->results()) {
1032 if (!first) {
1033 out << ", ";
1034 }
1035
1036 if (arg->type().resultNeedsDeref()) {
1037 out << "*";
1038 }
1039 out << "_hidl_out_" << arg->name();
1040
1041 first = false;
1042 }
1043
1044 out << ");\n\n";
1045 }
1046 status_t status = generateCppInstrumentationCall(
1047 out,
1048 InstrumentationEvent::CLIENT_API_EXIT,
Yifan Hong068c5522016-10-31 14:07:25 -07001049 method);
1050 if (status != OK) {
1051 return status;
1052 }
1053 }
1054
1055 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001056 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1057 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001058 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001059 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1060 } else {
1061 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1062 out << "return ::android::hardware::Return<void>();\n\n";
1063 }
1064
1065 out.unindent();
1066 out << "_hidl_error:\n";
1067 out.indent();
1068 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1069 out << "return ::android::hardware::Return<";
1070 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001071 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001072 } else {
1073 out << "void";
1074 }
1075 out << ">(_hidl_status);\n";
1076
1077 out.unindent();
1078 out << "}\n\n";
1079 return OK;
1080}
1081
Andreas Huber881227d2016-08-02 14:20:21 -07001082status_t AST::generateProxySource(
1083 Formatter &out, const std::string &baseName) const {
1084 const std::string klassName = "Bp" + baseName;
1085
1086 out << klassName
1087 << "::"
1088 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001089 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001090
1091 out.indent();
1092 out.indent();
1093
1094 out << ": BpInterface"
Steven Moreland40786312016-08-16 10:29:40 -07001095 << "<IHw"
Andreas Huber881227d2016-08-02 14:20:21 -07001096 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001097 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001098 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001099 << mPackage.string()
1100 << "::I"
1101 << baseName
1102 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001103
Andreas Huber881227d2016-08-02 14:20:21 -07001104 out.unindent();
1105 out.unindent();
1106 out << "}\n\n";
1107
Yifan Hong068c5522016-10-31 14:07:25 -07001108 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1109 return generateProxyMethodSource(out, klassName, method, superInterface);
1110 });
Andreas Huber881227d2016-08-02 14:20:21 -07001111
Yifan Hong068c5522016-10-31 14:07:25 -07001112 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001113}
1114
1115status_t AST::generateStubSource(
1116 Formatter &out, const std::string &baseName) const {
1117 out << "IMPLEMENT_HWBINDER_META_INTERFACE("
1118 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001119 << ", "
1120 << mPackage.cppNamespace()
Andreas Huber881227d2016-08-02 14:20:21 -07001121 << "::I"
1122 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001123 << "::descriptor);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001124
1125 const std::string klassName = "Bn" + baseName;
1126
Steven Moreland40786312016-08-16 10:29:40 -07001127 out << klassName
1128 << "::"
1129 << klassName
1130 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl)\n";
1131
1132 out.indent();
1133 out.indent();
1134
1135 out << ": BnInterface"
1136 << "<I"
1137 << baseName
1138 << ", IHw"
1139 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001140 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001141 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001142 << mPackage.string()
1143 << "::I"
1144 << baseName
1145 << "\") {\n";
Steven Moreland40786312016-08-16 10:29:40 -07001146
1147 out.unindent();
1148 out.unindent();
1149 out << "}\n\n";
1150
Andreas Huber881227d2016-08-02 14:20:21 -07001151 out << "::android::status_t " << klassName << "::onTransact(\n";
1152
1153 out.indent();
1154 out.indent();
1155
Iliyan Malchev549e2592016-08-10 08:59:12 -07001156 out << "uint32_t _hidl_code,\n"
1157 << "const ::android::hardware::Parcel &_hidl_data,\n"
1158 << "::android::hardware::Parcel *_hidl_reply,\n"
1159 << "uint32_t _hidl_flags,\n"
1160 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001161
1162 out.unindent();
1163
Iliyan Malchev549e2592016-08-10 08:59:12 -07001164 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001165 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001166 out.indent();
1167
1168 const Interface *iface = mRootScope->getInterface();
1169
Yifan Hong10fe0b52016-10-19 14:20:17 -07001170 for (const auto &tuple : iface->allMethodsFromRoot()) {
1171 const Method *method = tuple.method();
1172 const Interface *superInterface = tuple.interface();
1173 out << "case "
1174 << method->getSerialId()
1175 << " /* "
1176 << method->name()
1177 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001178
Yifan Hong10fe0b52016-10-19 14:20:17 -07001179 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001180
Yifan Hong10fe0b52016-10-19 14:20:17 -07001181 status_t err =
1182 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001183
Yifan Hong10fe0b52016-10-19 14:20:17 -07001184 if (err != OK) {
1185 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001186 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001187
1188 out.unindent();
1189 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001190 }
1191
1192 out << "default:\n{\n";
1193 out.indent();
1194
Andreas Huber8a82ff72016-08-04 10:29:39 -07001195 out << "return ::android::hardware::BnInterface<I"
Steven Moreland40786312016-08-16 10:29:40 -07001196 << baseName << ", IHw" << baseName
Andreas Huber881227d2016-08-02 14:20:21 -07001197 << ">::onTransact(\n";
1198
1199 out.indent();
1200 out.indent();
1201
Iliyan Malchev549e2592016-08-10 08:59:12 -07001202 out << "_hidl_code, _hidl_data, _hidl_reply, "
1203 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001204
1205 out.unindent();
1206 out.unindent();
1207
1208 out.unindent();
1209 out << "}\n";
1210
1211 out.unindent();
1212 out << "}\n\n";
1213
Iliyan Malchev549e2592016-08-10 08:59:12 -07001214 out << "if (_hidl_err == ::android::UNEXPECTED_NULL) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001215 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001216 out << "_hidl_err = ::android::hardware::Status::fromExceptionCode(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001217 out.indent();
1218 out.indent();
Andreas Huber8a82ff72016-08-04 10:29:39 -07001219 out << "::android::hardware::Status::EX_NULL_POINTER)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001220 out.indent();
1221 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001222 out << ".writeToParcel(_hidl_reply);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001223 out.unindent();
1224 out.unindent();
1225 out.unindent();
1226 out.unindent();
1227
1228 out.unindent();
1229 out << "}\n\n";
1230
Iliyan Malchev549e2592016-08-10 08:59:12 -07001231 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001232
1233 out.unindent();
1234 out << "}\n\n";
1235
1236 return OK;
1237}
1238
1239status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001240 Formatter &out, const Interface *iface, const Method *method) const {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001241 out << "if (!_hidl_data.enforceInterface(";
1242
Steven Morelandd39133b2016-11-11 12:30:08 -08001243 if (method->isHidlReserved()) {
Yifan Hong5bd9aff2016-11-08 18:52:55 -08001244 out << "::android::hardware::IBase";
Steven Morelandd39133b2016-11-11 12:30:08 -08001245 } else {
1246 out << iface->fqName().cppNamespace()
1247 << "::I"
1248 << iface->getBaseName();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001249 }
1250
1251 out << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001252
Andreas Huber881227d2016-08-02 14:20:21 -07001253 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001254 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001255 out << "break;\n";
1256 out.unindent();
1257 out << "}\n\n";
1258
Andreas Huber5e44a292016-09-27 14:52:39 -07001259 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001260
Yifan Hongbf459bc2016-08-23 16:50:37 -07001261 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001262 for (const auto &arg : method->args()) {
1263 emitCppReaderWriter(
1264 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001265 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001266 false /* parcelObjIsPointer */,
1267 arg,
1268 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001269 Type::ErrorMode_Break,
1270 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001271 }
1272
Yifan Hongbf459bc2016-08-23 16:50:37 -07001273 // Second DFS: resolve references
1274 for (const auto &arg : method->args()) {
1275 emitCppResolveReferences(
1276 out,
1277 "_hidl_data",
1278 false /* parcelObjIsPointer */,
1279 arg,
1280 true /* reader */,
1281 Type::ErrorMode_Break,
1282 false /* addPrefixToName */);
1283 }
1284
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001285 status_t status = generateCppInstrumentationCall(
1286 out,
1287 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001288 method);
1289 if (status != OK) {
1290 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001291 }
1292
Andreas Huber881227d2016-08-02 14:20:21 -07001293 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001294 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001295
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001296 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001297 out << elidedReturn->type().getCppResultType()
1298 << " "
1299 << elidedReturn->name()
1300 << " = "
1301 << method->name()
1302 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001303
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001304 bool first = true;
1305 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001306 if (!first) {
1307 out << ", ";
1308 }
1309
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001310 if (arg->type().resultNeedsDeref()) {
1311 out << "*";
1312 }
1313
1314 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001315
1316 first = false;
1317 }
1318
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001319 out << ");\n\n";
Andreas Huber8a82ff72016-08-04 10:29:39 -07001320 out << "::android::hardware::Status::ok()"
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001321 << ".writeToParcel(_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001322
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001323 elidedReturn->type().emitReaderWriter(
1324 out,
1325 elidedReturn->name(),
1326 "_hidl_reply",
1327 true, /* parcelObjIsPointer */
1328 false, /* isReader */
1329 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001330
Yifan Hongbf459bc2016-08-23 16:50:37 -07001331 emitCppResolveReferences(
1332 out,
1333 "_hidl_reply",
1334 true /* parcelObjIsPointer */,
1335 elidedReturn,
1336 false /* reader */,
1337 Type::ErrorMode_Ignore,
1338 false /* addPrefixToName */);
1339
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001340 status_t status = generateCppInstrumentationCall(
1341 out,
1342 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001343 method);
1344 if (status != OK) {
1345 return status;
1346 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001347
Iliyan Malchev549e2592016-08-10 08:59:12 -07001348 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001349 } else {
1350 if (returnsValue) {
1351 out << "bool _hidl_callbackCalled = false;\n\n";
1352 }
Andreas Huber881227d2016-08-02 14:20:21 -07001353
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001354 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001355
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001356 bool first = true;
1357 for (const auto &arg : method->args()) {
1358 if (!first) {
1359 out << ", ";
1360 }
Andreas Huber881227d2016-08-02 14:20:21 -07001361
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001362 if (arg->type().resultNeedsDeref()) {
1363 out << "*";
1364 }
1365
1366 out << arg->name();
1367
1368 first = false;
1369 }
1370
1371 if (returnsValue) {
1372 if (!first) {
1373 out << ", ";
1374 }
1375
1376 out << "[&](";
1377
1378 first = true;
1379 for (const auto &arg : method->results()) {
1380 if (!first) {
1381 out << ", ";
1382 }
1383
1384 out << "const auto &" << arg->name();
1385
1386 first = false;
1387 }
1388
1389 out << ") {\n";
1390 out.indent();
1391 out << "_hidl_callbackCalled = true;\n\n";
1392
1393 out << "::android::hardware::Status::ok()"
1394 << ".writeToParcel(_hidl_reply);\n\n";
1395
Yifan Hongbf459bc2016-08-23 16:50:37 -07001396 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001397 for (const auto &arg : method->results()) {
1398 emitCppReaderWriter(
1399 out,
1400 "_hidl_reply",
1401 true /* parcelObjIsPointer */,
1402 arg,
1403 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001404 Type::ErrorMode_Ignore,
1405 false /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001406 }
1407
Yifan Hongbf459bc2016-08-23 16:50:37 -07001408 // Second DFS: resolve references
1409 for (const auto &arg : method->results()) {
1410 emitCppResolveReferences(
1411 out,
1412 "_hidl_reply",
1413 true /* parcelObjIsPointer */,
1414 arg,
1415 false /* reader */,
1416 Type::ErrorMode_Ignore,
1417 false /* addPrefixToName */);
1418 }
1419
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001420 status_t status = generateCppInstrumentationCall(
1421 out,
1422 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001423 method);
1424 if (status != OK) {
1425 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001426 }
1427
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001428 out << "_hidl_cb(*_hidl_reply);\n";
1429
1430 out.unindent();
1431 out << "}\n";
1432 }
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
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001643status_t AST::generateCppInstrumentationCall(
1644 Formatter &out,
1645 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001646 const Method *method) const {
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001647 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1648 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001649 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001650 std::string event_str = "";
1651 switch (event) {
1652 case SERVER_API_ENTRY:
1653 {
1654 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1655 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001656 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001657 << (arg->type().resultNeedsDeref() ? "" : "&")
1658 << arg->name()
1659 << ");\n";
1660 }
1661 break;
1662 }
1663 case SERVER_API_EXIT:
1664 {
1665 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001666 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001667 out << "_hidl_args.push_back((void *)&"
Steven Moreland031ccf12016-10-31 15:54:38 -07001668 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001669 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001670 }
1671 break;
1672 }
1673 case CLIENT_API_ENTRY:
1674 {
1675 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1676 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001677 out << "_hidl_args.push_back((void *)&"
1678 << arg->name()
1679 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001680 }
1681 break;
1682 }
1683 case CLIENT_API_EXIT:
1684 {
1685 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1686 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001687 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001688 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001689 << "_hidl_out_"
1690 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001691 << ");\n";
1692 }
1693 break;
1694 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001695 case PASSTHROUGH_ENTRY:
1696 {
1697 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1698 for (const auto &arg : method->args()) {
1699 out << "_hidl_args.push_back((void *)&"
1700 << arg->name()
1701 << ");\n";
1702 }
1703 break;
1704 }
1705 case PASSTHROUGH_EXIT:
1706 {
1707 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
1708 // TODO(b/32576620): passthrough return values
1709 break;
1710 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001711 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001712 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001713 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001714 return UNKNOWN_ERROR;
1715 }
1716 }
1717
Steven Moreland031ccf12016-10-31 15:54:38 -07001718 const Interface *iface = mRootScope->getInterface();
1719
Steven Moreland1ab31442016-11-03 18:37:51 -07001720 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001721 out.indent();
1722 out << "callback("
1723 << event_str
1724 << ", \""
1725 << mPackage.package()
1726 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07001727 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001728 << "\", \""
1729 << iface->localName()
1730 << "\", \""
1731 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001732 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001733 out.unindent();
1734 out << "}\n";
1735 out.unindent();
1736 out << "}\n\n";
1737
1738 return OK;
1739}
1740
Andreas Huber881227d2016-08-02 14:20:21 -07001741} // namespace android
1742