blob: 03063854e960d10fb1a7099a0333c339b8641e3a [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Huber881227d2016-08-02 14:20:21 -070017#include "AST.h"
18
19#include "Coordinator.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070020#include "EnumType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070021#include "Interface.h"
22#include "Method.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070023#include "ScalarType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070024#include "Scope.h"
25
Andreas Huberdca261f2016-08-04 13:47:51 -070026#include <algorithm>
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070027#include <hidl-util/Formatter.h>
Steven Moreland5708edf2016-11-04 15:33:31 +000028#include <hidl-util/StringHelper.h>
Andreas Huber881227d2016-08-02 14:20:21 -070029#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070030#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070031#include <vector>
32
33namespace android {
34
Andreas Huberb82318c2016-08-02 14:45:54 -070035status_t AST::generateCpp(const std::string &outputPath) const {
36 status_t err = generateInterfaceHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070037
38 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070039 err = generateStubHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070040 }
41
42 if (err == OK) {
Steven Moreland40786312016-08-16 10:29:40 -070043 err = generateHwBinderHeader(outputPath);
44 }
45
46 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070047 err = generateProxyHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070048 }
49
50 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070051 err = generateAllSource(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070052 }
53
Steven Moreland69e7c702016-09-09 11:16:32 -070054 if (err == OK) {
55 generatePassthroughHeader(outputPath);
56 }
57
Andreas Huber881227d2016-08-02 14:20:21 -070058 return err;
59}
60
Andreas Huber737080b2016-08-02 15:38:04 -070061void AST::getPackageComponents(
62 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070063 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070064}
65
66void AST::getPackageAndVersionComponents(
67 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070068 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070069}
70
Steven Moreland5708edf2016-11-04 15:33:31 +000071std::string AST::makeHeaderGuard(const std::string &baseName,
72 bool indicateGenerated) const {
73 std::string guard;
Andreas Huber881227d2016-08-02 14:20:21 -070074
Steven Moreland5708edf2016-11-04 15:33:31 +000075 if (indicateGenerated) {
76 guard += "HIDL_GENERATED_";
77 }
78
79 guard += StringHelper::Uppercase(mPackage.tokenName());
Andreas Huber881227d2016-08-02 14:20:21 -070080 guard += "_";
Steven Moreland5708edf2016-11-04 15:33:31 +000081 guard += StringHelper::Uppercase(baseName);
82 guard += "_H";
Andreas Huber881227d2016-08-02 14:20:21 -070083
84 return guard;
85}
86
Steven Morelandee88eed2016-10-31 17:49:00 -070087// static
88void AST::generateCppPackageInclude(
89 Formatter &out,
90 const FQName &package,
91 const std::string &klass) {
92
93 out << "#include <";
94
95 std::vector<std::string> components;
96 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
97
98 for (const auto &component : components) {
99 out << component << "/";
100 }
101
102 out << klass
103 << ".h>\n";
104}
105
Andreas Huber881227d2016-08-02 14:20:21 -0700106void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
107 std::vector<std::string> packageComponents;
108 getPackageAndVersionComponents(
109 &packageComponents, true /* cpp_compatible */);
110
111 if (enter) {
112 for (const auto &component : packageComponents) {
113 out << "namespace " << component << " {\n";
114 }
Andreas Huber0e00de42016-08-03 09:56:02 -0700115
Andreas Huber2831d512016-08-15 09:33:47 -0700116 out.setNamespace(mPackage.cppNamespace() + "::");
Andreas Huber881227d2016-08-02 14:20:21 -0700117 } else {
Andreas Huber0e00de42016-08-03 09:56:02 -0700118 out.setNamespace(std::string());
119
Andreas Huber881227d2016-08-02 14:20:21 -0700120 for (auto it = packageComponents.rbegin();
121 it != packageComponents.rend();
122 ++it) {
123 out << "} // namespace " << *it << "\n";
124 }
125 }
126}
127
Andreas Huberb82318c2016-08-02 14:45:54 -0700128status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700129
Andreas Huberb82318c2016-08-02 14:45:54 -0700130 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700131 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700132 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700133
134 std::string ifaceName;
135 bool isInterface = true;
136 if (!AST::isInterface(&ifaceName)) {
137 ifaceName = "types";
138 isInterface = false;
139 }
140 path.append(ifaceName);
141 path.append(".h");
142
Andreas Huberd2943e12016-08-05 11:59:31 -0700143 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700144 FILE *file = fopen(path.c_str(), "w");
145
146 if (file == NULL) {
147 return -errno;
148 }
149
150 Formatter out(file);
151
152 const std::string guard = makeHeaderGuard(ifaceName);
153
154 out << "#ifndef " << guard << "\n";
155 out << "#define " << guard << "\n\n";
156
Andreas Huber737080b2016-08-02 15:38:04 -0700157 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700158 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700159 }
160
161 if (!mImportedNames.empty()) {
162 out << "\n";
163 }
164
Steven Moreland0693f312016-11-09 15:06:14 -0800165 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800166 if (isIBase()) {
167 out << "// skipped #include IServiceNotification.h\n\n";
168 } else {
169 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
170 }
Steven Moreland0693f312016-11-09 15:06:14 -0800171 }
172
Yifan Hongc8934042016-11-17 17:10:52 -0800173 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700174 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700175
176 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200177 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700178 }
179
Martijn Coenenaf712c02016-11-16 15:26:27 +0100180 out << "#include <utils/NativeHandle.h>\n";
181 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700182
183 enterLeaveNamespace(out, true /* enter */);
184 out << "\n";
185
186 if (isInterface) {
187 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700188 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700189
190 const Interface *iface = mRootScope->getInterface();
191 const Interface *superType = iface->superType();
192
Steven Moreland40786312016-08-16 10:29:40 -0700193 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800194 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700195 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000196 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700197 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700198 }
199
200 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700201
202 out.indent();
203
Andreas Huber881227d2016-08-02 14:20:21 -0700204 }
205
206 status_t err = emitTypeDeclarations(out);
207
208 if (err != OK) {
209 return err;
210 }
211
212 if (isInterface) {
213 const Interface *iface = mRootScope->getInterface();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700214 const Interface *superType = iface->superType();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700215 const std::string baseName = iface->getBaseName();
Steven Moreland19d5c172016-10-20 19:20:25 -0700216 out << "constexpr static ::android::hardware::hidl_version version = {"
Martijn Coenena21f1492016-09-08 15:55:14 +0200217 << mPackage.getPackageMajorVersion() << ","
218 << mPackage.getPackageMinorVersion() << "};\n";
Steven Moreland19d5c172016-10-20 19:20:25 -0700219 out << "virtual const ::android::hardware::hidl_version&"
220 << "getInterfaceVersion() const {\n";
Martijn Coenena21f1492016-09-08 15:55:14 +0200221 out.indent();
222 out << "return version;\n";
223 out.unindent();
224 out << "}\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800225 out << "virtual bool isRemote() const ";
226 if (!isIBase()) {
227 out << "override ";
228 }
229 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800230
Andreas Huber881227d2016-08-02 14:20:21 -0700231 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700232 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700233
Andreas Huber881227d2016-08-02 14:20:21 -0700234 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800235 const TypedVar *elidedReturn = method->canElideCallback();
236
237 if (elidedReturn == nullptr && returnsValue) {
238 out << "using "
239 << method->name()
240 << "_cb = std::function<void("
241 << Method::GetArgSignature(method->results(),
242 true /* specify namespaces */)
243 << ")>;\n";
244 }
Andreas Huber881227d2016-08-02 14:20:21 -0700245
Andreas Huber3599d922016-08-09 10:42:57 -0700246 method->dumpAnnotations(out);
247
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700248 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700249 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700250 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700251 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700252 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700253 }
254
255 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700256 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700257 << Method::GetArgSignature(method->args(),
258 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700259
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700260 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700261 if (!method->args().empty()) {
262 out << ", ";
263 }
264
Steven Moreland67f67b42016-09-29 08:59:02 -0700265 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700266 }
267
Yifan Hong10fe0b52016-10-19 14:20:17 -0700268 out << ")";
269 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800270 if (!isIBase()) {
271 out << " override";
272 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700273 out << " {\n";
274 out.indent();
275 method->cppImpl(out);
276 out.unindent();
277 out << "\n}\n";
278 } else {
279 out << " = 0;\n";
280 }
Andreas Huber881227d2016-08-02 14:20:21 -0700281 }
Steven Moreland40786312016-08-16 10:29:40 -0700282
Yifan Hongfe95aa22016-10-19 17:26:45 -0700283 if (!iface->isRootType()) {
284 out << "// cast static functions\n";
Yifan Hong3b320f82016-11-01 15:15:54 -0700285 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700286
287 for (const Interface *superType : iface->superTypeChain()) {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700288 out << "static "
289 << childTypeResult
290 << " castFrom("
Yifan Hong3b320f82016-11-01 15:15:54 -0700291 << superType->getCppArgumentType()
Yifan Hongfe95aa22016-10-19 17:26:45 -0700292 << " parent"
Yifan Hongfe95aa22016-10-19 17:26:45 -0700293 << ");\n";
294 }
295 }
296
Steven Morelandd39133b2016-11-11 12:30:08 -0800297 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700298
Yifan Hongc8934042016-11-17 17:10:52 -0800299 if (isIBase()) {
300 out << "// skipped DECLARE_SERVICE_MANAGER_INTERACTIONS\n\n";
301 } else {
302 out << "DECLARE_SERVICE_MANAGER_INTERACTIONS(" << baseName << ")\n\n";
303 }
Yifan Hong158655a2016-11-08 12:34:07 -0800304
305 out << "private: static int hidlStaticBlock;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700306 }
307
308 if (isInterface) {
309 out.unindent();
310
Andreas Hubere3f769a2016-10-10 10:54:44 -0700311 out << "};\n\n";
312 }
313
314 err = mRootScope->emitGlobalTypeDeclarations(out);
315
316 if (err != OK) {
317 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700318 }
319
320 out << "\n";
321 enterLeaveNamespace(out, false /* enter */);
322
323 out << "\n#endif // " << guard << "\n";
324
325 return OK;
326}
327
Steven Moreland40786312016-08-16 10:29:40 -0700328status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
329 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800330 bool isInterface = AST::isInterface(&ifaceName);
331 const Interface *iface = nullptr;
332 std::string baseName{};
333 std::string klassName{};
334
335 if(isInterface) {
336 iface = mRootScope->getInterface();
337 baseName = iface->getBaseName();
338 klassName = "IHw" + baseName;
339 } else {
340 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700341 }
342
Steven Moreland40786312016-08-16 10:29:40 -0700343 std::string path = outputPath;
344 path.append(mCoordinator->convertPackageRootToPath(mPackage));
345 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
346 path.append(klassName + ".h");
347
Yifan Hong244e82d2016-11-11 11:13:57 -0800348 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700349
350 if (file == NULL) {
351 return -errno;
352 }
353
354 Formatter out(file);
355
356 const std::string guard = makeHeaderGuard(klassName);
357
358 out << "#ifndef " << guard << "\n";
359 out << "#define " << guard << "\n\n";
360
Yifan Hong244e82d2016-11-11 11:13:57 -0800361 if (isInterface) {
362 generateCppPackageInclude(out, mPackage, ifaceName);
363 } else {
364 generateCppPackageInclude(out, mPackage, "types");
365 }
Steven Moreland40786312016-08-16 10:29:40 -0700366
Steven Morelandee88eed2016-10-31 17:49:00 -0700367 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700368
369 for (const auto &item : mImportedNames) {
370 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800371 generateCppPackageInclude(out, item, "hwtypes");
372 } else {
373 generateCppPackageInclude(out, item, "Bn" + item.getInterfaceBaseName());
Steven Moreland40786312016-08-16 10:29:40 -0700374 }
Steven Moreland40786312016-08-16 10:29:40 -0700375 }
376
377 out << "\n";
378
Yifan Hong859e53f2016-11-14 19:08:24 -0800379 out << "#include <hidl/HidlTransportSupport.h>\n";
Martijn Coenen93915102016-09-01 01:35:52 +0200380 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700381 out << "#include <hwbinder/IBinder.h>\n";
382 out << "#include <hwbinder/IInterface.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700383
384 out << "\n";
385
386 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700387
Yifan Hong244e82d2016-11-11 11:13:57 -0800388 if (isInterface) {
389 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700390
Yifan Hong244e82d2016-11-11 11:13:57 -0800391 out << "struct "
392 << klassName
393 << " : public "
394 << ifaceName;
Steven Moreland40786312016-08-16 10:29:40 -0700395
Yifan Hong244e82d2016-11-11 11:13:57 -0800396 const Interface *superType = iface->superType();
Steven Moreland40786312016-08-16 10:29:40 -0700397
Yifan Hong244e82d2016-11-11 11:13:57 -0800398 out << ", public ::android::hardware::IInterface";
Steven Moreland40786312016-08-16 10:29:40 -0700399
Yifan Hong244e82d2016-11-11 11:13:57 -0800400 out << " {\n";
Steven Moreland40786312016-08-16 10:29:40 -0700401
Yifan Hong244e82d2016-11-11 11:13:57 -0800402 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700403
Yifan Hong244e82d2016-11-11 11:13:57 -0800404 out << "DECLARE_HWBINDER_META_INTERFACE(" << baseName << ");\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700405
Yifan Hong244e82d2016-11-11 11:13:57 -0800406 out.unindent();
407
408 out << "};\n\n";
409 }
410
411 status_t err = mRootScope->emitGlobalHwDeclarations(out);
412 if (err != OK) {
413 return err;
414 }
Steven Moreland40786312016-08-16 10:29:40 -0700415
416 enterLeaveNamespace(out, false /* enter */);
417
418 out << "\n#endif // " << guard << "\n";
419
420 return OK;
421}
422
Andreas Huber881227d2016-08-02 14:20:21 -0700423status_t AST::emitTypeDeclarations(Formatter &out) const {
424 return mRootScope->emitTypeDeclarations(out);
425}
426
Steven Morelanda7a421a2016-09-07 08:35:18 -0700427status_t AST::generateStubMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700428 const Method *method) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700429 out << "inline ";
430
Yifan Hong068c5522016-10-31 14:07:25 -0700431 method->generateCppSignature(out);
Steven Morelanda7a421a2016-09-07 08:35:18 -0700432
433 const bool returnsValue = !method->results().empty();
434 const TypedVar *elidedReturn = method->canElideCallback();
435 out << " {\n";
436 out.indent();
437 out << "return mImpl->"
438 << method->name()
439 << "(";
440 bool first = true;
441 for (const auto &arg : method->args()) {
442 if (!first) {
443 out << ", ";
444 }
445 first = false;
446 out << arg->name();
447 }
448 if (returnsValue && elidedReturn == nullptr) {
449 if (!method->args().empty()) {
450 out << ", ";
451 }
452
453 out << "_hidl_cb";
454 }
455 out << ");\n";
456 out.unindent();
457 out << "}";
458
459 out << ";\n";
460
461 return OK;
462}
463
Steven Moreland69e7c702016-09-09 11:16:32 -0700464status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700465 const Method *method) const {
466 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700467
468 out << " {\n";
469 out.indent();
470
471 const bool returnsValue = !method->results().empty();
472 const TypedVar *elidedReturn = method->canElideCallback();
473
Steven Moreland67f67b42016-09-29 08:59:02 -0700474 if (returnsValue && elidedReturn == nullptr) {
475 generateCheckNonNull(out, "_hidl_cb");
476 }
477
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700478 generateCppInstrumentationCall(
479 out,
480 InstrumentationEvent::PASSTHROUGH_ENTRY,
481 method);
482
483 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700484
485 if (method->isOneway()) {
486 out << "addOnewayTask([this";
487 for (const auto &arg : method->args()) {
488 out << ", " << arg->name();
489 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700490 out << "] {\n";
491 out.indent();
492 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700493 }
494
495 out << "mImpl->"
496 << method->name()
497 << "(";
498
499 bool first = true;
500 for (const auto &arg : method->args()) {
501 if (!first) {
502 out << ", ";
503 }
504 first = false;
505 out << arg->name();
506 }
507 if (returnsValue && elidedReturn == nullptr) {
508 if (!method->args().empty()) {
509 out << ", ";
510 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800511 out << "[&](";
512 first = true;
513 for (const auto &arg : method->results()) {
514 if (!first) {
515 out << ", ";
516 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700517
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800518 out << "const auto &" << arg->name();
519
520 first = false;
521 }
522
523 out << ") {\n";
524 out.indent();
525 status_t status = generateCppInstrumentationCall(
526 out,
527 InstrumentationEvent::PASSTHROUGH_EXIT,
528 method);
529 if (status != OK) {
530 return status;
531 }
532
533 out << "_hidl_cb(";
534 first = true;
535 for (const auto &arg : method->results()) {
536 if (!first) {
537 out << ", ";
538 }
539
540 out << arg->name();
541
542 first = false;
543 }
544 out << ");\n";
545 out.unindent();
546 out << "});\n\n";
547 } else {
548 out << ");\n\n";
549 if (elidedReturn != nullptr) {
550 out << elidedReturn->type().getCppResultType()
551 << " "
552 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000553 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800554 }
555 status_t status = generateCppInstrumentationCall(
556 out,
557 InstrumentationEvent::PASSTHROUGH_EXIT,
558 method);
559 if (status != OK) {
560 return status;
561 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700562 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700563
564 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700565 out.unindent();
566 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700567 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700568
569 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700570
571 out.unindent();
572 out << "}\n";
573
574 return OK;
575}
576
Yifan Hong068c5522016-10-31 14:07:25 -0700577status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700578
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700579 const Interface *iface = mRootScope->getInterface();
580
Yifan Hong10fe0b52016-10-19 14:20:17 -0700581 const Interface *prevIterface = nullptr;
582 for (const auto &tuple : iface->allMethodsFromRoot()) {
583 const Method *method = tuple.method();
584 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700585
Yifan Hong10fe0b52016-10-19 14:20:17 -0700586 if(prevIterface != superInterface) {
587 if (prevIterface != nullptr) {
588 out << "\n";
589 }
590 out << "// Methods from "
591 << superInterface->fullName()
592 << " follow.\n";
593 prevIterface = superInterface;
594 }
Yifan Hong068c5522016-10-31 14:07:25 -0700595 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700596
Yifan Hong10fe0b52016-10-19 14:20:17 -0700597 if (err != OK) {
598 return err;
599 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700600 }
601
Yifan Hong10fe0b52016-10-19 14:20:17 -0700602 out << "\n";
603
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700604 return OK;
605}
606
Andreas Huberb82318c2016-08-02 14:45:54 -0700607status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700608 std::string ifaceName;
609 if (!AST::isInterface(&ifaceName)) {
610 // types.hal does not get a stub header.
611 return OK;
612 }
613
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700614 const Interface *iface = mRootScope->getInterface();
615 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700616 const std::string klassName = "Bn" + baseName;
Andreas Huber881227d2016-08-02 14:20:21 -0700617
Andreas Huberb82318c2016-08-02 14:45:54 -0700618 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700619 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700620 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700621 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700622 path.append(".h");
623
Andreas Huberd2943e12016-08-05 11:59:31 -0700624 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700625 FILE *file = fopen(path.c_str(), "w");
626
627 if (file == NULL) {
628 return -errno;
629 }
630
631 Formatter out(file);
632
Steven Moreland40786312016-08-16 10:29:40 -0700633 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700634
635 out << "#ifndef " << guard << "\n";
636 out << "#define " << guard << "\n\n";
637
Steven Morelandee88eed2016-10-31 17:49:00 -0700638 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
639 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700640
641 enterLeaveNamespace(out, true /* enter */);
642 out << "\n";
643
644 out << "struct "
645 << "Bn"
646 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700647 << " : public ::android::hardware::BnInterface<I"
648 << baseName << ", IHw" << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700649 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700650
651 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700652 out << "explicit Bn"
653 << baseName
654 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
655 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700656 out << "::android::status_t onTransact(\n";
657 out.indent();
658 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700659 out << "uint32_t _hidl_code,\n";
660 out << "const ::android::hardware::Parcel &_hidl_data,\n";
661 out << "::android::hardware::Parcel *_hidl_reply,\n";
662 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700663 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700664 out.unindent();
665 out.unindent();
666
Yifan Hong068c5522016-10-31 14:07:25 -0700667 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
668 return generateStubMethod(out, method);
669 });
Steven Moreland9c387612016-09-07 09:54:26 -0700670
671 if (err != OK) {
672 return err;
673 }
674
Zhuoyao Zhangde578002016-09-07 18:24:17 -0700675
Andreas Huber881227d2016-08-02 14:20:21 -0700676 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700677 out << "};\n\n";
678
679 enterLeaveNamespace(out, false /* enter */);
680
681 out << "\n#endif // " << guard << "\n";
682
683 return OK;
684}
685
Andreas Huberb82318c2016-08-02 14:45:54 -0700686status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700687 std::string ifaceName;
688 if (!AST::isInterface(&ifaceName)) {
689 // types.hal does not get a proxy header.
690 return OK;
691 }
692
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700693 const Interface *iface = mRootScope->getInterface();
694 const std::string baseName = iface->getBaseName();
Andreas Huber881227d2016-08-02 14:20:21 -0700695
Andreas Huberb82318c2016-08-02 14:45:54 -0700696 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700697 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700698 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700699 path.append("Bp");
700 path.append(baseName);
701 path.append(".h");
702
Andreas Huberd2943e12016-08-05 11:59:31 -0700703 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700704 FILE *file = fopen(path.c_str(), "w");
705
706 if (file == NULL) {
707 return -errno;
708 }
709
710 Formatter out(file);
711
712 const std::string guard = makeHeaderGuard("Bp" + baseName);
713
714 out << "#ifndef " << guard << "\n";
715 out << "#define " << guard << "\n\n";
716
717 std::vector<std::string> packageComponents;
718 getPackageAndVersionComponents(
719 &packageComponents, false /* cpp_compatible */);
720
Steven Morelandee88eed2016-10-31 17:49:00 -0700721 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
722 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700723
724 enterLeaveNamespace(out, true /* enter */);
725 out << "\n";
726
727 out << "struct "
728 << "Bp"
729 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700730 << " : public ::android::hardware::BpInterface<IHw"
731 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700732 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700733
734 out.indent();
735
736 out << "explicit Bp"
737 << baseName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700738 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700739 << "\n\n";
740
Yifan Hong10fe0b52016-10-19 14:20:17 -0700741 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700742
Yifan Hong068c5522016-10-31 14:07:25 -0700743 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
744 method->generateCppSignature(out);
745 out << " override;\n";
746 return OK;
747 });
Steven Moreland9c387612016-09-07 09:54:26 -0700748
749 if (err != OK) {
750 return err;
751 }
Andreas Huber881227d2016-08-02 14:20:21 -0700752
753 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700754 out << "};\n\n";
755
756 enterLeaveNamespace(out, false /* enter */);
757
758 out << "\n#endif // " << guard << "\n";
759
760 return OK;
761}
762
Andreas Huberb82318c2016-08-02 14:45:54 -0700763status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700764
Andreas Huberb82318c2016-08-02 14:45:54 -0700765 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700766 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700767 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700768
769 std::string ifaceName;
770 std::string baseName;
771
Yifan Hongfe95aa22016-10-19 17:26:45 -0700772 const Interface *iface = nullptr;
773 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700774 if (!AST::isInterface(&ifaceName)) {
775 baseName = "types";
776 isInterface = false;
777 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700778 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700779 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700780 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700781 }
782
783 path.append(baseName);
784
785 if (baseName != "types") {
786 path.append("All");
787 }
788
789 path.append(".cpp");
790
Andreas Huberd2943e12016-08-05 11:59:31 -0700791 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700792 FILE *file = fopen(path.c_str(), "w");
793
794 if (file == NULL) {
795 return -errno;
796 }
797
798 Formatter out(file);
799
Steven Moreland05cd4232016-11-21 16:01:12 -0800800 out << "#include <android/log.h>\n";
Martijn Coenen7b295242016-11-04 16:52:56 +0100801 out << "#include <cutils/trace.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700802 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700803 // This is a no-op for IServiceManager itself.
804 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
805
Steven Morelandee88eed2016-10-31 17:49:00 -0700806 generateCppPackageInclude(out, mPackage, "Bp" + baseName);
807 generateCppPackageInclude(out, mPackage, "Bn" + baseName);
808 generateCppPackageInclude(out, mPackage, "Bs" + baseName);
Yifan Hongfe95aa22016-10-19 17:26:45 -0700809
810 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700811 generateCppPackageInclude(out,
812 superType->fqName(),
813 "Bp" + superType->getBaseName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700814 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800815
816 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700817 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700818 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800819 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700820 }
821
822 out << "\n";
823
824 enterLeaveNamespace(out, true /* enter */);
825 out << "\n";
826
827 status_t err = generateTypeSource(out, ifaceName);
828
829 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700830 const Interface *iface = mRootScope->getInterface();
Steven Moreland19d5c172016-10-20 19:20:25 -0700831 out << "constexpr ::android::hardware::hidl_version "
832 << ifaceName
833 << "::version;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700834
835 // need to be put here, generateStubSource is using this.
Steven Morelandd39133b2016-11-11 12:30:08 -0800836 out << "const char* I"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700837 << iface->getBaseName()
838 << "::descriptor(\""
839 << iface->fqName().string()
840 << "\");\n\n";
841
Yifan Hong158655a2016-11-08 12:34:07 -0800842 out << "int I"
843 << iface->getBaseName()
844 << "::hidlStaticBlock = []() -> int {\n";
845 out.indentBlock([&] {
Steven Morelandd39133b2016-11-11 12:30:08 -0800846 out << "::android::hardware::gBnConstructorMap[I"
Yifan Hong158655a2016-11-08 12:34:07 -0800847 << iface->getBaseName()
Steven Morelandd39133b2016-11-11 12:30:08 -0800848 << "::descriptor]\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800849 out.indentBlock(2, [&] {
850 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
851 out.indentBlock([&] {
852 out << "return new Bn"
853 << iface->getBaseName()
854 << "(reinterpret_cast<I"
855 << iface->getBaseName()
856 << " *>(iIntf));\n";
857 });
858 out << "};\n";
859 });
860 out << "return 1;\n";
861 });
862 out << "}();\n\n";
863
Yifan Hongfe95aa22016-10-19 17:26:45 -0700864 err = generateInterfaceSource(out);
865 }
866
867 if (err == OK && isInterface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700868 err = generateProxySource(out, baseName);
869 }
870
871 if (err == OK && isInterface) {
872 err = generateStubSource(out, baseName);
873 }
874
Steven Moreland40786312016-08-16 10:29:40 -0700875 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -0700876 err = generatePassthroughSource(out);
877 }
878
879 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -0700880 const Interface *iface = mRootScope->getInterface();
881
Yifan Hongc8934042016-11-17 17:10:52 -0800882 if (isIBase()) {
883 out << "// skipped IMPLEMENT_SERVICE_MANAGER_INTERACTIONS\n";
884 } else {
885 out << "IMPLEMENT_SERVICE_MANAGER_INTERACTIONS("
886 << baseName << ", "
887 << "\"" << iface->fqName().package()
888 << iface->fqName().atVersion()
889 << "\")\n";
890 }
Steven Moreland40786312016-08-16 10:29:40 -0700891 }
892
Andreas Huber881227d2016-08-02 14:20:21 -0700893 enterLeaveNamespace(out, false /* enter */);
894
895 return err;
896}
897
Steven Moreland67f67b42016-09-29 08:59:02 -0700898// static
899void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
900 out << "if (" << nonNull << " == nullptr) {\n";
901 out.indent();
902 out << "return ::android::hardware::Status::fromExceptionCode(\n";
903 out.indent();
904 out.indent();
905 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
906 out.unindent();
907 out.unindent();
908 out.unindent();
909 out << "}\n\n";
910}
911
Andreas Huber881227d2016-08-02 14:20:21 -0700912status_t AST::generateTypeSource(
913 Formatter &out, const std::string &ifaceName) const {
914 return mRootScope->emitTypeDefinitions(out, ifaceName);
915}
916
Andreas Hubere7ff2282016-08-16 13:50:03 -0700917void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -0700918 Formatter &out,
919 const std::vector<TypedVar *> &args,
920 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700921 if (args.empty()) {
922 return;
923 }
924
925 for (const auto &arg : args) {
926 const Type &type = arg->type();
927
Yifan Hong3b320f82016-11-01 15:15:54 -0700928 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700929 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700930 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700931 << ";\n";
932 }
933
934 out << "\n";
935}
936
Andreas Huber881227d2016-08-02 14:20:21 -0700937void AST::emitCppReaderWriter(
938 Formatter &out,
939 const std::string &parcelObj,
940 bool parcelObjIsPointer,
941 const TypedVar *arg,
942 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -0700943 Type::ErrorMode mode,
944 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700945 const Type &type = arg->type();
946
Andreas Huber881227d2016-08-02 14:20:21 -0700947 type.emitReaderWriter(
948 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700949 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700950 parcelObj,
951 parcelObjIsPointer,
952 isReader,
953 mode);
954}
955
Yifan Hongbf459bc2016-08-23 16:50:37 -0700956void AST::emitCppResolveReferences(
957 Formatter &out,
958 const std::string &parcelObj,
959 bool parcelObjIsPointer,
960 const TypedVar *arg,
961 bool isReader,
962 Type::ErrorMode mode,
963 bool addPrefixToName) const {
964 const Type &type = arg->type();
965 if(type.needsResolveReferences()) {
966 type.emitResolveReferences(
967 out,
968 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
969 isReader, // nameIsPointer
970 parcelObj,
971 parcelObjIsPointer,
972 isReader,
973 mode);
974 }
975}
976
Yifan Hong068c5522016-10-31 14:07:25 -0700977status_t AST::generateProxyMethodSource(Formatter &out,
978 const std::string &klassName,
979 const Method *method,
980 const Interface *superInterface) const {
981
982 method->generateCppSignature(out,
983 klassName,
984 true /* specify namespaces */);
985
986 const bool returnsValue = !method->results().empty();
987 const TypedVar *elidedReturn = method->canElideCallback();
988
Steven Moreland41c6d2e2016-11-07 12:26:54 -0800989 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700990
991 out.indent();
992
993 if (returnsValue && elidedReturn == nullptr) {
994 generateCheckNonNull(out, "_hidl_cb");
995 }
996
997 status_t status = generateCppInstrumentationCall(
998 out,
999 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001000 method);
1001 if (status != OK) {
1002 return status;
1003 }
1004
1005 out << "::android::hardware::Parcel _hidl_data;\n";
1006 out << "::android::hardware::Parcel _hidl_reply;\n";
1007 out << "::android::status_t _hidl_err;\n";
1008 out << "::android::hardware::Status _hidl_status;\n\n";
1009
1010 declareCppReaderLocals(
1011 out, method->results(), true /* forResults */);
1012
1013 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongc8934042016-11-17 17:10:52 -08001014 out << superInterface->fqName().cppNamespace()
1015 << "::I"
1016 << superInterface->getBaseName();
Yifan Hong068c5522016-10-31 14:07:25 -07001017 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001018 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1019
1020 // First DFS: write all buffers and resolve pointers for parent
1021 for (const auto &arg : method->args()) {
1022 emitCppReaderWriter(
1023 out,
1024 "_hidl_data",
1025 false /* parcelObjIsPointer */,
1026 arg,
1027 false /* reader */,
1028 Type::ErrorMode_Goto,
1029 false /* addPrefixToName */);
1030 }
1031
1032 // Second DFS: resolve references.
1033 for (const auto &arg : method->args()) {
1034 emitCppResolveReferences(
1035 out,
1036 "_hidl_data",
1037 false /* parcelObjIsPointer */,
1038 arg,
1039 false /* reader */,
1040 Type::ErrorMode_Goto,
1041 false /* addPrefixToName */);
1042 }
1043
1044 out << "_hidl_err = remote()->transact("
1045 << method->getSerialId()
1046 << " /* "
1047 << method->name()
1048 << " */, _hidl_data, &_hidl_reply";
1049
1050 if (method->isOneway()) {
1051 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1052 }
1053 out << ");\n";
1054
1055 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1056
1057 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001058 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001059 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1060 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1061
1062
1063 // First DFS: write all buffers and resolve pointers for parent
1064 for (const auto &arg : method->results()) {
1065 emitCppReaderWriter(
1066 out,
1067 "_hidl_reply",
1068 false /* parcelObjIsPointer */,
1069 arg,
1070 true /* reader */,
1071 Type::ErrorMode_Goto,
1072 true /* addPrefixToName */);
1073 }
1074
1075 // Second DFS: resolve references.
1076 for (const auto &arg : method->results()) {
1077 emitCppResolveReferences(
1078 out,
1079 "_hidl_reply",
1080 false /* parcelObjIsPointer */,
1081 arg,
1082 true /* reader */,
1083 Type::ErrorMode_Goto,
1084 true /* addPrefixToName */);
1085 }
1086
1087 if (returnsValue && elidedReturn == nullptr) {
1088 out << "_hidl_cb(";
1089
1090 bool first = true;
1091 for (const auto &arg : method->results()) {
1092 if (!first) {
1093 out << ", ";
1094 }
1095
1096 if (arg->type().resultNeedsDeref()) {
1097 out << "*";
1098 }
1099 out << "_hidl_out_" << arg->name();
1100
1101 first = false;
1102 }
1103
1104 out << ");\n\n";
1105 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001106 }
1107 status = generateCppInstrumentationCall(
1108 out,
1109 InstrumentationEvent::CLIENT_API_EXIT,
1110 method);
1111 if (status != OK) {
1112 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001113 }
1114
1115 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001116 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1117 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001118 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001119 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1120 } else {
1121 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1122 out << "return ::android::hardware::Return<void>();\n\n";
1123 }
1124
1125 out.unindent();
1126 out << "_hidl_error:\n";
1127 out.indent();
1128 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1129 out << "return ::android::hardware::Return<";
1130 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001131 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001132 } else {
1133 out << "void";
1134 }
1135 out << ">(_hidl_status);\n";
1136
1137 out.unindent();
1138 out << "}\n\n";
1139 return OK;
1140}
1141
Andreas Huber881227d2016-08-02 14:20:21 -07001142status_t AST::generateProxySource(
1143 Formatter &out, const std::string &baseName) const {
1144 const std::string klassName = "Bp" + baseName;
1145
1146 out << klassName
1147 << "::"
1148 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001149 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001150
1151 out.indent();
1152 out.indent();
1153
1154 out << ": BpInterface"
Steven Moreland40786312016-08-16 10:29:40 -07001155 << "<IHw"
Andreas Huber881227d2016-08-02 14:20:21 -07001156 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001157 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001158 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001159 << mPackage.string()
1160 << "::I"
1161 << baseName
1162 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001163
Andreas Huber881227d2016-08-02 14:20:21 -07001164 out.unindent();
1165 out.unindent();
1166 out << "}\n\n";
1167
Yifan Hong068c5522016-10-31 14:07:25 -07001168 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1169 return generateProxyMethodSource(out, klassName, method, superInterface);
1170 });
Andreas Huber881227d2016-08-02 14:20:21 -07001171
Yifan Hong068c5522016-10-31 14:07:25 -07001172 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001173}
1174
1175status_t AST::generateStubSource(
1176 Formatter &out, const std::string &baseName) const {
1177 out << "IMPLEMENT_HWBINDER_META_INTERFACE("
1178 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001179 << ", "
1180 << mPackage.cppNamespace()
Andreas Huber881227d2016-08-02 14:20:21 -07001181 << "::I"
1182 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001183 << "::descriptor);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001184
1185 const std::string klassName = "Bn" + baseName;
1186
Steven Moreland40786312016-08-16 10:29:40 -07001187 out << klassName
1188 << "::"
1189 << klassName
1190 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl)\n";
1191
1192 out.indent();
1193 out.indent();
1194
1195 out << ": BnInterface"
1196 << "<I"
1197 << baseName
1198 << ", IHw"
1199 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001200 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001201 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001202 << mPackage.string()
1203 << "::I"
1204 << baseName
1205 << "\") {\n";
Steven Moreland40786312016-08-16 10:29:40 -07001206
1207 out.unindent();
1208 out.unindent();
1209 out << "}\n\n";
1210
Andreas Huber881227d2016-08-02 14:20:21 -07001211 out << "::android::status_t " << klassName << "::onTransact(\n";
1212
1213 out.indent();
1214 out.indent();
1215
Iliyan Malchev549e2592016-08-10 08:59:12 -07001216 out << "uint32_t _hidl_code,\n"
1217 << "const ::android::hardware::Parcel &_hidl_data,\n"
1218 << "::android::hardware::Parcel *_hidl_reply,\n"
1219 << "uint32_t _hidl_flags,\n"
1220 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001221
1222 out.unindent();
1223
Iliyan Malchev549e2592016-08-10 08:59:12 -07001224 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001225 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001226 out.indent();
1227
1228 const Interface *iface = mRootScope->getInterface();
1229
Yifan Hong10fe0b52016-10-19 14:20:17 -07001230 for (const auto &tuple : iface->allMethodsFromRoot()) {
1231 const Method *method = tuple.method();
1232 const Interface *superInterface = tuple.interface();
1233 out << "case "
1234 << method->getSerialId()
1235 << " /* "
1236 << method->name()
1237 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001238
Yifan Hong10fe0b52016-10-19 14:20:17 -07001239 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001240
Yifan Hong10fe0b52016-10-19 14:20:17 -07001241 status_t err =
1242 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001243
Yifan Hong10fe0b52016-10-19 14:20:17 -07001244 if (err != OK) {
1245 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001246 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001247
1248 out.unindent();
1249 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001250 }
1251
1252 out << "default:\n{\n";
1253 out.indent();
1254
Andreas Huber8a82ff72016-08-04 10:29:39 -07001255 out << "return ::android::hardware::BnInterface<I"
Steven Moreland40786312016-08-16 10:29:40 -07001256 << baseName << ", IHw" << baseName
Andreas Huber881227d2016-08-02 14:20:21 -07001257 << ">::onTransact(\n";
1258
1259 out.indent();
1260 out.indent();
1261
Iliyan Malchev549e2592016-08-10 08:59:12 -07001262 out << "_hidl_code, _hidl_data, _hidl_reply, "
1263 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001264
1265 out.unindent();
1266 out.unindent();
1267
1268 out.unindent();
1269 out << "}\n";
1270
1271 out.unindent();
1272 out << "}\n\n";
1273
Iliyan Malchev549e2592016-08-10 08:59:12 -07001274 out << "if (_hidl_err == ::android::UNEXPECTED_NULL) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001275 out.indent();
Yifan Hong859e53f2016-11-14 19:08:24 -08001276 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001277 out.indent();
1278 out.indent();
Yifan Hong859e53f2016-11-14 19:08:24 -08001279 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1280 out << "_hidl_reply);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001281 out.unindent();
1282 out.unindent();
1283
1284 out.unindent();
1285 out << "}\n\n";
1286
Iliyan Malchev549e2592016-08-10 08:59:12 -07001287 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001288
1289 out.unindent();
1290 out << "}\n\n";
1291
1292 return OK;
1293}
1294
1295status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001296 Formatter &out, const Interface *iface, const Method *method) const {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001297 out << "if (!_hidl_data.enforceInterface(";
1298
Yifan Hongc8934042016-11-17 17:10:52 -08001299 out << iface->fqName().cppNamespace()
1300 << "::I"
1301 << iface->getBaseName();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001302
1303 out << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001304
Andreas Huber881227d2016-08-02 14:20:21 -07001305 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001306 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001307 out << "break;\n";
1308 out.unindent();
1309 out << "}\n\n";
1310
Andreas Huber5e44a292016-09-27 14:52:39 -07001311 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001312
Yifan Hongbf459bc2016-08-23 16:50:37 -07001313 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001314 for (const auto &arg : method->args()) {
1315 emitCppReaderWriter(
1316 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001317 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001318 false /* parcelObjIsPointer */,
1319 arg,
1320 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001321 Type::ErrorMode_Break,
1322 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001323 }
1324
Yifan Hongbf459bc2016-08-23 16:50:37 -07001325 // Second DFS: resolve references
1326 for (const auto &arg : method->args()) {
1327 emitCppResolveReferences(
1328 out,
1329 "_hidl_data",
1330 false /* parcelObjIsPointer */,
1331 arg,
1332 true /* reader */,
1333 Type::ErrorMode_Break,
1334 false /* addPrefixToName */);
1335 }
1336
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001337 status_t status = generateCppInstrumentationCall(
1338 out,
1339 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001340 method);
1341 if (status != OK) {
1342 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001343 }
1344
Andreas Huber881227d2016-08-02 14:20:21 -07001345 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001346 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001347
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001348 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001349 out << elidedReturn->type().getCppResultType()
1350 << " "
1351 << elidedReturn->name()
1352 << " = "
1353 << method->name()
1354 << "(";
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()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001358 if (!first) {
1359 out << ", ";
1360 }
1361
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001362 if (arg->type().resultNeedsDeref()) {
1363 out << "*";
1364 }
1365
1366 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001367
1368 first = false;
1369 }
1370
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001371 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001372 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1373 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001374
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001375 elidedReturn->type().emitReaderWriter(
1376 out,
1377 elidedReturn->name(),
1378 "_hidl_reply",
1379 true, /* parcelObjIsPointer */
1380 false, /* isReader */
1381 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001382
Yifan Hongbf459bc2016-08-23 16:50:37 -07001383 emitCppResolveReferences(
1384 out,
1385 "_hidl_reply",
1386 true /* parcelObjIsPointer */,
1387 elidedReturn,
1388 false /* reader */,
1389 Type::ErrorMode_Ignore,
1390 false /* addPrefixToName */);
1391
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001392 status_t status = generateCppInstrumentationCall(
1393 out,
1394 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001395 method);
1396 if (status != OK) {
1397 return status;
1398 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001399
Iliyan Malchev549e2592016-08-10 08:59:12 -07001400 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001401 } else {
1402 if (returnsValue) {
1403 out << "bool _hidl_callbackCalled = false;\n\n";
1404 }
Andreas Huber881227d2016-08-02 14:20:21 -07001405
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001406 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001407
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001408 bool first = true;
1409 for (const auto &arg : method->args()) {
1410 if (!first) {
1411 out << ", ";
1412 }
Andreas Huber881227d2016-08-02 14:20:21 -07001413
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001414 if (arg->type().resultNeedsDeref()) {
1415 out << "*";
1416 }
1417
1418 out << arg->name();
1419
1420 first = false;
1421 }
1422
1423 if (returnsValue) {
1424 if (!first) {
1425 out << ", ";
1426 }
1427
1428 out << "[&](";
1429
1430 first = true;
1431 for (const auto &arg : method->results()) {
1432 if (!first) {
1433 out << ", ";
1434 }
1435
1436 out << "const auto &" << arg->name();
1437
1438 first = false;
1439 }
1440
1441 out << ") {\n";
1442 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001443 out << "if (_hidl_callbackCalled) {\n";
1444 out.indent();
1445 out << "LOG_ALWAYS_FATAL(\""
1446 << method->name()
1447 << ": _hidl_cb called a second time, but must be called once.\");\n";
1448 out.unindent();
1449 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001450 out << "_hidl_callbackCalled = true;\n\n";
1451
Yifan Hong859e53f2016-11-14 19:08:24 -08001452 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1453 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001454
Yifan Hongbf459bc2016-08-23 16:50:37 -07001455 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001456 for (const auto &arg : method->results()) {
1457 emitCppReaderWriter(
1458 out,
1459 "_hidl_reply",
1460 true /* parcelObjIsPointer */,
1461 arg,
1462 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001463 Type::ErrorMode_Ignore,
1464 false /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001465 }
1466
Yifan Hongbf459bc2016-08-23 16:50:37 -07001467 // Second DFS: resolve references
1468 for (const auto &arg : method->results()) {
1469 emitCppResolveReferences(
1470 out,
1471 "_hidl_reply",
1472 true /* parcelObjIsPointer */,
1473 arg,
1474 false /* reader */,
1475 Type::ErrorMode_Ignore,
1476 false /* addPrefixToName */);
1477 }
1478
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001479 status_t status = generateCppInstrumentationCall(
1480 out,
1481 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001482 method);
1483 if (status != OK) {
1484 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001485 }
1486
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001487 out << "_hidl_cb(*_hidl_reply);\n";
1488
1489 out.unindent();
1490 out << "}\n";
1491 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001492 out << ");\n\n";
1493
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001494 if (returnsValue) {
1495 out << "if (!_hidl_callbackCalled) {\n";
1496 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001497 out << "LOG_ALWAYS_FATAL(\""
1498 << method->name()
1499 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001500 out.unindent();
1501 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001502 } else {
1503 out << "::android::hardware::writeToParcel("
1504 << "::android::hardware::Status::ok(), "
1505 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001506 }
Andreas Huber881227d2016-08-02 14:20:21 -07001507 }
1508
1509 out << "break;\n";
1510
1511 return OK;
1512}
1513
Steven Moreland69e7c702016-09-09 11:16:32 -07001514status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1515 std::string ifaceName;
1516 if (!AST::isInterface(&ifaceName)) {
1517 // types.hal does not get a stub header.
1518 return OK;
1519 }
1520
1521 const Interface *iface = mRootScope->getInterface();
1522
1523 const std::string baseName = iface->getBaseName();
1524 const std::string klassName = "Bs" + baseName;
1525
1526 bool supportOneway = iface->hasOnewayMethods();
1527
1528 std::string path = outputPath;
1529 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1530 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1531 path.append(klassName);
1532 path.append(".h");
1533
1534 CHECK(Coordinator::MakeParentHierarchy(path));
1535 FILE *file = fopen(path.c_str(), "w");
1536
1537 if (file == NULL) {
1538 return -errno;
1539 }
1540
1541 Formatter out(file);
1542
1543 const std::string guard = makeHeaderGuard(klassName);
1544
1545 out << "#ifndef " << guard << "\n";
1546 out << "#define " << guard << "\n\n";
1547
1548 std::vector<std::string> packageComponents;
1549 getPackageAndVersionComponents(
1550 &packageComponents, false /* cpp_compatible */);
1551
1552 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001553
1554 generateCppPackageInclude(out, mPackage, ifaceName);
1555 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001556
1557 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001558 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001559 }
1560
1561 enterLeaveNamespace(out, true /* enter */);
1562 out << "\n";
1563
1564 out << "struct "
1565 << klassName
1566 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001567 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001568
1569 out.indent();
1570 out << "explicit "
1571 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001572 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001573 << ifaceName
1574 << "> impl);\n";
1575
Yifan Hong068c5522016-10-31 14:07:25 -07001576 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1577 return generatePassthroughMethod(out, method);
1578 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001579
1580 if (err != OK) {
1581 return err;
1582 }
1583
1584 out.unindent();
1585 out << "private:\n";
1586 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001587 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001588
1589 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001590 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001591
1592 out << "\n";
1593
1594 out << "::android::hardware::Return<void> addOnewayTask("
1595 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001596 }
1597
1598 out.unindent();
1599
1600 out << "};\n\n";
1601
1602 enterLeaveNamespace(out, false /* enter */);
1603
1604 out << "\n#endif // " << guard << "\n";
1605
1606 return OK;
1607}
1608
Yifan Hongfe95aa22016-10-19 17:26:45 -07001609status_t AST::generateInterfaceSource(Formatter &out) const {
1610 const Interface *iface = mRootScope->getInterface();
1611
Yifan Hong2d7126b2016-10-20 15:12:57 -07001612 // generate castFrom functions
Yifan Hongfe95aa22016-10-19 17:26:45 -07001613 if (!iface->isRootType()) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001614 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001615
1616 for (const Interface *superType : iface->superTypeChain()) {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001617 out << "// static \n"
1618 << childTypeResult
1619 << " I"
1620 << iface->getBaseName()
1621 << "::castFrom("
Yifan Hong3b320f82016-11-01 15:15:54 -07001622 << superType->getCppArgumentType()
1623 << " parent) {\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001624 out.indent();
1625 out << "return ::android::hardware::castInterface<";
1626 out << "I" << iface->getBaseName() << ", "
1627 << superType->fqName().cppName() << ", "
Yifan Hong158655a2016-11-08 12:34:07 -08001628 << "Bp" << iface->getBaseName() << ", "
1629 << superType->getHwName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001630 << ">(\n";
1631 out.indent();
1632 out.indent();
1633 out << "parent, \""
1634 << iface->fqName().string()
1635 << "\");\n";
1636 out.unindent();
1637 out.unindent();
1638 out.unindent();
1639 out << "}\n\n";
1640 }
1641 }
1642
1643 return OK;
1644}
1645
Steven Moreland69e7c702016-09-09 11:16:32 -07001646status_t AST::generatePassthroughSource(Formatter &out) const {
1647 const Interface *iface = mRootScope->getInterface();
1648
1649 const std::string baseName = iface->getBaseName();
1650 const std::string klassName = "Bs" + baseName;
1651
1652 out << klassName
1653 << "::"
1654 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001655 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001656 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001657 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001658 << iface->fqName().string()
1659 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001660 if (iface->hasOnewayMethods()) {
1661 out << "\n";
1662 out.indentBlock([&] {
1663 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1664 });
1665 }
1666 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001667
1668 if (iface->hasOnewayMethods()) {
1669 out << "::android::hardware::Return<void> "
1670 << klassName
1671 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1672 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001673 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001674 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001675 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1676 out.indent();
1677 out.indent();
1678 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1679 out.unindent();
1680 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001681 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001682 out << "}\n";
1683
Steven Morelandd366c262016-10-11 15:29:10 -07001684 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001685
1686 out.unindent();
1687 out << "}\n\n";
1688
1689
1690 }
1691
1692 return OK;
1693}
1694
Martijn Coenen7b295242016-11-04 16:52:56 +01001695status_t AST::generateCppAtraceCall(Formatter &out,
1696 InstrumentationEvent event,
1697 const Method *method) const {
1698 const Interface *iface = mRootScope->getInterface();
1699 std::string baseString = "HIDL::I" + iface->getBaseName() + "::" + method->name();
1700 switch (event) {
1701 case SERVER_API_ENTRY:
1702 {
1703 out << "atrace_begin(ATRACE_TAG_HAL, \""
1704 << baseString + "::server\");\n";
1705 break;
1706 }
1707 case CLIENT_API_ENTRY:
1708 {
1709 out << "atrace_begin(ATRACE_TAG_HAL, \""
1710 << baseString + "::client\");\n";
1711 break;
1712 }
1713 case PASSTHROUGH_ENTRY:
1714 {
1715 out << "atrace_begin(ATRACE_TAG_HAL, \""
1716 << baseString + "::passthrough\");\n";
1717 break;
1718 }
1719 case SERVER_API_EXIT:
1720 case CLIENT_API_EXIT:
1721 case PASSTHROUGH_EXIT:
1722 {
1723 out << "atrace_end(ATRACE_TAG_HAL);\n";
1724 break;
1725 }
1726 default:
1727 {
1728 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1729 return UNKNOWN_ERROR;
1730 }
1731 }
1732
1733 return OK;
1734}
1735
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001736status_t AST::generateCppInstrumentationCall(
1737 Formatter &out,
1738 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001739 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001740 status_t err = generateCppAtraceCall(out, event, method);
1741 if (err != OK) {
1742 return err;
1743 }
1744
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001745 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1746 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001747 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001748 std::string event_str = "";
1749 switch (event) {
1750 case SERVER_API_ENTRY:
1751 {
1752 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1753 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001754 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001755 << (arg->type().resultNeedsDeref() ? "" : "&")
1756 << arg->name()
1757 << ");\n";
1758 }
1759 break;
1760 }
1761 case SERVER_API_EXIT:
1762 {
1763 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001764 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001765 out << "_hidl_args.push_back((void *)&"
Steven Moreland031ccf12016-10-31 15:54:38 -07001766 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001767 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001768 }
1769 break;
1770 }
1771 case CLIENT_API_ENTRY:
1772 {
1773 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1774 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001775 out << "_hidl_args.push_back((void *)&"
1776 << arg->name()
1777 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001778 }
1779 break;
1780 }
1781 case CLIENT_API_EXIT:
1782 {
1783 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1784 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001785 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001786 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001787 << "_hidl_out_"
1788 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001789 << ");\n";
1790 }
1791 break;
1792 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001793 case PASSTHROUGH_ENTRY:
1794 {
1795 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1796 for (const auto &arg : method->args()) {
1797 out << "_hidl_args.push_back((void *)&"
1798 << arg->name()
1799 << ");\n";
1800 }
1801 break;
1802 }
1803 case PASSTHROUGH_EXIT:
1804 {
1805 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001806 for (const auto &arg : method->results()) {
1807 out << "_hidl_args.push_back((void *)&"
1808 << arg->name()
1809 << ");\n";
1810 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001811 break;
1812 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001813 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001814 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001815 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001816 return UNKNOWN_ERROR;
1817 }
1818 }
1819
Steven Moreland031ccf12016-10-31 15:54:38 -07001820 const Interface *iface = mRootScope->getInterface();
1821
Steven Moreland1ab31442016-11-03 18:37:51 -07001822 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001823 out.indent();
1824 out << "callback("
1825 << event_str
1826 << ", \""
1827 << mPackage.package()
1828 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07001829 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001830 << "\", \""
1831 << iface->localName()
1832 << "\", \""
1833 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001834 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001835 out.unindent();
1836 out << "}\n";
1837 out.unindent();
1838 out << "}\n\n";
1839
1840 return OK;
1841}
1842
Andreas Huber881227d2016-08-02 14:20:21 -07001843} // namespace android
1844