blob: ef26d356ec71eca8af26c72d3ce5dfdbe1c893be [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) {
Yifan Hong7a118f52016-12-07 11:21:15 -080055 err = generatePassthroughHeader(outputPath);
Steven Moreland69e7c702016-09-09 11:16:32 -070056 }
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
Steven Moreland038903b2017-03-30 12:11:24 -0700128static void declareGetService(Formatter &out, const std::string &interfaceName, bool isTry) {
129 const std::string functionName = isTry ? "tryGetService" : "getService";
130
131 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800132 << "const std::string &serviceName=\"default\", bool getStub=false);\n";
Steven Moreland038903b2017-03-30 12:11:24 -0700133 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800134 << "const char serviceName[], bool getStub=false)"
135 << " { std::string str(serviceName ? serviceName : \"\");"
Steven Moreland038903b2017-03-30 12:11:24 -0700136 << " return " << functionName << "(str, getStub); }\n";
137 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800138 << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
139 // without c_str the std::string constructor is ambiguous
140 << " { std::string str(serviceName.c_str());"
Steven Moreland038903b2017-03-30 12:11:24 -0700141 << " return " << functionName << "(str, getStub); }\n";
142 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
143 << "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
144}
145
146static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
147 declareGetService(out, interfaceName, true /* isTry */);
148 declareGetService(out, interfaceName, false /* isTry */);
149
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800150 out << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800151 out << "static bool registerForNotifications(\n";
152 out.indent(2, [&] {
153 out << "const std::string &serviceName,\n"
154 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
155 << "&notification);\n";
156 });
157
158}
159
Steven Moreland038903b2017-03-30 12:11:24 -0700160static void implementGetService(Formatter &out,
161 const FQName &fqName,
162 bool isTry) {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800163
164 const std::string interfaceName = fqName.getInterfaceName();
Steven Moreland038903b2017-03-30 12:11:24 -0700165 const std::string functionName = isTry ? "tryGetService" : "getService";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800166
167 out << "// static\n"
Steven Moreland038903b2017-03-30 12:11:24 -0700168 << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
Yifan Hong31f07ff2017-03-21 18:56:35 +0000169 << "const std::string &serviceName, const bool getStub) ";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800170 out.block([&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000171 out << "::android::sp<" << interfaceName << "> iface = nullptr;\n";
Yifan Hongd3b58ed2017-01-30 14:13:10 -0800172 out << "::android::vintf::Transport transport = ::android::hardware::getTransport("
Yifan Hong152866b2017-02-28 15:34:27 -0800173 << interfaceName << "::descriptor, serviceName);\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000174
Steven Moreland2edcf9d2017-03-30 16:30:35 -0700175 out << "const bool vintfHwbinder = (transport == ::android::vintf::Transport::HWBINDER);\n"
176 << "const bool vintfPassthru = (transport == ::android::vintf::Transport::PASSTHROUGH);\n"
Yifan Hong31f07ff2017-03-21 18:56:35 +0000177 << "const bool vintfEmpty = (transport == ::android::vintf::Transport::EMPTY);\n\n";
178
179 // if (getStub) {
180 // getPassthroughServiceManager()->get only once.
181 // } else {
182 // if (vintfHwbinder) {
183 // while (no alive service) {
184 // waitForHwService
185 // defaultServiceManager()->get
186 // }
187 // } else if (vintfEmpty) {
188 // defaultServiceManager()->get only once.
189 // getPassthroughServiceManager()->get only once.
190 // } else if (vintfPassthru) {
191 // getPassthroughServiceManager()->get only once.
192 // }
193 // }
194
Yifan Hong223fd472017-03-23 17:17:57 +0000195 out << "bool tried = false;\n";
196 out.sWhile("!getStub && (vintfHwbinder || (vintfEmpty && !tried))", [&] {
Yifan Hong31f07ff2017-03-21 18:56:35 +0000197
198 out.sIf("tried", [&] {
199 // sleep only after the first trial.
200 out << "ALOGI(\"getService: retrying in 1s...\");\n"
201 << "sleep(1);\n";
202 }).endl();
203
Yifan Hong223fd472017-03-23 17:17:57 +0000204 out << "tried = true;\n";
205
Steven Morelandf10af872017-01-25 16:01:56 +0000206 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800207 out.indent(2, [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000208 out << "= ::android::hardware::defaultServiceManager();\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800209 });
Yifan Hong31f07ff2017-03-21 18:56:35 +0000210 out.sIf("sm == nullptr", [&] {
211 // hwbinder is not available on this device, so future tries
212 // would also be null. I can only "break" here and
213 // (vintfEmpty) try passthrough or (vintfHwbinder) return nullptr.
214 out << "ALOGE(\"getService: defaultServiceManager() is null\");\n"
215 << "break;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800216 }).endl();
Yifan Hong31f07ff2017-03-21 18:56:35 +0000217
Steven Moreland038903b2017-03-30 12:11:24 -0700218 if (!isTry) {
219 out.sIf("vintfHwbinder", [&] {
220 out << "::android::hardware::details::waitForHwService("
221 << interfaceName << "::descriptor" << ", serviceName);\n";
222 }).endl();
223 }
Yifan Hong31f07ff2017-03-21 18:56:35 +0000224
225 out << "::android::hardware::Return<::android::sp<"
226 << gIBaseFqName.cppName() << ">> ret = \n";
227 out.indent(2, [&] {
228 out << "sm->get(" << interfaceName << "::descriptor, serviceName);\n";
229 });
230
231 out.sIf("!ret.isOk()", [&] {
Steven Moreland42394ce2017-03-27 17:03:04 -0700232 // hwservicemanager fails, may be security issue
Yifan Hong31f07ff2017-03-21 18:56:35 +0000233 out << "ALOGE(\"getService: defaultServiceManager()->get returns %s\", "
234 << "ret.description().c_str());\n"
Steven Moreland42394ce2017-03-27 17:03:04 -0700235 << "break;\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000236 }).endl();
237
Yifan Hong200209c2017-03-29 03:39:09 -0700238 out << "::android::sp<" << gIBaseFqName.cppName() << "> base = ret;\n";
239 out.sIf("base == nullptr", [&] {
240 // race condition. hwservicemanager drops the service
241 // from waitForHwService to here
Steven Morelanddff644c2017-03-24 10:59:01 -0700242 out << "ALOGW(\"getService: found null hwbinder interface\");\n"
Yifan Hong9c74a5b2017-04-04 13:27:25 -0700243 << (isTry ? "break" : "continue")
244 << ";\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000245 }).endl();
Yifan Hong200209c2017-03-29 03:39:09 -0700246 out << "::android::hardware::Return<::android::sp<" << interfaceName
247 << ">> castRet = " << interfaceName << "::castFrom(base, true /* emitError */);\n";
248 out.sIf("!castRet.isOk()", [&] {
249 out.sIf("castRet.isDeadObject()", [&] {
250 // service is dead (castFrom cannot call interfaceChain)
251 out << "ALOGW(\"getService: found dead hwbinder service\");\n"
Yifan Hong9c74a5b2017-04-04 13:27:25 -0700252 << (isTry ? "break" : "continue")
253 << ";\n";
Yifan Hong200209c2017-03-29 03:39:09 -0700254 }).sElse([&] {
255 out << "ALOGW(\"getService: cannot call into hwbinder service: %s"
256 << "; No permission? Check for selinux denials.\", "
257 << "castRet.description().c_str());\n"
258 << "break;\n";
259 }).endl();
260 }).endl();
261 out << "iface = castRet;\n";
262 out.sIf("iface == nullptr", [&] {
263 // returned service isn't of correct type; this is a bug
264 // to hwservicemanager or to the service itself (interfaceChain
265 // is not consistent).
266 out << "ALOGW(\"getService: received incompatible service; bug in hwservicemanager?\");\n"
267 << "break;\n";
268 }).endl();
Yifan Hong31f07ff2017-03-21 18:56:35 +0000269
270 out << "return iface;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800271 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800272
Yifan Hong31f07ff2017-03-21 18:56:35 +0000273 out.sIf("getStub || vintfPassthru || vintfEmpty", [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000274 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> pm\n";
Steven Morelande3fa5da2017-01-25 07:07:53 +0000275 out.indent(2, [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000276 out << "= ::android::hardware::getPassthroughServiceManager();\n";
Steven Morelande3fa5da2017-01-25 07:07:53 +0000277 });
Steven Morelandf10af872017-01-25 16:01:56 +0000278
279 out.sIf("pm != nullptr", [&] () {
280 out << "::android::hardware::Return<::android::sp<" << gIBaseFqName.cppName() << ">> ret = \n";
281 out.indent(2, [&] {
282 out << "pm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
Steven Moreland2c2dea82017-01-18 17:24:17 -0800283 });
Steven Morelandf10af872017-01-25 16:01:56 +0000284 out.sIf("ret.isOk()", [&] {
285 out << "::android::sp<" << gIBaseFqName.cppName()
286 << "> baseInterface = ret;\n";
287 out.sIf("baseInterface != nullptr", [&]() {
288 out << "iface = new " << fqName.getInterfacePassthroughName()
289 << "(" << interfaceName << "::castFrom(baseInterface));\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000290 }).endl();
Steven Morelandf10af872017-01-25 16:01:56 +0000291 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800292 }).endl();
293 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800294
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800295 out << "return iface;\n";
296 }).endl().endl();
Steven Moreland038903b2017-03-30 12:11:24 -0700297}
298
299static void implementServiceManagerInteractions(Formatter &out,
300 const FQName &fqName, const std::string &package) {
301
302 const std::string interfaceName = fqName.getInterfaceName();
303
304 implementGetService(out, fqName, true /* isTry */);
305 implementGetService(out, fqName, false /* isTry */);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800306
Yifan Hongeefe4f22017-01-04 15:32:42 -0800307 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800308 << "const std::string &serviceName) ";
309 out.block([&] {
310 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
311 out.indent(2, [&] {
312 out << "= ::android::hardware::defaultServiceManager();\n";
313 });
314 out.sIf("sm == nullptr", [&] {
315 out << "return ::android::INVALID_OPERATION;\n";
316 }).endl();
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100317 out << "::android::hardware::Return<bool> ret = "
318 << "sm->add(serviceName.c_str(), this);\n"
319 << "return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800320 }).endl().endl();
321
Yifan Hongeefe4f22017-01-04 15:32:42 -0800322 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800323 out.indent(2, [&] {
324 out << "const std::string &serviceName,\n"
325 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
326 << "&notification) ";
327 });
328 out.block([&] {
329 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
330 out.indent(2, [&] {
331 out << "= ::android::hardware::defaultServiceManager();\n";
332 });
333 out.sIf("sm == nullptr", [&] {
334 out << "return false;\n";
335 }).endl();
336 out << "::android::hardware::Return<bool> success =\n";
337 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800338 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800339 out.indent(2, [&] {
340 out << "serviceName, notification);\n";
341 });
342 });
343 out << "return success.isOk() && success;\n";
344 }).endl().endl();
345}
346
Andreas Huberb82318c2016-08-02 14:45:54 -0700347status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700348
Andreas Huberb82318c2016-08-02 14:45:54 -0700349 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700350 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700351 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700352
353 std::string ifaceName;
354 bool isInterface = true;
355 if (!AST::isInterface(&ifaceName)) {
356 ifaceName = "types";
357 isInterface = false;
358 }
359 path.append(ifaceName);
360 path.append(".h");
361
Andreas Huberd2943e12016-08-05 11:59:31 -0700362 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700363 FILE *file = fopen(path.c_str(), "w");
364
365 if (file == NULL) {
366 return -errno;
367 }
368
369 Formatter out(file);
370
371 const std::string guard = makeHeaderGuard(ifaceName);
372
373 out << "#ifndef " << guard << "\n";
374 out << "#define " << guard << "\n\n";
375
Andreas Huber737080b2016-08-02 15:38:04 -0700376 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700377 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700378 }
379
380 if (!mImportedNames.empty()) {
381 out << "\n";
382 }
383
Steven Moreland0693f312016-11-09 15:06:14 -0800384 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800385 if (isIBase()) {
386 out << "// skipped #include IServiceNotification.h\n\n";
387 } else {
388 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
389 }
Steven Moreland0693f312016-11-09 15:06:14 -0800390 }
391
Yifan Hongc8934042016-11-17 17:10:52 -0800392 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700393 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700394
395 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200396 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700397 }
398
Martijn Coenenaf712c02016-11-16 15:26:27 +0100399 out << "#include <utils/NativeHandle.h>\n";
400 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700401
402 enterLeaveNamespace(out, true /* enter */);
403 out << "\n";
404
405 if (isInterface) {
406 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700407 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700408
409 const Interface *iface = mRootScope->getInterface();
410 const Interface *superType = iface->superType();
411
Steven Moreland40786312016-08-16 10:29:40 -0700412 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800413 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700414 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000415 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700416 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700417 }
418
419 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700420
421 out.indent();
422
Andreas Huber881227d2016-08-02 14:20:21 -0700423 }
424
425 status_t err = emitTypeDeclarations(out);
426
427 if (err != OK) {
428 return err;
429 }
430
431 if (isInterface) {
432 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800433
Yifan Hongc8934042016-11-17 17:10:52 -0800434 out << "virtual bool isRemote() const ";
435 if (!isIBase()) {
436 out << "override ";
437 }
438 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800439
Andreas Huber881227d2016-08-02 14:20:21 -0700440 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700441 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700442
Andreas Huber881227d2016-08-02 14:20:21 -0700443 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800444 const TypedVar *elidedReturn = method->canElideCallback();
445
446 if (elidedReturn == nullptr && returnsValue) {
447 out << "using "
448 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700449 << "_cb = std::function<void(";
450 method->emitCppResultSignature(out, true /* specify namespaces */);
451 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800452 }
Andreas Huber881227d2016-08-02 14:20:21 -0700453
Andreas Huber3599d922016-08-09 10:42:57 -0700454 method->dumpAnnotations(out);
455
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700456 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700457 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700458 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700459 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700460 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700461 }
462
463 out << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700464 << "(";
465 method->emitCppArgSignature(out, true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700466
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700467 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700468 if (!method->args().empty()) {
469 out << ", ";
470 }
471
Steven Moreland67f67b42016-09-29 08:59:02 -0700472 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700473 }
474
Yifan Hong10fe0b52016-10-19 14:20:17 -0700475 out << ")";
476 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800477 if (!isIBase()) {
478 out << " override";
479 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700480 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700481 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700482 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700483 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700484 }
Steven Moreland40786312016-08-16 10:29:40 -0700485
Yifan Hong3d746092016-12-07 14:26:33 -0800486 out << "// cast static functions\n";
487 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700488
Yifan Hong3d746092016-12-07 14:26:33 -0800489 for (const Interface *superType : iface->typeChain()) {
Yifan Hong200209c2017-03-29 03:39:09 -0700490 out << "static ::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -0800491 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -0700492 << "> castFrom("
Yifan Hong3d746092016-12-07 14:26:33 -0800493 << superType->getCppArgumentType()
494 << " parent"
Yifan Hong200209c2017-03-29 03:39:09 -0700495 << ", bool emitError = false);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700496 }
497
Steven Morelandd39133b2016-11-11 12:30:08 -0800498 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700499
Yifan Hongc8934042016-11-17 17:10:52 -0800500 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800501 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800502 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800503 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800504 }
Andreas Huber881227d2016-08-02 14:20:21 -0700505 }
506
507 if (isInterface) {
508 out.unindent();
509
Andreas Hubere3f769a2016-10-10 10:54:44 -0700510 out << "};\n\n";
511 }
512
513 err = mRootScope->emitGlobalTypeDeclarations(out);
514
515 if (err != OK) {
516 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700517 }
518
519 out << "\n";
520 enterLeaveNamespace(out, false /* enter */);
521
522 out << "\n#endif // " << guard << "\n";
523
524 return OK;
525}
526
Steven Moreland40786312016-08-16 10:29:40 -0700527status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
528 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800529 bool isInterface = AST::isInterface(&ifaceName);
530 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800531 std::string klassName{};
532
533 if(isInterface) {
534 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800535 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800536 } else {
537 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700538 }
539
Steven Moreland40786312016-08-16 10:29:40 -0700540 std::string path = outputPath;
541 path.append(mCoordinator->convertPackageRootToPath(mPackage));
542 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
543 path.append(klassName + ".h");
544
Yifan Hong244e82d2016-11-11 11:13:57 -0800545 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700546
547 if (file == NULL) {
548 return -errno;
549 }
550
551 Formatter out(file);
552
553 const std::string guard = makeHeaderGuard(klassName);
554
555 out << "#ifndef " << guard << "\n";
556 out << "#define " << guard << "\n\n";
557
Yifan Hong244e82d2016-11-11 11:13:57 -0800558 if (isInterface) {
559 generateCppPackageInclude(out, mPackage, ifaceName);
560 } else {
561 generateCppPackageInclude(out, mPackage, "types");
562 }
Steven Moreland40786312016-08-16 10:29:40 -0700563
Steven Morelandee88eed2016-10-31 17:49:00 -0700564 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700565
566 for (const auto &item : mImportedNames) {
567 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800568 generateCppPackageInclude(out, item, "hwtypes");
569 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800570 generateCppPackageInclude(out, item, item.getInterfaceStubName());
571 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700572 }
Steven Moreland40786312016-08-16 10:29:40 -0700573 }
574
575 out << "\n";
576
Martijn Coenen93915102016-09-01 01:35:52 +0200577 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700578 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100579 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700580
581 out << "\n";
582
583 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700584
Yifan Hong244e82d2016-11-11 11:13:57 -0800585 status_t err = mRootScope->emitGlobalHwDeclarations(out);
586 if (err != OK) {
587 return err;
588 }
Steven Moreland40786312016-08-16 10:29:40 -0700589
590 enterLeaveNamespace(out, false /* enter */);
591
592 out << "\n#endif // " << guard << "\n";
593
594 return OK;
595}
596
Andreas Huber881227d2016-08-02 14:20:21 -0700597status_t AST::emitTypeDeclarations(Formatter &out) const {
598 return mRootScope->emitTypeDeclarations(out);
599}
600
Yifan Hong7a118f52016-12-07 11:21:15 -0800601static void wrapPassthroughArg(Formatter &out,
602 const TypedVar *arg, bool addPrefixToName,
603 std::function<void(void)> handleError) {
604 if (!arg->type().isInterface()) {
605 return;
606 }
607 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
608 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
609 + arg->name();
610 const Interface &iface = static_cast<const Interface &>(arg->type());
611 out << iface.getCppStackType() << " " << wrappedName << ";\n";
612 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
613 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
614 out << wrappedName
615 << " = "
616 << iface.fqName().cppName()
Yifan Hong052425a2017-03-13 17:06:13 -0700617 << "::castFrom(::android::hardware::details::wrapPassthrough("
Yifan Hong7a118f52016-12-07 11:21:15 -0800618 << name << "));\n";
619 out.sIf(wrappedName + " == nullptr", [&] {
620 // Fatal error. Happens when the BsFoo class is not found in the binary
621 // or any dynamic libraries.
622 handleError();
623 }).endl();
624 }).sElse([&] {
625 out << wrappedName << " = " << name << ";\n";
626 }).endl().endl();
627}
628
Steven Moreland69e7c702016-09-09 11:16:32 -0700629status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700630 const Method *method) const {
631 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700632
633 out << " {\n";
634 out.indent();
635
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800636 if (method->isHidlReserved()
637 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
638 method->cppImpl(IMPL_PASSTHROUGH, out);
639 out.unindent();
640 out << "}\n\n";
641 return OK;
642 }
643
Steven Moreland69e7c702016-09-09 11:16:32 -0700644 const bool returnsValue = !method->results().empty();
645 const TypedVar *elidedReturn = method->canElideCallback();
646
Steven Moreland67f67b42016-09-29 08:59:02 -0700647 if (returnsValue && elidedReturn == nullptr) {
648 generateCheckNonNull(out, "_hidl_cb");
649 }
650
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700651 generateCppInstrumentationCall(
652 out,
653 InstrumentationEvent::PASSTHROUGH_ENTRY,
654 method);
655
Yifan Hong7a118f52016-12-07 11:21:15 -0800656
657 for (const auto &arg : method->args()) {
658 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
659 out << "return ::android::hardware::Status::fromExceptionCode(\n";
660 out.indent(2, [&] {
661 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800662 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800663 });
664 });
665 }
666
667 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700668 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700669
670 if (method->isOneway()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800671 out << "addOnewayTask([this, &_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700672 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800673 out << ", "
674 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
675 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700676 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700677 out << "] {\n";
678 out.indent();
679 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700680 }
681
682 out << "mImpl->"
683 << method->name()
684 << "(";
685
Yifan Hong932464e2017-03-30 15:40:22 -0700686 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800687 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700688 });
Steven Moreland69e7c702016-09-09 11:16:32 -0700689 if (returnsValue && elidedReturn == nullptr) {
690 if (!method->args().empty()) {
691 out << ", ";
692 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800693 out << "[&](";
Yifan Hong932464e2017-03-30 15:40:22 -0700694 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800695 out << "const auto &_hidl_out_"
696 << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700697 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800698
699 out << ") {\n";
700 out.indent();
701 status_t status = generateCppInstrumentationCall(
702 out,
703 InstrumentationEvent::PASSTHROUGH_EXIT,
704 method);
705 if (status != OK) {
706 return status;
707 }
708
Yifan Hong7a118f52016-12-07 11:21:15 -0800709 for (const auto &arg : method->results()) {
710 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
711 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
712 out.indent(2, [&] {
713 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800714 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800715 });
716 out << "return;\n";
717 });
718 }
719
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800720 out << "_hidl_cb(";
Yifan Hong932464e2017-03-30 15:40:22 -0700721 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800722 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
723 << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700724 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800725 out << ");\n";
726 out.unindent();
727 out << "});\n\n";
728 } else {
729 out << ");\n\n";
730 if (elidedReturn != nullptr) {
731 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800732 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800733 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000734 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800735 }
736 status_t status = generateCppInstrumentationCall(
737 out,
738 InstrumentationEvent::PASSTHROUGH_EXIT,
739 method);
740 if (status != OK) {
741 return status;
742 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700743 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700744
745 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700746 out.unindent();
747 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700748 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700749
750 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700751
752 out.unindent();
753 out << "}\n";
754
755 return OK;
756}
757
Yifan Hong068c5522016-10-31 14:07:25 -0700758status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700759
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700760 const Interface *iface = mRootScope->getInterface();
761
Yifan Hong10fe0b52016-10-19 14:20:17 -0700762 const Interface *prevIterface = nullptr;
763 for (const auto &tuple : iface->allMethodsFromRoot()) {
764 const Method *method = tuple.method();
765 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700766
Yifan Hong10fe0b52016-10-19 14:20:17 -0700767 if(prevIterface != superInterface) {
768 if (prevIterface != nullptr) {
769 out << "\n";
770 }
771 out << "// Methods from "
772 << superInterface->fullName()
773 << " follow.\n";
774 prevIterface = superInterface;
775 }
Yifan Hong068c5522016-10-31 14:07:25 -0700776 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700777
Yifan Hong10fe0b52016-10-19 14:20:17 -0700778 if (err != OK) {
779 return err;
780 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700781 }
782
Yifan Hong10fe0b52016-10-19 14:20:17 -0700783 out << "\n";
784
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700785 return OK;
786}
787
Andreas Huberb82318c2016-08-02 14:45:54 -0700788status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700789 std::string ifaceName;
790 if (!AST::isInterface(&ifaceName)) {
791 // types.hal does not get a stub header.
792 return OK;
793 }
794
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700795 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800796 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700797
Andreas Huberb82318c2016-08-02 14:45:54 -0700798 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700799 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700800 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700801 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700802 path.append(".h");
803
Andreas Huberd2943e12016-08-05 11:59:31 -0700804 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700805 FILE *file = fopen(path.c_str(), "w");
806
807 if (file == NULL) {
808 return -errno;
809 }
810
811 Formatter out(file);
812
Steven Moreland40786312016-08-16 10:29:40 -0700813 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700814
815 out << "#ifndef " << guard << "\n";
816 out << "#define " << guard << "\n\n";
817
Yifan Hongeefe4f22017-01-04 15:32:42 -0800818 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700819 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700820
821 enterLeaveNamespace(out, true /* enter */);
822 out << "\n";
823
824 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800825 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100826 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800827 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000828 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100829 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800830 out << " : public "
831 << gIBaseFqName.getInterfaceStubFqName().cppName()
832 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100833 }
Andreas Huber881227d2016-08-02 14:20:21 -0700834
835 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800836 out << "explicit "
837 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700838 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100839 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800840 out << "explicit "
841 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100842 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800843 << " const std::string& HidlInstrumentor_package,"
844 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700845 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700846 out << "::android::status_t onTransact(\n";
847 out.indent();
848 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700849 out << "uint32_t _hidl_code,\n";
850 out << "const ::android::hardware::Parcel &_hidl_data,\n";
851 out << "::android::hardware::Parcel *_hidl_reply,\n";
852 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700853 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700854 out.unindent();
855 out.unindent();
856
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100857 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
858 out.unindent();
859 out << "private:\n";
860 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800861
862 status_t err = generateMethods(out, [&](const Method *method, const Interface *iface) {
863 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
864 return OK;
865 }
866 const bool returnsValue = !method->results().empty();
867 const TypedVar *elidedReturn = method->canElideCallback();
868
869 if (elidedReturn == nullptr && returnsValue) {
870 out << "using " << method->name() << "_cb = "
871 << iface->fqName().cppName()
872 << "::" << method->name() << "_cb;\n";
873 }
874 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800875 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800876 return OK;
877 });
878 if (err != OK) {
879 return err;
880 }
881
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100882 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700883 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700884 out << "};\n\n";
885
886 enterLeaveNamespace(out, false /* enter */);
887
888 out << "\n#endif // " << guard << "\n";
889
890 return OK;
891}
892
Andreas Huberb82318c2016-08-02 14:45:54 -0700893status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700894 std::string ifaceName;
895 if (!AST::isInterface(&ifaceName)) {
896 // types.hal does not get a proxy header.
897 return OK;
898 }
899
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700900 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800901 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700902
Andreas Huberb82318c2016-08-02 14:45:54 -0700903 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700904 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700905 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800906 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700907 path.append(".h");
908
Andreas Huberd2943e12016-08-05 11:59:31 -0700909 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700910 FILE *file = fopen(path.c_str(), "w");
911
912 if (file == NULL) {
913 return -errno;
914 }
915
916 Formatter out(file);
917
Yifan Hongeefe4f22017-01-04 15:32:42 -0800918 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700919
920 out << "#ifndef " << guard << "\n";
921 out << "#define " << guard << "\n\n";
922
Martijn Coenen115d4282016-12-19 05:14:04 +0100923 out << "#include <hidl/HidlTransportSupport.h>\n\n";
924
Andreas Huber881227d2016-08-02 14:20:21 -0700925 std::vector<std::string> packageComponents;
926 getPackageAndVersionComponents(
927 &packageComponents, false /* cpp_compatible */);
928
Yifan Hongeefe4f22017-01-04 15:32:42 -0800929 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700930 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700931
932 enterLeaveNamespace(out, true /* enter */);
933 out << "\n";
934
935 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800936 << proxyName
937 << " : public ::android::hardware::BpInterface<"
938 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000939 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700940
941 out.indent();
942
Yifan Hongeefe4f22017-01-04 15:32:42 -0800943 out << "explicit "
944 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700945 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700946 << "\n\n";
947
Yifan Hong10fe0b52016-10-19 14:20:17 -0700948 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700949
Yifan Hong068c5522016-10-31 14:07:25 -0700950 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
951 method->generateCppSignature(out);
952 out << " override;\n";
953 return OK;
954 });
Steven Moreland9c387612016-09-07 09:54:26 -0700955
956 if (err != OK) {
957 return err;
958 }
Andreas Huber881227d2016-08-02 14:20:21 -0700959
960 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100961 out << "private:\n";
962 out.indent();
963 out << "std::mutex _hidl_mMutex;\n"
964 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
965 << " _hidl_mDeathRecipients;\n";
966 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700967 out << "};\n\n";
968
969 enterLeaveNamespace(out, false /* enter */);
970
971 out << "\n#endif // " << guard << "\n";
972
973 return OK;
974}
975
Andreas Huberb82318c2016-08-02 14:45:54 -0700976status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700977
Andreas Huberb82318c2016-08-02 14:45:54 -0700978 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700979 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700980 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700981
982 std::string ifaceName;
983 std::string baseName;
984
Yifan Hongfe95aa22016-10-19 17:26:45 -0700985 const Interface *iface = nullptr;
986 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700987 if (!AST::isInterface(&ifaceName)) {
988 baseName = "types";
989 isInterface = false;
990 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700991 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700992 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700993 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700994 }
995
996 path.append(baseName);
997
998 if (baseName != "types") {
999 path.append("All");
1000 }
1001
1002 path.append(".cpp");
1003
Andreas Huberd2943e12016-08-05 11:59:31 -07001004 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -07001005 FILE *file = fopen(path.c_str(), "w");
1006
1007 if (file == NULL) {
1008 return -errno;
1009 }
1010
1011 Formatter out(file);
1012
Steven Moreland623c0042017-01-13 14:42:29 -08001013 out << "#define LOG_TAG \""
1014 << mPackage.string() << "::" << baseName
1015 << "\"\n\n";
1016
Steven Moreland05cd4232016-11-21 16:01:12 -08001017 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001018 out << "#include <cutils/trace.h>\n";
1019 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001020 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -07001021 // This is a no-op for IServiceManager itself.
1022 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
1023
Steven Morelandbec74ed2017-01-25 17:42:35 -08001024 // TODO(b/34274385) remove this
1025 out << "#include <hidl/LegacySupport.h>\n";
1026
Yifan Hongeefe4f22017-01-04 15:32:42 -08001027 generateCppPackageInclude(out, mPackage, iface->getProxyName());
1028 generateCppPackageInclude(out, mPackage, iface->getStubName());
1029 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001030
1031 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -07001032 generateCppPackageInclude(out,
1033 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -08001034 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001035 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -08001036
1037 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001038 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -07001039 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -08001040 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -07001041 }
1042
1043 out << "\n";
1044
1045 enterLeaveNamespace(out, true /* enter */);
1046 out << "\n";
1047
1048 status_t err = generateTypeSource(out, ifaceName);
1049
1050 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001051 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001052
1053 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -08001054 out << "const char* "
1055 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -07001056 << "::descriptor(\""
1057 << iface->fqName().string()
1058 << "\");\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +01001059 out << "__attribute__((constructor))";
1060 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001061 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001062 out << "::android::hardware::details::gBnConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001063 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001064 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001065 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001066 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001067 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001068 out << "return new "
1069 << iface->getStubName()
1070 << "(reinterpret_cast<"
1071 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001072 << " *>(iIntf));\n";
1073 });
Yifan Hongb04de382017-02-06 15:31:52 -08001074 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001075 });
Yifan Honga159f3b2017-03-16 14:53:51 -07001076 out << "::android::hardware::details::gBsConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001077 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001078 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001079 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001080 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -08001081 << gIBaseFqName.cppName()
1082 << "> {\n";
1083 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001084 out << "return new "
1085 << iface->getPassthroughName()
1086 << "(reinterpret_cast<"
1087 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001088 << " *>(iIntf));\n";
1089 });
Yifan Hongb04de382017-02-06 15:31:52 -08001090 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001091 });
Yifan Hong158655a2016-11-08 12:34:07 -08001092 });
Martijn Coenen8adcb652017-02-03 17:37:36 +01001093 out << "};\n\n";
1094 out << "__attribute__((destructor))";
1095 out << "static void static_destructor() {\n";
1096 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001097 out << "::android::hardware::details::gBnConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001098 << iface->localName()
1099 << "::descriptor);\n";
Yifan Honga159f3b2017-03-16 14:53:51 -07001100 out << "::android::hardware::details::gBsConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001101 << iface->localName()
1102 << "::descriptor);\n";
1103 });
1104 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001105
Yifan Hongfe95aa22016-10-19 17:26:45 -07001106 err = generateInterfaceSource(out);
1107 }
1108
1109 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001110 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001111 }
1112
1113 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001114 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001115 }
1116
Steven Moreland40786312016-08-16 10:29:40 -07001117 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001118 err = generatePassthroughSource(out);
1119 }
1120
1121 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001122 const Interface *iface = mRootScope->getInterface();
1123
Yifan Hongc8934042016-11-17 17:10:52 -08001124 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001125 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001126 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001127 std::string package = iface->fqName().package()
1128 + iface->fqName().atVersion();
1129
Yifan Hongeefe4f22017-01-04 15:32:42 -08001130 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001131 }
Steven Moreland40786312016-08-16 10:29:40 -07001132 }
1133
Andreas Huber881227d2016-08-02 14:20:21 -07001134 enterLeaveNamespace(out, false /* enter */);
1135
1136 return err;
1137}
1138
Steven Moreland67f67b42016-09-29 08:59:02 -07001139// static
1140void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001141 out.sIf(nonNull + " == nullptr", [&] {
1142 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1143 out.indent(2, [&] {
1144 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1145 });
1146 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001147}
1148
Andreas Huber881227d2016-08-02 14:20:21 -07001149status_t AST::generateTypeSource(
1150 Formatter &out, const std::string &ifaceName) const {
1151 return mRootScope->emitTypeDefinitions(out, ifaceName);
1152}
1153
Andreas Hubere7ff2282016-08-16 13:50:03 -07001154void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001155 Formatter &out,
1156 const std::vector<TypedVar *> &args,
1157 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001158 if (args.empty()) {
1159 return;
1160 }
1161
1162 for (const auto &arg : args) {
1163 const Type &type = arg->type();
1164
Yifan Hong3b320f82016-11-01 15:15:54 -07001165 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001166 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001167 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001168 << ";\n";
1169 }
1170
1171 out << "\n";
1172}
1173
Andreas Huber881227d2016-08-02 14:20:21 -07001174void AST::emitCppReaderWriter(
1175 Formatter &out,
1176 const std::string &parcelObj,
1177 bool parcelObjIsPointer,
1178 const TypedVar *arg,
1179 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001180 Type::ErrorMode mode,
1181 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001182 const Type &type = arg->type();
1183
Andreas Huber881227d2016-08-02 14:20:21 -07001184 type.emitReaderWriter(
1185 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001186 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001187 parcelObj,
1188 parcelObjIsPointer,
1189 isReader,
1190 mode);
1191}
1192
Yifan Hongbf459bc2016-08-23 16:50:37 -07001193void AST::emitCppResolveReferences(
1194 Formatter &out,
1195 const std::string &parcelObj,
1196 bool parcelObjIsPointer,
1197 const TypedVar *arg,
1198 bool isReader,
1199 Type::ErrorMode mode,
1200 bool addPrefixToName) const {
1201 const Type &type = arg->type();
1202 if(type.needsResolveReferences()) {
1203 type.emitResolveReferences(
1204 out,
1205 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1206 isReader, // nameIsPointer
1207 parcelObj,
1208 parcelObjIsPointer,
1209 isReader,
1210 mode);
1211 }
1212}
1213
Yifan Hong068c5522016-10-31 14:07:25 -07001214status_t AST::generateProxyMethodSource(Formatter &out,
1215 const std::string &klassName,
1216 const Method *method,
1217 const Interface *superInterface) const {
1218
1219 method->generateCppSignature(out,
1220 klassName,
1221 true /* specify namespaces */);
1222
1223 const bool returnsValue = !method->results().empty();
1224 const TypedVar *elidedReturn = method->canElideCallback();
1225
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001226 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001227
1228 out.indent();
1229
Martijn Coenen115d4282016-12-19 05:14:04 +01001230 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1231 method->cppImpl(IMPL_PROXY, out);
1232 out.unindent();
1233 out << "}\n\n";
1234 return OK;
1235 }
1236
Yifan Hong068c5522016-10-31 14:07:25 -07001237 if (returnsValue && elidedReturn == nullptr) {
1238 generateCheckNonNull(out, "_hidl_cb");
1239 }
1240
1241 status_t status = generateCppInstrumentationCall(
1242 out,
1243 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001244 method);
1245 if (status != OK) {
1246 return status;
1247 }
1248
1249 out << "::android::hardware::Parcel _hidl_data;\n";
1250 out << "::android::hardware::Parcel _hidl_reply;\n";
1251 out << "::android::status_t _hidl_err;\n";
1252 out << "::android::hardware::Status _hidl_status;\n\n";
1253
1254 declareCppReaderLocals(
1255 out, method->results(), true /* forResults */);
1256
1257 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001258 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001259 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001260 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1261
Martijn Coenenfff73352017-01-04 16:36:31 +01001262 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001263 // First DFS: write all buffers and resolve pointers for parent
1264 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001265 if (arg->type().isInterface()) {
1266 hasInterfaceArgument = true;
1267 }
Yifan Hong068c5522016-10-31 14:07:25 -07001268 emitCppReaderWriter(
1269 out,
1270 "_hidl_data",
1271 false /* parcelObjIsPointer */,
1272 arg,
1273 false /* reader */,
1274 Type::ErrorMode_Goto,
1275 false /* addPrefixToName */);
1276 }
1277
1278 // Second DFS: resolve references.
1279 for (const auto &arg : method->args()) {
1280 emitCppResolveReferences(
1281 out,
1282 "_hidl_data",
1283 false /* parcelObjIsPointer */,
1284 arg,
1285 false /* reader */,
1286 Type::ErrorMode_Goto,
1287 false /* addPrefixToName */);
1288 }
1289
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001290 if (hasInterfaceArgument) {
1291 // Start binder threadpool to handle incoming transactions
1292 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1293 }
Yifan Hong068c5522016-10-31 14:07:25 -07001294 out << "_hidl_err = remote()->transact("
1295 << method->getSerialId()
1296 << " /* "
1297 << method->name()
1298 << " */, _hidl_data, &_hidl_reply";
1299
1300 if (method->isOneway()) {
1301 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1302 }
1303 out << ");\n";
1304
1305 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1306
1307 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001308 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001309 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1310 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1311
1312
1313 // First DFS: write all buffers and resolve pointers for parent
1314 for (const auto &arg : method->results()) {
1315 emitCppReaderWriter(
1316 out,
1317 "_hidl_reply",
1318 false /* parcelObjIsPointer */,
1319 arg,
1320 true /* reader */,
1321 Type::ErrorMode_Goto,
1322 true /* addPrefixToName */);
1323 }
1324
1325 // Second DFS: resolve references.
1326 for (const auto &arg : method->results()) {
1327 emitCppResolveReferences(
1328 out,
1329 "_hidl_reply",
1330 false /* parcelObjIsPointer */,
1331 arg,
1332 true /* reader */,
1333 Type::ErrorMode_Goto,
1334 true /* addPrefixToName */);
1335 }
1336
1337 if (returnsValue && elidedReturn == nullptr) {
1338 out << "_hidl_cb(";
1339
Yifan Hong932464e2017-03-30 15:40:22 -07001340 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001341 if (arg->type().resultNeedsDeref()) {
1342 out << "*";
1343 }
1344 out << "_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001345 });
Yifan Hong068c5522016-10-31 14:07:25 -07001346
1347 out << ");\n\n";
1348 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001349 }
1350 status = generateCppInstrumentationCall(
1351 out,
1352 InstrumentationEvent::CLIENT_API_EXIT,
1353 method);
1354 if (status != OK) {
1355 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001356 }
1357
1358 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001359 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1360 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001361 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001362 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1363 } else {
1364 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1365 out << "return ::android::hardware::Return<void>();\n\n";
1366 }
1367
1368 out.unindent();
1369 out << "_hidl_error:\n";
1370 out.indent();
1371 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1372 out << "return ::android::hardware::Return<";
1373 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001374 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001375 } else {
1376 out << "void";
1377 }
1378 out << ">(_hidl_status);\n";
1379
1380 out.unindent();
1381 out << "}\n\n";
1382 return OK;
1383}
1384
Andreas Huber881227d2016-08-02 14:20:21 -07001385status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001386 Formatter &out, const FQName &fqName) const {
1387 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001388
1389 out << klassName
1390 << "::"
1391 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001392 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001393
1394 out.indent();
1395 out.indent();
1396
1397 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001398 << "<"
1399 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001400 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001401 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001402 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001403 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001404 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001405 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001406
Andreas Huber881227d2016-08-02 14:20:21 -07001407 out.unindent();
1408 out.unindent();
1409 out << "}\n\n";
1410
Yifan Hong068c5522016-10-31 14:07:25 -07001411 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1412 return generateProxyMethodSource(out, klassName, method, superInterface);
1413 });
Andreas Huber881227d2016-08-02 14:20:21 -07001414
Yifan Hong068c5522016-10-31 14:07:25 -07001415 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001416}
1417
1418status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001419 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001420 const Interface *iface) const {
1421 const std::string interfaceName = iface->localName();
1422 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001423
Steven Moreland40786312016-08-16 10:29:40 -07001424 out << klassName
1425 << "::"
1426 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001427 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001428
1429 out.indent();
1430 out.indent();
1431
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001432 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001433 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001434 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001435 out << ": "
1436 << gIBaseFqName.getInterfaceStubFqName().cppName()
1437 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001438 }
1439
1440 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001441 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001442 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001443 << "\") { \n";
1444 out.indent();
1445 out << "_hidl_mImpl = _hidl_impl;\n";
1446 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001447
1448 out.unindent();
1449 out.unindent();
1450 out << "}\n\n";
1451
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001452 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001453 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001454 // class properly.
1455 out << klassName
1456 << "::"
1457 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001458 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1459 << " const std::string &HidlInstrumentor_package,"
1460 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001461
1462 out.indent();
1463 out.indent();
1464
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001465 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001466 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001467 out.indent();
1468 out << "_hidl_mImpl = _hidl_impl;\n";
1469 out.unindent();
1470
1471 out.unindent();
1472 out.unindent();
1473 out << "}\n\n";
1474 }
1475
Yifan Hongbcffce22017-02-01 15:52:06 -08001476 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1477 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1478 return OK;
1479 }
1480 method->generateCppSignature(out, iface->getStubName());
1481 out << " ";
1482 out.block([&] {
1483 method->cppImpl(IMPL_STUB_IMPL, out);
1484 }).endl();
1485 return OK;
1486 });
Steven Moreland60818632017-02-04 00:33:42 -08001487 if (err != OK) {
1488 return err;
1489 }
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001490
Andreas Huber881227d2016-08-02 14:20:21 -07001491 out << "::android::status_t " << klassName << "::onTransact(\n";
1492
1493 out.indent();
1494 out.indent();
1495
Iliyan Malchev549e2592016-08-10 08:59:12 -07001496 out << "uint32_t _hidl_code,\n"
1497 << "const ::android::hardware::Parcel &_hidl_data,\n"
1498 << "::android::hardware::Parcel *_hidl_reply,\n"
1499 << "uint32_t _hidl_flags,\n"
1500 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001501
1502 out.unindent();
1503
Iliyan Malchev549e2592016-08-10 08:59:12 -07001504 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001505 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001506 out.indent();
1507
Yifan Hong10fe0b52016-10-19 14:20:17 -07001508 for (const auto &tuple : iface->allMethodsFromRoot()) {
1509 const Method *method = tuple.method();
1510 const Interface *superInterface = tuple.interface();
1511 out << "case "
1512 << method->getSerialId()
1513 << " /* "
1514 << method->name()
1515 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001516
Yifan Hong10fe0b52016-10-19 14:20:17 -07001517 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001518
Yifan Hong10fe0b52016-10-19 14:20:17 -07001519 status_t err =
1520 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001521
Yifan Hong10fe0b52016-10-19 14:20:17 -07001522 if (err != OK) {
1523 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001524 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001525
1526 out.unindent();
1527 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001528 }
1529
1530 out << "default:\n{\n";
1531 out.indent();
1532
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001533 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001534
1535 out.indent();
1536 out.indent();
1537
Iliyan Malchev549e2592016-08-10 08:59:12 -07001538 out << "_hidl_code, _hidl_data, _hidl_reply, "
1539 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001540
1541 out.unindent();
1542 out.unindent();
1543
1544 out.unindent();
1545 out << "}\n";
1546
1547 out.unindent();
1548 out << "}\n\n";
1549
Yifan Honga018ed52016-12-13 16:35:08 -08001550 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1551 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1552 out.indent(2, [&] {
1553 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1554 out << "_hidl_reply);\n";
1555 });
1556 });
Andreas Huber881227d2016-08-02 14:20:21 -07001557
Iliyan Malchev549e2592016-08-10 08:59:12 -07001558 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001559
1560 out.unindent();
1561 out << "}\n\n";
1562
1563 return OK;
1564}
1565
1566status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001567 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001568 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1569 method->cppImpl(IMPL_STUB, out);
1570 out << "break;\n";
1571 return OK;
1572 }
1573
Yifan Hongeefe4f22017-01-04 15:32:42 -08001574 out << "if (!_hidl_data.enforceInterface("
1575 << iface->fullName()
1576 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001577
Andreas Huber881227d2016-08-02 14:20:21 -07001578 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001579 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001580 out << "break;\n";
1581 out.unindent();
1582 out << "}\n\n";
1583
Andreas Huber5e44a292016-09-27 14:52:39 -07001584 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001585
Yifan Hongbf459bc2016-08-23 16:50:37 -07001586 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001587 for (const auto &arg : method->args()) {
1588 emitCppReaderWriter(
1589 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001590 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001591 false /* parcelObjIsPointer */,
1592 arg,
1593 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001594 Type::ErrorMode_Break,
1595 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001596 }
1597
Yifan Hongbf459bc2016-08-23 16:50:37 -07001598 // Second DFS: resolve references
1599 for (const auto &arg : method->args()) {
1600 emitCppResolveReferences(
1601 out,
1602 "_hidl_data",
1603 false /* parcelObjIsPointer */,
1604 arg,
1605 true /* reader */,
1606 Type::ErrorMode_Break,
1607 false /* addPrefixToName */);
1608 }
1609
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001610 status_t status = generateCppInstrumentationCall(
1611 out,
1612 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001613 method);
1614 if (status != OK) {
1615 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001616 }
1617
Andreas Huber881227d2016-08-02 14:20:21 -07001618 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001619 const TypedVar *elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -08001620 const std::string callee =
1621 (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL))
1622 ? "this" : "_hidl_mImpl";
Andreas Huber881227d2016-08-02 14:20:21 -07001623
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001624 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001625 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001626 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001627 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001628 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001629 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001630 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001631
Yifan Hong932464e2017-03-30 15:40:22 -07001632 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001633 if (arg->type().resultNeedsDeref()) {
1634 out << "*";
1635 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001636 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001637 });
Andreas Huber881227d2016-08-02 14:20:21 -07001638
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001639 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001640 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1641 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001642
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001643 elidedReturn->type().emitReaderWriter(
1644 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001645 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001646 "_hidl_reply",
1647 true, /* parcelObjIsPointer */
1648 false, /* isReader */
1649 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001650
Yifan Hongbf459bc2016-08-23 16:50:37 -07001651 emitCppResolveReferences(
1652 out,
1653 "_hidl_reply",
1654 true /* parcelObjIsPointer */,
1655 elidedReturn,
1656 false /* reader */,
1657 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001658 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001659
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001660 status_t status = generateCppInstrumentationCall(
1661 out,
1662 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001663 method);
1664 if (status != OK) {
1665 return status;
1666 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001667
Iliyan Malchev549e2592016-08-10 08:59:12 -07001668 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001669 } else {
1670 if (returnsValue) {
1671 out << "bool _hidl_callbackCalled = false;\n\n";
1672 }
Andreas Huber881227d2016-08-02 14:20:21 -07001673
Yifan Hongcd2ae452017-01-31 14:33:40 -08001674 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001675
Yifan Hong932464e2017-03-30 15:40:22 -07001676 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001677 if (arg->type().resultNeedsDeref()) {
1678 out << "*";
1679 }
1680
1681 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001682 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001683
1684 if (returnsValue) {
Yifan Hong932464e2017-03-30 15:40:22 -07001685 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001686 out << ", ";
1687 }
1688
1689 out << "[&](";
1690
Yifan Hong932464e2017-03-30 15:40:22 -07001691 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001692 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001693 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001694
1695 out << ") {\n";
1696 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001697 out << "if (_hidl_callbackCalled) {\n";
1698 out.indent();
1699 out << "LOG_ALWAYS_FATAL(\""
1700 << method->name()
1701 << ": _hidl_cb called a second time, but must be called once.\");\n";
1702 out.unindent();
1703 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001704 out << "_hidl_callbackCalled = true;\n\n";
1705
Yifan Hong859e53f2016-11-14 19:08:24 -08001706 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1707 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001708
Yifan Hongbf459bc2016-08-23 16:50:37 -07001709 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001710 for (const auto &arg : method->results()) {
1711 emitCppReaderWriter(
1712 out,
1713 "_hidl_reply",
1714 true /* parcelObjIsPointer */,
1715 arg,
1716 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001717 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001718 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001719 }
1720
Yifan Hongbf459bc2016-08-23 16:50:37 -07001721 // Second DFS: resolve references
1722 for (const auto &arg : method->results()) {
1723 emitCppResolveReferences(
1724 out,
1725 "_hidl_reply",
1726 true /* parcelObjIsPointer */,
1727 arg,
1728 false /* reader */,
1729 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001730 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001731 }
1732
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001733 status_t status = generateCppInstrumentationCall(
1734 out,
1735 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001736 method);
1737 if (status != OK) {
1738 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001739 }
1740
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001741 out << "_hidl_cb(*_hidl_reply);\n";
1742
1743 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001744 out << "});\n\n";
1745 } else {
1746 out << ");\n\n";
1747 status_t status = generateCppInstrumentationCall(
1748 out,
1749 InstrumentationEvent::SERVER_API_EXIT,
1750 method);
1751 if (status != OK) {
1752 return status;
1753 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001754 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001755
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001756 if (returnsValue) {
1757 out << "if (!_hidl_callbackCalled) {\n";
1758 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001759 out << "LOG_ALWAYS_FATAL(\""
1760 << method->name()
1761 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001762 out.unindent();
1763 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001764 } else {
1765 out << "::android::hardware::writeToParcel("
1766 << "::android::hardware::Status::ok(), "
1767 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001768 }
Andreas Huber881227d2016-08-02 14:20:21 -07001769 }
1770
1771 out << "break;\n";
1772
1773 return OK;
1774}
1775
Steven Moreland69e7c702016-09-09 11:16:32 -07001776status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1777 std::string ifaceName;
1778 if (!AST::isInterface(&ifaceName)) {
1779 // types.hal does not get a stub header.
1780 return OK;
1781 }
1782
1783 const Interface *iface = mRootScope->getInterface();
1784
Yifan Hongeefe4f22017-01-04 15:32:42 -08001785 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001786
1787 bool supportOneway = iface->hasOnewayMethods();
1788
1789 std::string path = outputPath;
1790 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1791 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1792 path.append(klassName);
1793 path.append(".h");
1794
1795 CHECK(Coordinator::MakeParentHierarchy(path));
1796 FILE *file = fopen(path.c_str(), "w");
1797
1798 if (file == NULL) {
1799 return -errno;
1800 }
1801
1802 Formatter out(file);
1803
1804 const std::string guard = makeHeaderGuard(klassName);
1805
1806 out << "#ifndef " << guard << "\n";
1807 out << "#define " << guard << "\n\n";
1808
1809 std::vector<std::string> packageComponents;
1810 getPackageAndVersionComponents(
1811 &packageComponents, false /* cpp_compatible */);
1812
Yifan Hongb0949432016-12-15 15:32:24 -08001813 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001814 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001815
1816 generateCppPackageInclude(out, mPackage, ifaceName);
1817 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001818
Yifan Hong7a118f52016-12-07 11:21:15 -08001819 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001820 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001821 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001822 }
1823
1824 enterLeaveNamespace(out, true /* enter */);
1825 out << "\n";
1826
1827 out << "struct "
1828 << klassName
1829 << " : " << ifaceName
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001830 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001831
1832 out.indent();
1833 out << "explicit "
1834 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001835 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001836 << ifaceName
1837 << "> impl);\n";
1838
Yifan Hong068c5522016-10-31 14:07:25 -07001839 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1840 return generatePassthroughMethod(out, method);
1841 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001842
1843 if (err != OK) {
1844 return err;
1845 }
1846
1847 out.unindent();
1848 out << "private:\n";
1849 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001850 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001851
1852 if (supportOneway) {
Yifan Hongef91d362017-03-20 17:18:13 -07001853 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001854
1855 out << "\n";
1856
1857 out << "::android::hardware::Return<void> addOnewayTask("
1858 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001859 }
1860
1861 out.unindent();
1862
1863 out << "};\n\n";
1864
1865 enterLeaveNamespace(out, false /* enter */);
1866
1867 out << "\n#endif // " << guard << "\n";
1868
1869 return OK;
1870}
1871
Yifan Hongfe95aa22016-10-19 17:26:45 -07001872status_t AST::generateInterfaceSource(Formatter &out) const {
1873 const Interface *iface = mRootScope->getInterface();
1874
Yifan Hong2d7126b2016-10-20 15:12:57 -07001875 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001876 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001877
Steven Morelandd4b068a2017-03-20 06:30:51 -07001878 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1879 bool reserved = method->isHidlReserved();
1880
1881 if (!reserved) {
1882 out << "// no default implementation for: ";
1883 }
1884 method->generateCppSignature(out, iface->localName());
1885 if (reserved) {
1886 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001887 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001888 }).endl();
1889 }
1890
1891 out << "\n";
1892
1893 return OK;
1894 });
1895 if (err != OK) {
1896 return err;
1897 }
1898
Yifan Hong3d746092016-12-07 14:26:33 -08001899 for (const Interface *superType : iface->typeChain()) {
Yifan Hong200209c2017-03-29 03:39:09 -07001900 out << "// static \n::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -08001901 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -07001902 << "> "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001903 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001904 << "::castFrom("
1905 << superType->getCppArgumentType()
Yifan Hong200209c2017-03-29 03:39:09 -07001906 << " parent, bool "
1907 << (iface == superType ? "/* emitError */" : "emitError")
1908 << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001909 out.indent();
1910 if (iface == superType) {
1911 out << "return parent;\n";
1912 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001913 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001914 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001915 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001916 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001917 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001918 << ">(\n";
1919 out.indent();
1920 out.indent();
1921 out << "parent, \""
1922 << iface->fqName().string()
Yifan Hong200209c2017-03-29 03:39:09 -07001923 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001924 out.unindent();
1925 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001926 }
Yifan Hong3d746092016-12-07 14:26:33 -08001927 out.unindent();
1928 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001929 }
1930
1931 return OK;
1932}
1933
Steven Moreland69e7c702016-09-09 11:16:32 -07001934status_t AST::generatePassthroughSource(Formatter &out) const {
1935 const Interface *iface = mRootScope->getInterface();
1936
Yifan Hongeefe4f22017-01-04 15:32:42 -08001937 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001938
1939 out << klassName
1940 << "::"
1941 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001942 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001943 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001944 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001945 << mPackage.string()
1946 << "\", \""
1947 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001948 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001949 if (iface->hasOnewayMethods()) {
1950 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001951 out.indent([&] {
Yifan Hongf01dad42017-03-20 19:03:11 -07001952 out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001953 });
1954 }
1955 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001956
1957 if (iface->hasOnewayMethods()) {
1958 out << "::android::hardware::Return<void> "
1959 << klassName
1960 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1961 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001962 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001963 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001964 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1965 out.indent();
1966 out.indent();
1967 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1968 out.unindent();
1969 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001970 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001971 out << "}\n";
1972
Steven Morelandd366c262016-10-11 15:29:10 -07001973 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001974
1975 out.unindent();
1976 out << "}\n\n";
1977
1978
1979 }
1980
1981 return OK;
1982}
1983
Martijn Coenen7b295242016-11-04 16:52:56 +01001984status_t AST::generateCppAtraceCall(Formatter &out,
1985 InstrumentationEvent event,
1986 const Method *method) const {
1987 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001988 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001989 switch (event) {
1990 case SERVER_API_ENTRY:
1991 {
1992 out << "atrace_begin(ATRACE_TAG_HAL, \""
1993 << baseString + "::server\");\n";
1994 break;
1995 }
1996 case CLIENT_API_ENTRY:
1997 {
1998 out << "atrace_begin(ATRACE_TAG_HAL, \""
1999 << baseString + "::client\");\n";
2000 break;
2001 }
2002 case PASSTHROUGH_ENTRY:
2003 {
2004 out << "atrace_begin(ATRACE_TAG_HAL, \""
2005 << baseString + "::passthrough\");\n";
2006 break;
2007 }
2008 case SERVER_API_EXIT:
2009 case CLIENT_API_EXIT:
2010 case PASSTHROUGH_EXIT:
2011 {
2012 out << "atrace_end(ATRACE_TAG_HAL);\n";
2013 break;
2014 }
2015 default:
2016 {
2017 LOG(ERROR) << "Unsupported instrumentation event: " << event;
2018 return UNKNOWN_ERROR;
2019 }
2020 }
2021
2022 return OK;
2023}
2024
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002025status_t AST::generateCppInstrumentationCall(
2026 Formatter &out,
2027 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07002028 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01002029 status_t err = generateCppAtraceCall(out, event, method);
2030 if (err != OK) {
2031 return err;
2032 }
2033
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002034 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
2035 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002036 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002037 std::string event_str = "";
2038 switch (event) {
2039 case SERVER_API_ENTRY:
2040 {
2041 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
2042 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002043 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002044 << (arg->type().resultNeedsDeref() ? "" : "&")
2045 << arg->name()
2046 << ");\n";
2047 }
2048 break;
2049 }
2050 case SERVER_API_EXIT:
2051 {
2052 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07002053 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002054 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07002055 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002056 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002057 }
2058 break;
2059 }
2060 case CLIENT_API_ENTRY:
2061 {
2062 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2063 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002064 out << "_hidl_args.push_back((void *)&"
2065 << arg->name()
2066 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002067 }
2068 break;
2069 }
2070 case CLIENT_API_EXIT:
2071 {
2072 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2073 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002074 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002075 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002076 << "_hidl_out_"
2077 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002078 << ");\n";
2079 }
2080 break;
2081 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002082 case PASSTHROUGH_ENTRY:
2083 {
2084 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2085 for (const auto &arg : method->args()) {
2086 out << "_hidl_args.push_back((void *)&"
2087 << arg->name()
2088 << ");\n";
2089 }
2090 break;
2091 }
2092 case PASSTHROUGH_EXIT:
2093 {
2094 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002095 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002096 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002097 << arg->name()
2098 << ");\n";
2099 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002100 break;
2101 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002102 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002103 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002104 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002105 return UNKNOWN_ERROR;
2106 }
2107 }
2108
Steven Moreland031ccf12016-10-31 15:54:38 -07002109 const Interface *iface = mRootScope->getInterface();
2110
Steven Moreland1ab31442016-11-03 18:37:51 -07002111 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002112 out.indent();
2113 out << "callback("
2114 << event_str
2115 << ", \""
2116 << mPackage.package()
2117 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002118 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002119 << "\", \""
2120 << iface->localName()
2121 << "\", \""
2122 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002123 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002124 out.unindent();
2125 out << "}\n";
2126 out.unindent();
2127 out << "}\n\n";
2128
2129 return OK;
2130}
2131
Andreas Huber881227d2016-08-02 14:20:21 -07002132} // namespace android