blob: 4d7a444a87e5194c6874ab86068ea99ef449f024 [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) {
Steven Moreland0693f312016-11-09 15:06:14 -0800177 out << "#include <hidl/ServiceManagement.h>\n";
Martijn Coenen93915102016-09-01 01:35:52 +0200178 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700179 }
180
Martijn Coenenaf712c02016-11-16 15:26:27 +0100181 out << "#include <utils/NativeHandle.h>\n";
182 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700183
184 enterLeaveNamespace(out, true /* enter */);
185 out << "\n";
186
187 if (isInterface) {
188 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700189 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700190
191 const Interface *iface = mRootScope->getInterface();
192 const Interface *superType = iface->superType();
193
Steven Moreland40786312016-08-16 10:29:40 -0700194 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800195 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700196 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000197 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700198 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700199 }
200
201 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700202
203 out.indent();
204
Andreas Huber881227d2016-08-02 14:20:21 -0700205 }
206
207 status_t err = emitTypeDeclarations(out);
208
209 if (err != OK) {
210 return err;
211 }
212
213 if (isInterface) {
214 const Interface *iface = mRootScope->getInterface();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700215 const Interface *superType = iface->superType();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700216 const std::string baseName = iface->getBaseName();
Steven Moreland19d5c172016-10-20 19:20:25 -0700217 out << "constexpr static ::android::hardware::hidl_version version = {"
Martijn Coenena21f1492016-09-08 15:55:14 +0200218 << mPackage.getPackageMajorVersion() << ","
219 << mPackage.getPackageMinorVersion() << "};\n";
Steven Moreland19d5c172016-10-20 19:20:25 -0700220 out << "virtual const ::android::hardware::hidl_version&"
221 << "getInterfaceVersion() const {\n";
Martijn Coenena21f1492016-09-08 15:55:14 +0200222 out.indent();
223 out << "return version;\n";
224 out.unindent();
225 out << "}\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800226 out << "virtual bool isRemote() const ";
227 if (!isIBase()) {
228 out << "override ";
229 }
230 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800231
Andreas Huber881227d2016-08-02 14:20:21 -0700232 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700233 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700234
Andreas Huber881227d2016-08-02 14:20:21 -0700235 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800236 const TypedVar *elidedReturn = method->canElideCallback();
237
238 if (elidedReturn == nullptr && returnsValue) {
239 out << "using "
240 << method->name()
241 << "_cb = std::function<void("
242 << Method::GetArgSignature(method->results(),
243 true /* specify namespaces */)
244 << ")>;\n";
245 }
Andreas Huber881227d2016-08-02 14:20:21 -0700246
Andreas Huber3599d922016-08-09 10:42:57 -0700247 method->dumpAnnotations(out);
248
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700249 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700250 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700251 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700252 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700253 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700254 }
255
256 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700257 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700258 << Method::GetArgSignature(method->args(),
259 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700260
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700261 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700262 if (!method->args().empty()) {
263 out << ", ";
264 }
265
Steven Moreland67f67b42016-09-29 08:59:02 -0700266 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700267 }
268
Yifan Hong10fe0b52016-10-19 14:20:17 -0700269 out << ")";
270 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800271 if (!isIBase()) {
272 out << " override";
273 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700274 out << " {\n";
275 out.indent();
276 method->cppImpl(out);
277 out.unindent();
278 out << "\n}\n";
279 } else {
280 out << " = 0;\n";
281 }
Andreas Huber881227d2016-08-02 14:20:21 -0700282 }
Steven Moreland40786312016-08-16 10:29:40 -0700283
Yifan Hongfe95aa22016-10-19 17:26:45 -0700284 if (!iface->isRootType()) {
285 out << "// cast static functions\n";
Yifan Hong3b320f82016-11-01 15:15:54 -0700286 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700287
288 for (const Interface *superType : iface->superTypeChain()) {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700289 out << "static "
290 << childTypeResult
291 << " castFrom("
Yifan Hong3b320f82016-11-01 15:15:54 -0700292 << superType->getCppArgumentType()
Yifan Hongfe95aa22016-10-19 17:26:45 -0700293 << " parent"
Yifan Hongfe95aa22016-10-19 17:26:45 -0700294 << ");\n";
295 }
296 }
297
Steven Morelandd39133b2016-11-11 12:30:08 -0800298 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700299
Yifan Hongc8934042016-11-17 17:10:52 -0800300 if (isIBase()) {
301 out << "// skipped DECLARE_SERVICE_MANAGER_INTERACTIONS\n\n";
302 } else {
303 out << "DECLARE_SERVICE_MANAGER_INTERACTIONS(" << baseName << ")\n\n";
304 }
Yifan Hong158655a2016-11-08 12:34:07 -0800305
306 out << "private: static int hidlStaticBlock;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700307 }
308
309 if (isInterface) {
310 out.unindent();
311
Andreas Hubere3f769a2016-10-10 10:54:44 -0700312 out << "};\n\n";
313 }
314
315 err = mRootScope->emitGlobalTypeDeclarations(out);
316
317 if (err != OK) {
318 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700319 }
320
321 out << "\n";
322 enterLeaveNamespace(out, false /* enter */);
323
324 out << "\n#endif // " << guard << "\n";
325
326 return OK;
327}
328
Steven Moreland40786312016-08-16 10:29:40 -0700329status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
330 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800331 bool isInterface = AST::isInterface(&ifaceName);
332 const Interface *iface = nullptr;
333 std::string baseName{};
334 std::string klassName{};
335
336 if(isInterface) {
337 iface = mRootScope->getInterface();
338 baseName = iface->getBaseName();
339 klassName = "IHw" + baseName;
340 } else {
341 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700342 }
343
Steven Moreland40786312016-08-16 10:29:40 -0700344 std::string path = outputPath;
345 path.append(mCoordinator->convertPackageRootToPath(mPackage));
346 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
347 path.append(klassName + ".h");
348
Yifan Hong244e82d2016-11-11 11:13:57 -0800349 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700350
351 if (file == NULL) {
352 return -errno;
353 }
354
355 Formatter out(file);
356
357 const std::string guard = makeHeaderGuard(klassName);
358
359 out << "#ifndef " << guard << "\n";
360 out << "#define " << guard << "\n\n";
361
Yifan Hong244e82d2016-11-11 11:13:57 -0800362 if (isInterface) {
363 generateCppPackageInclude(out, mPackage, ifaceName);
364 } else {
365 generateCppPackageInclude(out, mPackage, "types");
366 }
Steven Moreland40786312016-08-16 10:29:40 -0700367
Steven Morelandee88eed2016-10-31 17:49:00 -0700368 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700369
370 for (const auto &item : mImportedNames) {
371 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800372 generateCppPackageInclude(out, item, "hwtypes");
373 } else {
374 generateCppPackageInclude(out, item, "Bn" + item.getInterfaceBaseName());
Steven Moreland40786312016-08-16 10:29:40 -0700375 }
Steven Moreland40786312016-08-16 10:29:40 -0700376 }
377
378 out << "\n";
379
Yifan Hong859e53f2016-11-14 19:08:24 -0800380 out << "#include <hidl/HidlTransportSupport.h>\n";
Martijn Coenen93915102016-09-01 01:35:52 +0200381 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700382 out << "#include <hwbinder/IBinder.h>\n";
383 out << "#include <hwbinder/IInterface.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700384
385 out << "\n";
386
387 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700388
Yifan Hong244e82d2016-11-11 11:13:57 -0800389 if (isInterface) {
390 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700391
Yifan Hong244e82d2016-11-11 11:13:57 -0800392 out << "struct "
393 << klassName
394 << " : public "
395 << ifaceName;
Steven Moreland40786312016-08-16 10:29:40 -0700396
Yifan Hong244e82d2016-11-11 11:13:57 -0800397 const Interface *superType = iface->superType();
Steven Moreland40786312016-08-16 10:29:40 -0700398
Yifan Hong244e82d2016-11-11 11:13:57 -0800399 out << ", public ::android::hardware::IInterface";
Steven Moreland40786312016-08-16 10:29:40 -0700400
Yifan Hong244e82d2016-11-11 11:13:57 -0800401 out << " {\n";
Steven Moreland40786312016-08-16 10:29:40 -0700402
Yifan Hong244e82d2016-11-11 11:13:57 -0800403 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700404
Yifan Hong244e82d2016-11-11 11:13:57 -0800405 out << "DECLARE_HWBINDER_META_INTERFACE(" << baseName << ");\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700406
Yifan Hong244e82d2016-11-11 11:13:57 -0800407 out.unindent();
408
409 out << "};\n\n";
410 }
411
412 status_t err = mRootScope->emitGlobalHwDeclarations(out);
413 if (err != OK) {
414 return err;
415 }
Steven Moreland40786312016-08-16 10:29:40 -0700416
417 enterLeaveNamespace(out, false /* enter */);
418
419 out << "\n#endif // " << guard << "\n";
420
421 return OK;
422}
423
Andreas Huber881227d2016-08-02 14:20:21 -0700424status_t AST::emitTypeDeclarations(Formatter &out) const {
425 return mRootScope->emitTypeDeclarations(out);
426}
427
Steven Morelanda7a421a2016-09-07 08:35:18 -0700428status_t AST::generateStubMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700429 const Method *method) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700430 out << "inline ";
431
Yifan Hong068c5522016-10-31 14:07:25 -0700432 method->generateCppSignature(out);
Steven Morelanda7a421a2016-09-07 08:35:18 -0700433
434 const bool returnsValue = !method->results().empty();
435 const TypedVar *elidedReturn = method->canElideCallback();
436 out << " {\n";
437 out.indent();
438 out << "return mImpl->"
439 << method->name()
440 << "(";
441 bool first = true;
442 for (const auto &arg : method->args()) {
443 if (!first) {
444 out << ", ";
445 }
446 first = false;
447 out << arg->name();
448 }
449 if (returnsValue && elidedReturn == nullptr) {
450 if (!method->args().empty()) {
451 out << ", ";
452 }
453
454 out << "_hidl_cb";
455 }
456 out << ");\n";
457 out.unindent();
458 out << "}";
459
460 out << ";\n";
461
462 return OK;
463}
464
Steven Moreland69e7c702016-09-09 11:16:32 -0700465status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700466 const Method *method) const {
467 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700468
469 out << " {\n";
470 out.indent();
471
472 const bool returnsValue = !method->results().empty();
473 const TypedVar *elidedReturn = method->canElideCallback();
474
Steven Moreland67f67b42016-09-29 08:59:02 -0700475 if (returnsValue && elidedReturn == nullptr) {
476 generateCheckNonNull(out, "_hidl_cb");
477 }
478
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700479 generateCppInstrumentationCall(
480 out,
481 InstrumentationEvent::PASSTHROUGH_ENTRY,
482 method);
483
484 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700485
486 if (method->isOneway()) {
487 out << "addOnewayTask([this";
488 for (const auto &arg : method->args()) {
489 out << ", " << arg->name();
490 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700491 out << "] {\n";
492 out.indent();
493 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700494 }
495
496 out << "mImpl->"
497 << method->name()
498 << "(";
499
500 bool first = true;
501 for (const auto &arg : method->args()) {
502 if (!first) {
503 out << ", ";
504 }
505 first = false;
506 out << arg->name();
507 }
508 if (returnsValue && elidedReturn == nullptr) {
509 if (!method->args().empty()) {
510 out << ", ";
511 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800512 out << "[&](";
513 first = true;
514 for (const auto &arg : method->results()) {
515 if (!first) {
516 out << ", ";
517 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700518
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800519 out << "const auto &" << arg->name();
520
521 first = false;
522 }
523
524 out << ") {\n";
525 out.indent();
526 status_t status = generateCppInstrumentationCall(
527 out,
528 InstrumentationEvent::PASSTHROUGH_EXIT,
529 method);
530 if (status != OK) {
531 return status;
532 }
533
534 out << "_hidl_cb(";
535 first = true;
536 for (const auto &arg : method->results()) {
537 if (!first) {
538 out << ", ";
539 }
540
541 out << arg->name();
542
543 first = false;
544 }
545 out << ");\n";
546 out.unindent();
547 out << "});\n\n";
548 } else {
549 out << ");\n\n";
550 if (elidedReturn != nullptr) {
551 out << elidedReturn->type().getCppResultType()
552 << " "
553 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000554 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800555 }
556 status_t status = generateCppInstrumentationCall(
557 out,
558 InstrumentationEvent::PASSTHROUGH_EXIT,
559 method);
560 if (status != OK) {
561 return status;
562 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700563 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700564
565 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700566 out.unindent();
567 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700568 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700569
570 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700571
572 out.unindent();
573 out << "}\n";
574
575 return OK;
576}
577
Yifan Hong068c5522016-10-31 14:07:25 -0700578status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700579
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700580 const Interface *iface = mRootScope->getInterface();
581
Yifan Hong10fe0b52016-10-19 14:20:17 -0700582 const Interface *prevIterface = nullptr;
583 for (const auto &tuple : iface->allMethodsFromRoot()) {
584 const Method *method = tuple.method();
585 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700586
Yifan Hong10fe0b52016-10-19 14:20:17 -0700587 if(prevIterface != superInterface) {
588 if (prevIterface != nullptr) {
589 out << "\n";
590 }
591 out << "// Methods from "
592 << superInterface->fullName()
593 << " follow.\n";
594 prevIterface = superInterface;
595 }
Yifan Hong068c5522016-10-31 14:07:25 -0700596 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700597
Yifan Hong10fe0b52016-10-19 14:20:17 -0700598 if (err != OK) {
599 return err;
600 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700601 }
602
Yifan Hong10fe0b52016-10-19 14:20:17 -0700603 out << "\n";
604
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700605 return OK;
606}
607
Andreas Huberb82318c2016-08-02 14:45:54 -0700608status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700609 std::string ifaceName;
610 if (!AST::isInterface(&ifaceName)) {
611 // types.hal does not get a stub header.
612 return OK;
613 }
614
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700615 const Interface *iface = mRootScope->getInterface();
616 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700617 const std::string klassName = "Bn" + baseName;
Andreas Huber881227d2016-08-02 14:20:21 -0700618
Andreas Huberb82318c2016-08-02 14:45:54 -0700619 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700620 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700621 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700622 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700623 path.append(".h");
624
Andreas Huberd2943e12016-08-05 11:59:31 -0700625 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700626 FILE *file = fopen(path.c_str(), "w");
627
628 if (file == NULL) {
629 return -errno;
630 }
631
632 Formatter out(file);
633
Steven Moreland40786312016-08-16 10:29:40 -0700634 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700635
636 out << "#ifndef " << guard << "\n";
637 out << "#define " << guard << "\n\n";
638
Steven Morelandee88eed2016-10-31 17:49:00 -0700639 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
640 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700641
642 enterLeaveNamespace(out, true /* enter */);
643 out << "\n";
644
645 out << "struct "
646 << "Bn"
647 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700648 << " : public ::android::hardware::BnInterface<I"
649 << baseName << ", IHw" << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700650 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700651
652 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700653 out << "explicit Bn"
654 << baseName
655 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
656 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700657 out << "::android::status_t onTransact(\n";
658 out.indent();
659 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700660 out << "uint32_t _hidl_code,\n";
661 out << "const ::android::hardware::Parcel &_hidl_data,\n";
662 out << "::android::hardware::Parcel *_hidl_reply,\n";
663 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700664 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700665 out.unindent();
666 out.unindent();
667
Yifan Hong068c5522016-10-31 14:07:25 -0700668 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
669 return generateStubMethod(out, method);
670 });
Steven Moreland9c387612016-09-07 09:54:26 -0700671
672 if (err != OK) {
673 return err;
674 }
675
Zhuoyao Zhangde578002016-09-07 18:24:17 -0700676
Andreas Huber881227d2016-08-02 14:20:21 -0700677 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700678 out << "};\n\n";
679
680 enterLeaveNamespace(out, false /* enter */);
681
682 out << "\n#endif // " << guard << "\n";
683
684 return OK;
685}
686
Andreas Huberb82318c2016-08-02 14:45:54 -0700687status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700688 std::string ifaceName;
689 if (!AST::isInterface(&ifaceName)) {
690 // types.hal does not get a proxy header.
691 return OK;
692 }
693
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700694 const Interface *iface = mRootScope->getInterface();
695 const std::string baseName = iface->getBaseName();
Andreas Huber881227d2016-08-02 14:20:21 -0700696
Andreas Huberb82318c2016-08-02 14:45:54 -0700697 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700698 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700699 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700700 path.append("Bp");
701 path.append(baseName);
702 path.append(".h");
703
Andreas Huberd2943e12016-08-05 11:59:31 -0700704 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700705 FILE *file = fopen(path.c_str(), "w");
706
707 if (file == NULL) {
708 return -errno;
709 }
710
711 Formatter out(file);
712
713 const std::string guard = makeHeaderGuard("Bp" + baseName);
714
715 out << "#ifndef " << guard << "\n";
716 out << "#define " << guard << "\n\n";
717
718 std::vector<std::string> packageComponents;
719 getPackageAndVersionComponents(
720 &packageComponents, false /* cpp_compatible */);
721
Steven Morelandee88eed2016-10-31 17:49:00 -0700722 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
723 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700724
725 enterLeaveNamespace(out, true /* enter */);
726 out << "\n";
727
728 out << "struct "
729 << "Bp"
730 << baseName
Steven Moreland40786312016-08-16 10:29:40 -0700731 << " : public ::android::hardware::BpInterface<IHw"
732 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700733 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700734
735 out.indent();
736
737 out << "explicit Bp"
738 << baseName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700739 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700740 << "\n\n";
741
Yifan Hong10fe0b52016-10-19 14:20:17 -0700742 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700743
Yifan Hong068c5522016-10-31 14:07:25 -0700744 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
745 method->generateCppSignature(out);
746 out << " override;\n";
747 return OK;
748 });
Steven Moreland9c387612016-09-07 09:54:26 -0700749
750 if (err != OK) {
751 return err;
752 }
Andreas Huber881227d2016-08-02 14:20:21 -0700753
754 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700755 out << "};\n\n";
756
757 enterLeaveNamespace(out, false /* enter */);
758
759 out << "\n#endif // " << guard << "\n";
760
761 return OK;
762}
763
Andreas Huberb82318c2016-08-02 14:45:54 -0700764status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700765
Andreas Huberb82318c2016-08-02 14:45:54 -0700766 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700767 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700768 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700769
770 std::string ifaceName;
771 std::string baseName;
772
Yifan Hongfe95aa22016-10-19 17:26:45 -0700773 const Interface *iface = nullptr;
774 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700775 if (!AST::isInterface(&ifaceName)) {
776 baseName = "types";
777 isInterface = false;
778 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700779 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700780 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700781 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700782 }
783
784 path.append(baseName);
785
786 if (baseName != "types") {
787 path.append("All");
788 }
789
790 path.append(".cpp");
791
Andreas Huberd2943e12016-08-05 11:59:31 -0700792 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700793 FILE *file = fopen(path.c_str(), "w");
794
795 if (file == NULL) {
796 return -errno;
797 }
798
799 Formatter out(file);
800
Steven Moreland05cd4232016-11-21 16:01:12 -0800801 out << "#include <android/log.h>\n";
Martijn Coenen7b295242016-11-04 16:52:56 +0100802 out << "#include <cutils/trace.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700803 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700804 // This is a no-op for IServiceManager itself.
805 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
806
Steven Morelandee88eed2016-10-31 17:49:00 -0700807 generateCppPackageInclude(out, mPackage, "Bp" + baseName);
808 generateCppPackageInclude(out, mPackage, "Bn" + baseName);
809 generateCppPackageInclude(out, mPackage, "Bs" + baseName);
Yifan Hongfe95aa22016-10-19 17:26:45 -0700810
811 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700812 generateCppPackageInclude(out,
813 superType->fqName(),
814 "Bp" + superType->getBaseName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700815 }
Andreas Huber881227d2016-08-02 14:20:21 -0700816 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700817 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800818 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700819 }
820
821 out << "\n";
822
823 enterLeaveNamespace(out, true /* enter */);
824 out << "\n";
825
826 status_t err = generateTypeSource(out, ifaceName);
827
828 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700829 const Interface *iface = mRootScope->getInterface();
Steven Moreland19d5c172016-10-20 19:20:25 -0700830 out << "constexpr ::android::hardware::hidl_version "
831 << ifaceName
832 << "::version;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700833
834 // need to be put here, generateStubSource is using this.
Steven Morelandd39133b2016-11-11 12:30:08 -0800835 out << "const char* I"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700836 << iface->getBaseName()
837 << "::descriptor(\""
838 << iface->fqName().string()
839 << "\");\n\n";
840
Yifan Hong158655a2016-11-08 12:34:07 -0800841 out << "int I"
842 << iface->getBaseName()
843 << "::hidlStaticBlock = []() -> int {\n";
844 out.indentBlock([&] {
Steven Morelandd39133b2016-11-11 12:30:08 -0800845 out << "::android::hardware::gBnConstructorMap[I"
Yifan Hong158655a2016-11-08 12:34:07 -0800846 << iface->getBaseName()
Steven Morelandd39133b2016-11-11 12:30:08 -0800847 << "::descriptor]\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800848 out.indentBlock(2, [&] {
849 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
850 out.indentBlock([&] {
851 out << "return new Bn"
852 << iface->getBaseName()
853 << "(reinterpret_cast<I"
854 << iface->getBaseName()
855 << " *>(iIntf));\n";
856 });
857 out << "};\n";
858 });
859 out << "return 1;\n";
860 });
861 out << "}();\n\n";
862
Yifan Hongfe95aa22016-10-19 17:26:45 -0700863 err = generateInterfaceSource(out);
864 }
865
866 if (err == OK && isInterface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700867 err = generateProxySource(out, baseName);
868 }
869
870 if (err == OK && isInterface) {
871 err = generateStubSource(out, baseName);
872 }
873
Steven Moreland40786312016-08-16 10:29:40 -0700874 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -0700875 err = generatePassthroughSource(out);
876 }
877
878 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -0700879 const Interface *iface = mRootScope->getInterface();
880
Yifan Hongc8934042016-11-17 17:10:52 -0800881 if (isIBase()) {
882 out << "// skipped IMPLEMENT_SERVICE_MANAGER_INTERACTIONS\n";
883 } else {
884 out << "IMPLEMENT_SERVICE_MANAGER_INTERACTIONS("
885 << baseName << ", "
886 << "\"" << iface->fqName().package()
887 << iface->fqName().atVersion()
888 << "\")\n";
889 }
Steven Moreland40786312016-08-16 10:29:40 -0700890 }
891
Andreas Huber881227d2016-08-02 14:20:21 -0700892 enterLeaveNamespace(out, false /* enter */);
893
894 return err;
895}
896
Steven Moreland67f67b42016-09-29 08:59:02 -0700897// static
898void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
899 out << "if (" << nonNull << " == nullptr) {\n";
900 out.indent();
901 out << "return ::android::hardware::Status::fromExceptionCode(\n";
902 out.indent();
903 out.indent();
904 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
905 out.unindent();
906 out.unindent();
907 out.unindent();
908 out << "}\n\n";
909}
910
Andreas Huber881227d2016-08-02 14:20:21 -0700911status_t AST::generateTypeSource(
912 Formatter &out, const std::string &ifaceName) const {
913 return mRootScope->emitTypeDefinitions(out, ifaceName);
914}
915
Andreas Hubere7ff2282016-08-16 13:50:03 -0700916void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -0700917 Formatter &out,
918 const std::vector<TypedVar *> &args,
919 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700920 if (args.empty()) {
921 return;
922 }
923
924 for (const auto &arg : args) {
925 const Type &type = arg->type();
926
Yifan Hong3b320f82016-11-01 15:15:54 -0700927 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700928 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700929 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700930 << ";\n";
931 }
932
933 out << "\n";
934}
935
Andreas Huber881227d2016-08-02 14:20:21 -0700936void AST::emitCppReaderWriter(
937 Formatter &out,
938 const std::string &parcelObj,
939 bool parcelObjIsPointer,
940 const TypedVar *arg,
941 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -0700942 Type::ErrorMode mode,
943 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700944 const Type &type = arg->type();
945
Andreas Huber881227d2016-08-02 14:20:21 -0700946 type.emitReaderWriter(
947 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700948 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700949 parcelObj,
950 parcelObjIsPointer,
951 isReader,
952 mode);
953}
954
Yifan Hongbf459bc2016-08-23 16:50:37 -0700955void AST::emitCppResolveReferences(
956 Formatter &out,
957 const std::string &parcelObj,
958 bool parcelObjIsPointer,
959 const TypedVar *arg,
960 bool isReader,
961 Type::ErrorMode mode,
962 bool addPrefixToName) const {
963 const Type &type = arg->type();
964 if(type.needsResolveReferences()) {
965 type.emitResolveReferences(
966 out,
967 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
968 isReader, // nameIsPointer
969 parcelObj,
970 parcelObjIsPointer,
971 isReader,
972 mode);
973 }
974}
975
Yifan Hong068c5522016-10-31 14:07:25 -0700976status_t AST::generateProxyMethodSource(Formatter &out,
977 const std::string &klassName,
978 const Method *method,
979 const Interface *superInterface) const {
980
981 method->generateCppSignature(out,
982 klassName,
983 true /* specify namespaces */);
984
985 const bool returnsValue = !method->results().empty();
986 const TypedVar *elidedReturn = method->canElideCallback();
987
Steven Moreland41c6d2e2016-11-07 12:26:54 -0800988 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700989
990 out.indent();
991
992 if (returnsValue && elidedReturn == nullptr) {
993 generateCheckNonNull(out, "_hidl_cb");
994 }
995
996 status_t status = generateCppInstrumentationCall(
997 out,
998 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -0700999 method);
1000 if (status != OK) {
1001 return status;
1002 }
1003
1004 out << "::android::hardware::Parcel _hidl_data;\n";
1005 out << "::android::hardware::Parcel _hidl_reply;\n";
1006 out << "::android::status_t _hidl_err;\n";
1007 out << "::android::hardware::Status _hidl_status;\n\n";
1008
1009 declareCppReaderLocals(
1010 out, method->results(), true /* forResults */);
1011
1012 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongc8934042016-11-17 17:10:52 -08001013 out << superInterface->fqName().cppNamespace()
1014 << "::I"
1015 << superInterface->getBaseName();
Yifan Hong068c5522016-10-31 14:07:25 -07001016 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001017 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1018
1019 // First DFS: write all buffers and resolve pointers for parent
1020 for (const auto &arg : method->args()) {
1021 emitCppReaderWriter(
1022 out,
1023 "_hidl_data",
1024 false /* parcelObjIsPointer */,
1025 arg,
1026 false /* reader */,
1027 Type::ErrorMode_Goto,
1028 false /* addPrefixToName */);
1029 }
1030
1031 // Second DFS: resolve references.
1032 for (const auto &arg : method->args()) {
1033 emitCppResolveReferences(
1034 out,
1035 "_hidl_data",
1036 false /* parcelObjIsPointer */,
1037 arg,
1038 false /* reader */,
1039 Type::ErrorMode_Goto,
1040 false /* addPrefixToName */);
1041 }
1042
1043 out << "_hidl_err = remote()->transact("
1044 << method->getSerialId()
1045 << " /* "
1046 << method->name()
1047 << " */, _hidl_data, &_hidl_reply";
1048
1049 if (method->isOneway()) {
1050 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1051 }
1052 out << ");\n";
1053
1054 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1055
1056 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001057 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001058 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1059 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1060
1061
1062 // First DFS: write all buffers and resolve pointers for parent
1063 for (const auto &arg : method->results()) {
1064 emitCppReaderWriter(
1065 out,
1066 "_hidl_reply",
1067 false /* parcelObjIsPointer */,
1068 arg,
1069 true /* reader */,
1070 Type::ErrorMode_Goto,
1071 true /* addPrefixToName */);
1072 }
1073
1074 // Second DFS: resolve references.
1075 for (const auto &arg : method->results()) {
1076 emitCppResolveReferences(
1077 out,
1078 "_hidl_reply",
1079 false /* parcelObjIsPointer */,
1080 arg,
1081 true /* reader */,
1082 Type::ErrorMode_Goto,
1083 true /* addPrefixToName */);
1084 }
1085
1086 if (returnsValue && elidedReturn == nullptr) {
1087 out << "_hidl_cb(";
1088
1089 bool first = true;
1090 for (const auto &arg : method->results()) {
1091 if (!first) {
1092 out << ", ";
1093 }
1094
1095 if (arg->type().resultNeedsDeref()) {
1096 out << "*";
1097 }
1098 out << "_hidl_out_" << arg->name();
1099
1100 first = false;
1101 }
1102
1103 out << ");\n\n";
1104 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001105 }
1106 status = generateCppInstrumentationCall(
1107 out,
1108 InstrumentationEvent::CLIENT_API_EXIT,
1109 method);
1110 if (status != OK) {
1111 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001112 }
1113
1114 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001115 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1116 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001117 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001118 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1119 } else {
1120 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1121 out << "return ::android::hardware::Return<void>();\n\n";
1122 }
1123
1124 out.unindent();
1125 out << "_hidl_error:\n";
1126 out.indent();
1127 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1128 out << "return ::android::hardware::Return<";
1129 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001130 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001131 } else {
1132 out << "void";
1133 }
1134 out << ">(_hidl_status);\n";
1135
1136 out.unindent();
1137 out << "}\n\n";
1138 return OK;
1139}
1140
Andreas Huber881227d2016-08-02 14:20:21 -07001141status_t AST::generateProxySource(
1142 Formatter &out, const std::string &baseName) const {
1143 const std::string klassName = "Bp" + baseName;
1144
1145 out << klassName
1146 << "::"
1147 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001148 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001149
1150 out.indent();
1151 out.indent();
1152
1153 out << ": BpInterface"
Steven Moreland40786312016-08-16 10:29:40 -07001154 << "<IHw"
Andreas Huber881227d2016-08-02 14:20:21 -07001155 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001156 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001157 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001158 << mPackage.string()
1159 << "::I"
1160 << baseName
1161 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001162
Andreas Huber881227d2016-08-02 14:20:21 -07001163 out.unindent();
1164 out.unindent();
1165 out << "}\n\n";
1166
Yifan Hong068c5522016-10-31 14:07:25 -07001167 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1168 return generateProxyMethodSource(out, klassName, method, superInterface);
1169 });
Andreas Huber881227d2016-08-02 14:20:21 -07001170
Yifan Hong068c5522016-10-31 14:07:25 -07001171 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001172}
1173
1174status_t AST::generateStubSource(
1175 Formatter &out, const std::string &baseName) const {
1176 out << "IMPLEMENT_HWBINDER_META_INTERFACE("
1177 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001178 << ", "
1179 << mPackage.cppNamespace()
Andreas Huber881227d2016-08-02 14:20:21 -07001180 << "::I"
1181 << baseName
Yifan Hong10fe0b52016-10-19 14:20:17 -07001182 << "::descriptor);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001183
1184 const std::string klassName = "Bn" + baseName;
1185
Steven Moreland40786312016-08-16 10:29:40 -07001186 out << klassName
1187 << "::"
1188 << klassName
1189 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl)\n";
1190
1191 out.indent();
1192 out.indent();
1193
1194 out << ": BnInterface"
1195 << "<I"
1196 << baseName
1197 << ", IHw"
1198 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001199 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001200 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001201 << mPackage.string()
1202 << "::I"
1203 << baseName
1204 << "\") {\n";
Steven Moreland40786312016-08-16 10:29:40 -07001205
1206 out.unindent();
1207 out.unindent();
1208 out << "}\n\n";
1209
Andreas Huber881227d2016-08-02 14:20:21 -07001210 out << "::android::status_t " << klassName << "::onTransact(\n";
1211
1212 out.indent();
1213 out.indent();
1214
Iliyan Malchev549e2592016-08-10 08:59:12 -07001215 out << "uint32_t _hidl_code,\n"
1216 << "const ::android::hardware::Parcel &_hidl_data,\n"
1217 << "::android::hardware::Parcel *_hidl_reply,\n"
1218 << "uint32_t _hidl_flags,\n"
1219 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001220
1221 out.unindent();
1222
Iliyan Malchev549e2592016-08-10 08:59:12 -07001223 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001224 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001225 out.indent();
1226
1227 const Interface *iface = mRootScope->getInterface();
1228
Yifan Hong10fe0b52016-10-19 14:20:17 -07001229 for (const auto &tuple : iface->allMethodsFromRoot()) {
1230 const Method *method = tuple.method();
1231 const Interface *superInterface = tuple.interface();
1232 out << "case "
1233 << method->getSerialId()
1234 << " /* "
1235 << method->name()
1236 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001237
Yifan Hong10fe0b52016-10-19 14:20:17 -07001238 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001239
Yifan Hong10fe0b52016-10-19 14:20:17 -07001240 status_t err =
1241 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001242
Yifan Hong10fe0b52016-10-19 14:20:17 -07001243 if (err != OK) {
1244 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001245 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001246
1247 out.unindent();
1248 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001249 }
1250
1251 out << "default:\n{\n";
1252 out.indent();
1253
Andreas Huber8a82ff72016-08-04 10:29:39 -07001254 out << "return ::android::hardware::BnInterface<I"
Steven Moreland40786312016-08-16 10:29:40 -07001255 << baseName << ", IHw" << baseName
Andreas Huber881227d2016-08-02 14:20:21 -07001256 << ">::onTransact(\n";
1257
1258 out.indent();
1259 out.indent();
1260
Iliyan Malchev549e2592016-08-10 08:59:12 -07001261 out << "_hidl_code, _hidl_data, _hidl_reply, "
1262 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001263
1264 out.unindent();
1265 out.unindent();
1266
1267 out.unindent();
1268 out << "}\n";
1269
1270 out.unindent();
1271 out << "}\n\n";
1272
Iliyan Malchev549e2592016-08-10 08:59:12 -07001273 out << "if (_hidl_err == ::android::UNEXPECTED_NULL) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001274 out.indent();
Yifan Hong859e53f2016-11-14 19:08:24 -08001275 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001276 out.indent();
1277 out.indent();
Yifan Hong859e53f2016-11-14 19:08:24 -08001278 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1279 out << "_hidl_reply);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001280 out.unindent();
1281 out.unindent();
1282
1283 out.unindent();
1284 out << "}\n\n";
1285
Iliyan Malchev549e2592016-08-10 08:59:12 -07001286 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001287
1288 out.unindent();
1289 out << "}\n\n";
1290
1291 return OK;
1292}
1293
1294status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001295 Formatter &out, const Interface *iface, const Method *method) const {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001296 out << "if (!_hidl_data.enforceInterface(";
1297
Yifan Hongc8934042016-11-17 17:10:52 -08001298 out << iface->fqName().cppNamespace()
1299 << "::I"
1300 << iface->getBaseName();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001301
1302 out << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001303
Andreas Huber881227d2016-08-02 14:20:21 -07001304 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001305 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001306 out << "break;\n";
1307 out.unindent();
1308 out << "}\n\n";
1309
Andreas Huber5e44a292016-09-27 14:52:39 -07001310 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001311
Yifan Hongbf459bc2016-08-23 16:50:37 -07001312 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001313 for (const auto &arg : method->args()) {
1314 emitCppReaderWriter(
1315 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001316 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001317 false /* parcelObjIsPointer */,
1318 arg,
1319 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001320 Type::ErrorMode_Break,
1321 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001322 }
1323
Yifan Hongbf459bc2016-08-23 16:50:37 -07001324 // Second DFS: resolve references
1325 for (const auto &arg : method->args()) {
1326 emitCppResolveReferences(
1327 out,
1328 "_hidl_data",
1329 false /* parcelObjIsPointer */,
1330 arg,
1331 true /* reader */,
1332 Type::ErrorMode_Break,
1333 false /* addPrefixToName */);
1334 }
1335
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001336 status_t status = generateCppInstrumentationCall(
1337 out,
1338 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001339 method);
1340 if (status != OK) {
1341 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001342 }
1343
Andreas Huber881227d2016-08-02 14:20:21 -07001344 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001345 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001346
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001347 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001348 out << elidedReturn->type().getCppResultType()
1349 << " "
1350 << elidedReturn->name()
1351 << " = "
1352 << method->name()
1353 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001354
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001355 bool first = true;
1356 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001357 if (!first) {
1358 out << ", ";
1359 }
1360
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001361 if (arg->type().resultNeedsDeref()) {
1362 out << "*";
1363 }
1364
1365 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001366
1367 first = false;
1368 }
1369
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001370 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001371 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1372 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001373
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001374 elidedReturn->type().emitReaderWriter(
1375 out,
1376 elidedReturn->name(),
1377 "_hidl_reply",
1378 true, /* parcelObjIsPointer */
1379 false, /* isReader */
1380 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001381
Yifan Hongbf459bc2016-08-23 16:50:37 -07001382 emitCppResolveReferences(
1383 out,
1384 "_hidl_reply",
1385 true /* parcelObjIsPointer */,
1386 elidedReturn,
1387 false /* reader */,
1388 Type::ErrorMode_Ignore,
1389 false /* addPrefixToName */);
1390
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001391 status_t status = generateCppInstrumentationCall(
1392 out,
1393 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001394 method);
1395 if (status != OK) {
1396 return status;
1397 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001398
Iliyan Malchev549e2592016-08-10 08:59:12 -07001399 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001400 } else {
1401 if (returnsValue) {
1402 out << "bool _hidl_callbackCalled = false;\n\n";
1403 }
Andreas Huber881227d2016-08-02 14:20:21 -07001404
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001405 out << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001406
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001407 bool first = true;
1408 for (const auto &arg : method->args()) {
1409 if (!first) {
1410 out << ", ";
1411 }
Andreas Huber881227d2016-08-02 14:20:21 -07001412
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001413 if (arg->type().resultNeedsDeref()) {
1414 out << "*";
1415 }
1416
1417 out << arg->name();
1418
1419 first = false;
1420 }
1421
1422 if (returnsValue) {
1423 if (!first) {
1424 out << ", ";
1425 }
1426
1427 out << "[&](";
1428
1429 first = true;
1430 for (const auto &arg : method->results()) {
1431 if (!first) {
1432 out << ", ";
1433 }
1434
1435 out << "const auto &" << arg->name();
1436
1437 first = false;
1438 }
1439
1440 out << ") {\n";
1441 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001442 out << "if (_hidl_callbackCalled) {\n";
1443 out.indent();
1444 out << "LOG_ALWAYS_FATAL(\""
1445 << method->name()
1446 << ": _hidl_cb called a second time, but must be called once.\");\n";
1447 out.unindent();
1448 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001449 out << "_hidl_callbackCalled = true;\n\n";
1450
Yifan Hong859e53f2016-11-14 19:08:24 -08001451 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1452 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001453
Yifan Hongbf459bc2016-08-23 16:50:37 -07001454 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001455 for (const auto &arg : method->results()) {
1456 emitCppReaderWriter(
1457 out,
1458 "_hidl_reply",
1459 true /* parcelObjIsPointer */,
1460 arg,
1461 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001462 Type::ErrorMode_Ignore,
1463 false /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001464 }
1465
Yifan Hongbf459bc2016-08-23 16:50:37 -07001466 // Second DFS: resolve references
1467 for (const auto &arg : method->results()) {
1468 emitCppResolveReferences(
1469 out,
1470 "_hidl_reply",
1471 true /* parcelObjIsPointer */,
1472 arg,
1473 false /* reader */,
1474 Type::ErrorMode_Ignore,
1475 false /* addPrefixToName */);
1476 }
1477
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001478 status_t status = generateCppInstrumentationCall(
1479 out,
1480 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001481 method);
1482 if (status != OK) {
1483 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001484 }
1485
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001486 out << "_hidl_cb(*_hidl_reply);\n";
1487
1488 out.unindent();
1489 out << "}\n";
1490 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001491 out << ");\n\n";
1492
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001493 if (returnsValue) {
1494 out << "if (!_hidl_callbackCalled) {\n";
1495 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001496 out << "LOG_ALWAYS_FATAL(\""
1497 << method->name()
1498 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001499 out.unindent();
1500 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001501 } else {
1502 out << "::android::hardware::writeToParcel("
1503 << "::android::hardware::Status::ok(), "
1504 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001505 }
Andreas Huber881227d2016-08-02 14:20:21 -07001506 }
1507
1508 out << "break;\n";
1509
1510 return OK;
1511}
1512
Steven Moreland69e7c702016-09-09 11:16:32 -07001513status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1514 std::string ifaceName;
1515 if (!AST::isInterface(&ifaceName)) {
1516 // types.hal does not get a stub header.
1517 return OK;
1518 }
1519
1520 const Interface *iface = mRootScope->getInterface();
1521
1522 const std::string baseName = iface->getBaseName();
1523 const std::string klassName = "Bs" + baseName;
1524
1525 bool supportOneway = iface->hasOnewayMethods();
1526
1527 std::string path = outputPath;
1528 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1529 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1530 path.append(klassName);
1531 path.append(".h");
1532
1533 CHECK(Coordinator::MakeParentHierarchy(path));
1534 FILE *file = fopen(path.c_str(), "w");
1535
1536 if (file == NULL) {
1537 return -errno;
1538 }
1539
1540 Formatter out(file);
1541
1542 const std::string guard = makeHeaderGuard(klassName);
1543
1544 out << "#ifndef " << guard << "\n";
1545 out << "#define " << guard << "\n\n";
1546
1547 std::vector<std::string> packageComponents;
1548 getPackageAndVersionComponents(
1549 &packageComponents, false /* cpp_compatible */);
1550
1551 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001552
1553 generateCppPackageInclude(out, mPackage, ifaceName);
1554 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001555
1556 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001557 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001558 }
1559
1560 enterLeaveNamespace(out, true /* enter */);
1561 out << "\n";
1562
1563 out << "struct "
1564 << klassName
1565 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001566 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001567
1568 out.indent();
1569 out << "explicit "
1570 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001571 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001572 << ifaceName
1573 << "> impl);\n";
1574
Yifan Hong068c5522016-10-31 14:07:25 -07001575 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1576 return generatePassthroughMethod(out, method);
1577 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001578
1579 if (err != OK) {
1580 return err;
1581 }
1582
1583 out.unindent();
1584 out << "private:\n";
1585 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001586 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001587
1588 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001589 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001590
1591 out << "\n";
1592
1593 out << "::android::hardware::Return<void> addOnewayTask("
1594 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001595 }
1596
1597 out.unindent();
1598
1599 out << "};\n\n";
1600
1601 enterLeaveNamespace(out, false /* enter */);
1602
1603 out << "\n#endif // " << guard << "\n";
1604
1605 return OK;
1606}
1607
Yifan Hongfe95aa22016-10-19 17:26:45 -07001608status_t AST::generateInterfaceSource(Formatter &out) const {
1609 const Interface *iface = mRootScope->getInterface();
1610
Yifan Hong2d7126b2016-10-20 15:12:57 -07001611 // generate castFrom functions
Yifan Hongfe95aa22016-10-19 17:26:45 -07001612 if (!iface->isRootType()) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001613 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001614
1615 for (const Interface *superType : iface->superTypeChain()) {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001616 out << "// static \n"
1617 << childTypeResult
1618 << " I"
1619 << iface->getBaseName()
1620 << "::castFrom("
Yifan Hong3b320f82016-11-01 15:15:54 -07001621 << superType->getCppArgumentType()
1622 << " parent) {\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001623 out.indent();
1624 out << "return ::android::hardware::castInterface<";
1625 out << "I" << iface->getBaseName() << ", "
1626 << superType->fqName().cppName() << ", "
Yifan Hong158655a2016-11-08 12:34:07 -08001627 << "Bp" << iface->getBaseName() << ", "
1628 << superType->getHwName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001629 << ">(\n";
1630 out.indent();
1631 out.indent();
1632 out << "parent, \""
1633 << iface->fqName().string()
1634 << "\");\n";
1635 out.unindent();
1636 out.unindent();
1637 out.unindent();
1638 out << "}\n\n";
1639 }
1640 }
1641
1642 return OK;
1643}
1644
Steven Moreland69e7c702016-09-09 11:16:32 -07001645status_t AST::generatePassthroughSource(Formatter &out) const {
1646 const Interface *iface = mRootScope->getInterface();
1647
1648 const std::string baseName = iface->getBaseName();
1649 const std::string klassName = "Bs" + baseName;
1650
1651 out << klassName
1652 << "::"
1653 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001654 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001655 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001656 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001657 << iface->fqName().string()
1658 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001659 if (iface->hasOnewayMethods()) {
1660 out << "\n";
1661 out.indentBlock([&] {
1662 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1663 });
1664 }
1665 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001666
1667 if (iface->hasOnewayMethods()) {
1668 out << "::android::hardware::Return<void> "
1669 << klassName
1670 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1671 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001672 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001673 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001674 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1675 out.indent();
1676 out.indent();
1677 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1678 out.unindent();
1679 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001680 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001681 out << "}\n";
1682
Steven Morelandd366c262016-10-11 15:29:10 -07001683 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001684
1685 out.unindent();
1686 out << "}\n\n";
1687
1688
1689 }
1690
1691 return OK;
1692}
1693
Martijn Coenen7b295242016-11-04 16:52:56 +01001694status_t AST::generateCppAtraceCall(Formatter &out,
1695 InstrumentationEvent event,
1696 const Method *method) const {
1697 const Interface *iface = mRootScope->getInterface();
1698 std::string baseString = "HIDL::I" + iface->getBaseName() + "::" + method->name();
1699 switch (event) {
1700 case SERVER_API_ENTRY:
1701 {
1702 out << "atrace_begin(ATRACE_TAG_HAL, \""
1703 << baseString + "::server\");\n";
1704 break;
1705 }
1706 case CLIENT_API_ENTRY:
1707 {
1708 out << "atrace_begin(ATRACE_TAG_HAL, \""
1709 << baseString + "::client\");\n";
1710 break;
1711 }
1712 case PASSTHROUGH_ENTRY:
1713 {
1714 out << "atrace_begin(ATRACE_TAG_HAL, \""
1715 << baseString + "::passthrough\");\n";
1716 break;
1717 }
1718 case SERVER_API_EXIT:
1719 case CLIENT_API_EXIT:
1720 case PASSTHROUGH_EXIT:
1721 {
1722 out << "atrace_end(ATRACE_TAG_HAL);\n";
1723 break;
1724 }
1725 default:
1726 {
1727 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1728 return UNKNOWN_ERROR;
1729 }
1730 }
1731
1732 return OK;
1733}
1734
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001735status_t AST::generateCppInstrumentationCall(
1736 Formatter &out,
1737 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001738 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001739 status_t err = generateCppAtraceCall(out, event, method);
1740 if (err != OK) {
1741 return err;
1742 }
1743
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001744 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1745 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001746 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001747 std::string event_str = "";
1748 switch (event) {
1749 case SERVER_API_ENTRY:
1750 {
1751 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1752 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001753 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001754 << (arg->type().resultNeedsDeref() ? "" : "&")
1755 << arg->name()
1756 << ");\n";
1757 }
1758 break;
1759 }
1760 case SERVER_API_EXIT:
1761 {
1762 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001763 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001764 out << "_hidl_args.push_back((void *)&"
Steven Moreland031ccf12016-10-31 15:54:38 -07001765 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001766 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001767 }
1768 break;
1769 }
1770 case CLIENT_API_ENTRY:
1771 {
1772 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1773 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001774 out << "_hidl_args.push_back((void *)&"
1775 << arg->name()
1776 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001777 }
1778 break;
1779 }
1780 case CLIENT_API_EXIT:
1781 {
1782 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1783 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001784 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001785 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001786 << "_hidl_out_"
1787 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001788 << ");\n";
1789 }
1790 break;
1791 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001792 case PASSTHROUGH_ENTRY:
1793 {
1794 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1795 for (const auto &arg : method->args()) {
1796 out << "_hidl_args.push_back((void *)&"
1797 << arg->name()
1798 << ");\n";
1799 }
1800 break;
1801 }
1802 case PASSTHROUGH_EXIT:
1803 {
1804 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001805 for (const auto &arg : method->results()) {
1806 out << "_hidl_args.push_back((void *)&"
1807 << arg->name()
1808 << ");\n";
1809 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001810 break;
1811 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001812 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001813 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001814 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001815 return UNKNOWN_ERROR;
1816 }
1817 }
1818
Steven Moreland031ccf12016-10-31 15:54:38 -07001819 const Interface *iface = mRootScope->getInterface();
1820
Steven Moreland1ab31442016-11-03 18:37:51 -07001821 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001822 out.indent();
1823 out << "callback("
1824 << event_str
1825 << ", \""
1826 << mPackage.package()
1827 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07001828 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001829 << "\", \""
1830 << iface->localName()
1831 << "\", \""
1832 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001833 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001834 out.unindent();
1835 out << "}\n";
1836 out.unindent();
1837 out << "}\n\n";
1838
1839 return OK;
1840}
1841
Andreas Huber881227d2016-08-02 14:20:21 -07001842} // namespace android
1843