blob: d7e581e73c23220d25c227d5cba50df62850a468 [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 Morelandeec5f7a2017-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 Morelandeec5f7a2017-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 Morelandeec5f7a2017-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 Morelandeec5f7a2017-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 Morelandeec5f7a2017-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 Morelandeec5f7a2017-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 Morelandeec5f7a2017-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 Moreland8146c322017-04-06 09:17:44 -0700171 out << "using ::android::hardware::defaultServiceManager;\n";
172 out << "using ::android::hardware::details::waitForHwService;\n";
173 out << "using ::android::hardware::getPassthroughServiceManager;\n";
174 out << "using ::android::hardware::Return;\n";
175 out << "using ::android::sp;\n";
176 out << "using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;\n\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000177
Steven Moreland8146c322017-04-06 09:17:44 -0700178 out << "sp<" << interfaceName << "> iface = nullptr;\n";
179
180 out.endl();
181
182 out << "const sp<::android::hidl::manager::V1_0::IServiceManager> sm"
183 << " = defaultServiceManager();\n";
184
185 out.sIf("sm == nullptr", [&] {
186 // hwbinder is not available on this device, so future tries
187 // would also be null. I can only return nullptr.
188 out << "ALOGE(\"getService: defaultServiceManager() is null\");\n"
189 << "return nullptr;\n";
190 }).endl().endl();
191
192 out << "Return<Transport> transportRet = sm->getTransport("
193 << interfaceName << "::descriptor, serviceName);\n\n";
194
195 out.sIf("!transportRet.isOk()", [&] {
196 out << "ALOGE(\"getService: defaultServiceManager()->getTransport returns %s\", "
197 << "transportRet.description().c_str());\n";
198 out << "return nullptr;\n";
199 });
200
201 out.endl();
202
203 out << "Transport transport = transportRet;\n";
204 out << "const bool vintfHwbinder = (transport == Transport::HWBINDER);\n"
205 << "const bool vintfPassthru = (transport == Transport::PASSTHROUGH);\n"
206 << "const bool vintfEmpty = (transport == Transport::EMPTY);\n\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000207
208 // if (getStub) {
209 // getPassthroughServiceManager()->get only once.
210 // } else {
211 // if (vintfHwbinder) {
212 // while (no alive service) {
213 // waitForHwService
214 // defaultServiceManager()->get
215 // }
216 // } else if (vintfEmpty) {
217 // defaultServiceManager()->get only once.
218 // getPassthroughServiceManager()->get only once.
219 // } else if (vintfPassthru) {
220 // getPassthroughServiceManager()->get only once.
221 // }
222 // }
223
Yifan Hongf1ef44f2017-03-23 17:17:57 +0000224 out << "bool tried = false;\n";
225 out.sWhile("!getStub && (vintfHwbinder || (vintfEmpty && !tried))", [&] {
Yifan Hong31f07ff2017-03-21 18:56:35 +0000226
227 out.sIf("tried", [&] {
228 // sleep only after the first trial.
229 out << "ALOGI(\"getService: retrying in 1s...\");\n"
230 << "sleep(1);\n";
231 }).endl();
232
Yifan Hongf1ef44f2017-03-23 17:17:57 +0000233 out << "tried = true;\n";
234
Yifan Hong31f07ff2017-03-21 18:56:35 +0000235
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700236 if (!isTry) {
237 out.sIf("vintfHwbinder", [&] {
Steven Moreland8146c322017-04-06 09:17:44 -0700238 out << "waitForHwService("
239 << interfaceName << "::descriptor, serviceName);\n";
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700240 }).endl();
241 }
Yifan Hong31f07ff2017-03-21 18:56:35 +0000242
Steven Moreland8146c322017-04-06 09:17:44 -0700243 out << "Return<sp<" << gIBaseFqName.cppName() << ">> ret = \n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000244 out.indent(2, [&] {
245 out << "sm->get(" << interfaceName << "::descriptor, serviceName);\n";
246 });
247
248 out.sIf("!ret.isOk()", [&] {
Steven Moreland42394ce2017-03-27 17:03:04 -0700249 // hwservicemanager fails, may be security issue
Yifan Hong31f07ff2017-03-21 18:56:35 +0000250 out << "ALOGE(\"getService: defaultServiceManager()->get returns %s\", "
251 << "ret.description().c_str());\n"
Steven Moreland42394ce2017-03-27 17:03:04 -0700252 << "break;\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000253 }).endl();
254
Steven Moreland8146c322017-04-06 09:17:44 -0700255 out << "sp<" << gIBaseFqName.cppName() << "> base = ret;\n";
Yifan Hong7783bb02017-03-29 03:39:09 -0700256 out.sIf("base == nullptr", [&] {
257 // race condition. hwservicemanager drops the service
258 // from waitForHwService to here
Steven Morelanddff644c2017-03-24 10:59:01 -0700259 out << "ALOGW(\"getService: found null hwbinder interface\");\n"
Yifan Hongdd0b55d2017-04-04 13:27:25 -0700260 << (isTry ? "break" : "continue")
261 << ";\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000262 }).endl();
Steven Moreland8146c322017-04-06 09:17:44 -0700263 out << "Return<sp<" << interfaceName
Yifan Hong7783bb02017-03-29 03:39:09 -0700264 << ">> castRet = " << interfaceName << "::castFrom(base, true /* emitError */);\n";
265 out.sIf("!castRet.isOk()", [&] {
266 out.sIf("castRet.isDeadObject()", [&] {
267 // service is dead (castFrom cannot call interfaceChain)
268 out << "ALOGW(\"getService: found dead hwbinder service\");\n"
Yifan Hongdd0b55d2017-04-04 13:27:25 -0700269 << (isTry ? "break" : "continue")
270 << ";\n";
Yifan Hong7783bb02017-03-29 03:39:09 -0700271 }).sElse([&] {
272 out << "ALOGW(\"getService: cannot call into hwbinder service: %s"
273 << "; No permission? Check for selinux denials.\", "
274 << "castRet.description().c_str());\n"
275 << "break;\n";
276 }).endl();
277 }).endl();
278 out << "iface = castRet;\n";
279 out.sIf("iface == nullptr", [&] {
280 // returned service isn't of correct type; this is a bug
281 // to hwservicemanager or to the service itself (interfaceChain
282 // is not consistent).
283 out << "ALOGW(\"getService: received incompatible service; bug in hwservicemanager?\");\n"
Yifan Hong31f07ff2017-03-21 18:56:35 +0000284 << "break;\n";
285 }).endl();
286
287 out << "return iface;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800288 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800289
Yifan Hong31f07ff2017-03-21 18:56:35 +0000290 out.sIf("getStub || vintfPassthru || vintfEmpty", [&] {
Steven Moreland8146c322017-04-06 09:17:44 -0700291 out << "const sp<::android::hidl::manager::V1_0::IServiceManager> pm"
292 << " = getPassthroughServiceManager();\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000293
294 out.sIf("pm != nullptr", [&] () {
Steven Moreland8146c322017-04-06 09:17:44 -0700295 out << "Return<sp<" << gIBaseFqName.cppName() << ">> ret = \n";
Steven Morelandf10af872017-01-25 16:01:56 +0000296 out.indent(2, [&] {
297 out << "pm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
Steven Moreland2c2dea82017-01-18 17:24:17 -0800298 });
Steven Morelandf10af872017-01-25 16:01:56 +0000299 out.sIf("ret.isOk()", [&] {
Steven Moreland8146c322017-04-06 09:17:44 -0700300 out << "sp<" << gIBaseFqName.cppName()
Steven Morelandf10af872017-01-25 16:01:56 +0000301 << "> baseInterface = ret;\n";
302 out.sIf("baseInterface != nullptr", [&]() {
303 out << "iface = new " << fqName.getInterfacePassthroughName()
304 << "(" << interfaceName << "::castFrom(baseInterface));\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000305 }).endl();
Steven Morelandf10af872017-01-25 16:01:56 +0000306 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800307 }).endl();
308 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800309
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800310 out << "return iface;\n";
311 }).endl().endl();
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700312}
313
314static void implementServiceManagerInteractions(Formatter &out,
315 const FQName &fqName, const std::string &package) {
316
317 const std::string interfaceName = fqName.getInterfaceName();
318
319 implementGetService(out, fqName, true /* isTry */);
320 implementGetService(out, fqName, false /* isTry */);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800321
Yifan Hongeefe4f22017-01-04 15:32:42 -0800322 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800323 << "const std::string &serviceName) ";
324 out.block([&] {
325 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
326 out.indent(2, [&] {
327 out << "= ::android::hardware::defaultServiceManager();\n";
328 });
329 out.sIf("sm == nullptr", [&] {
330 out << "return ::android::INVALID_OPERATION;\n";
331 }).endl();
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100332 out << "::android::hardware::Return<bool> ret = "
333 << "sm->add(serviceName.c_str(), this);\n"
334 << "return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800335 }).endl().endl();
336
Yifan Hongeefe4f22017-01-04 15:32:42 -0800337 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800338 out.indent(2, [&] {
339 out << "const std::string &serviceName,\n"
340 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
341 << "&notification) ";
342 });
343 out.block([&] {
344 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
345 out.indent(2, [&] {
346 out << "= ::android::hardware::defaultServiceManager();\n";
347 });
348 out.sIf("sm == nullptr", [&] {
349 out << "return false;\n";
350 }).endl();
351 out << "::android::hardware::Return<bool> success =\n";
352 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800353 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800354 out.indent(2, [&] {
355 out << "serviceName, notification);\n";
356 });
357 });
358 out << "return success.isOk() && success;\n";
359 }).endl().endl();
360}
361
Andreas Huberb82318c2016-08-02 14:45:54 -0700362status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700363
Andreas Huberb82318c2016-08-02 14:45:54 -0700364 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700365 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700366 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700367
368 std::string ifaceName;
369 bool isInterface = true;
370 if (!AST::isInterface(&ifaceName)) {
371 ifaceName = "types";
372 isInterface = false;
373 }
374 path.append(ifaceName);
375 path.append(".h");
376
Andreas Huberd2943e12016-08-05 11:59:31 -0700377 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700378 FILE *file = fopen(path.c_str(), "w");
379
380 if (file == NULL) {
381 return -errno;
382 }
383
384 Formatter out(file);
385
386 const std::string guard = makeHeaderGuard(ifaceName);
387
388 out << "#ifndef " << guard << "\n";
389 out << "#define " << guard << "\n\n";
390
Andreas Huber737080b2016-08-02 15:38:04 -0700391 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700392 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700393 }
394
395 if (!mImportedNames.empty()) {
396 out << "\n";
397 }
398
Steven Moreland0693f312016-11-09 15:06:14 -0800399 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800400 if (isIBase()) {
401 out << "// skipped #include IServiceNotification.h\n\n";
402 } else {
403 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
404 }
Steven Moreland0693f312016-11-09 15:06:14 -0800405 }
406
Yifan Hongc8934042016-11-17 17:10:52 -0800407 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700408 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700409
410 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200411 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700412 }
413
Martijn Coenenaf712c02016-11-16 15:26:27 +0100414 out << "#include <utils/NativeHandle.h>\n";
415 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700416
417 enterLeaveNamespace(out, true /* enter */);
418 out << "\n";
419
420 if (isInterface) {
421 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700422 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700423
424 const Interface *iface = mRootScope->getInterface();
425 const Interface *superType = iface->superType();
426
Steven Moreland40786312016-08-16 10:29:40 -0700427 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800428 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700429 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000430 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700431 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700432 }
433
434 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700435
436 out.indent();
437
Andreas Huber881227d2016-08-02 14:20:21 -0700438 }
439
440 status_t err = emitTypeDeclarations(out);
441
442 if (err != OK) {
443 return err;
444 }
445
446 if (isInterface) {
447 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800448
Yifan Hongc8934042016-11-17 17:10:52 -0800449 out << "virtual bool isRemote() const ";
450 if (!isIBase()) {
451 out << "override ";
452 }
453 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800454
Andreas Huber881227d2016-08-02 14:20:21 -0700455 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700456 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700457
Andreas Huber881227d2016-08-02 14:20:21 -0700458 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800459 const TypedVar *elidedReturn = method->canElideCallback();
460
461 if (elidedReturn == nullptr && returnsValue) {
462 out << "using "
463 << method->name()
Yifan Hong7d234ea2017-03-30 15:40:22 -0700464 << "_cb = std::function<void(";
465 method->emitCppResultSignature(out, true /* specify namespaces */);
466 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800467 }
Andreas Huber881227d2016-08-02 14:20:21 -0700468
Andreas Huber3599d922016-08-09 10:42:57 -0700469 method->dumpAnnotations(out);
470
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700471 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700472 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700473 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700474 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700475 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700476 }
477
478 out << method->name()
Yifan Hong7d234ea2017-03-30 15:40:22 -0700479 << "(";
480 method->emitCppArgSignature(out, true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700481
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700482 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700483 if (!method->args().empty()) {
484 out << ", ";
485 }
486
Steven Moreland67f67b42016-09-29 08:59:02 -0700487 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700488 }
489
Yifan Hong10fe0b52016-10-19 14:20:17 -0700490 out << ")";
491 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800492 if (!isIBase()) {
493 out << " override";
494 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700495 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700496 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700497 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700498 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700499 }
Steven Moreland40786312016-08-16 10:29:40 -0700500
Yifan Hong3d746092016-12-07 14:26:33 -0800501 out << "// cast static functions\n";
502 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700503
Yifan Hong3d746092016-12-07 14:26:33 -0800504 for (const Interface *superType : iface->typeChain()) {
Yifan Hong7783bb02017-03-29 03:39:09 -0700505 out << "static ::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -0800506 << childTypeResult
Yifan Hong7783bb02017-03-29 03:39:09 -0700507 << "> castFrom("
Yifan Hong3d746092016-12-07 14:26:33 -0800508 << superType->getCppArgumentType()
509 << " parent"
Yifan Hong7783bb02017-03-29 03:39:09 -0700510 << ", bool emitError = false);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700511 }
512
Steven Morelandd39133b2016-11-11 12:30:08 -0800513 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700514
Yifan Hongc8934042016-11-17 17:10:52 -0800515 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800516 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800517 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800518 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800519 }
Andreas Huber881227d2016-08-02 14:20:21 -0700520 }
521
522 if (isInterface) {
523 out.unindent();
524
Andreas Hubere3f769a2016-10-10 10:54:44 -0700525 out << "};\n\n";
526 }
527
528 err = mRootScope->emitGlobalTypeDeclarations(out);
529
530 if (err != OK) {
531 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700532 }
533
534 out << "\n";
535 enterLeaveNamespace(out, false /* enter */);
536
537 out << "\n#endif // " << guard << "\n";
538
539 return OK;
540}
541
Steven Moreland40786312016-08-16 10:29:40 -0700542status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
543 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800544 bool isInterface = AST::isInterface(&ifaceName);
545 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800546 std::string klassName{};
547
548 if(isInterface) {
549 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800550 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800551 } else {
552 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700553 }
554
Steven Moreland40786312016-08-16 10:29:40 -0700555 std::string path = outputPath;
556 path.append(mCoordinator->convertPackageRootToPath(mPackage));
557 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
558 path.append(klassName + ".h");
559
Yifan Hong244e82d2016-11-11 11:13:57 -0800560 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700561
562 if (file == NULL) {
563 return -errno;
564 }
565
566 Formatter out(file);
567
568 const std::string guard = makeHeaderGuard(klassName);
569
570 out << "#ifndef " << guard << "\n";
571 out << "#define " << guard << "\n\n";
572
Yifan Hong244e82d2016-11-11 11:13:57 -0800573 if (isInterface) {
574 generateCppPackageInclude(out, mPackage, ifaceName);
575 } else {
576 generateCppPackageInclude(out, mPackage, "types");
577 }
Steven Moreland40786312016-08-16 10:29:40 -0700578
Steven Morelandee88eed2016-10-31 17:49:00 -0700579 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700580
581 for (const auto &item : mImportedNames) {
582 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800583 generateCppPackageInclude(out, item, "hwtypes");
584 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800585 generateCppPackageInclude(out, item, item.getInterfaceStubName());
586 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700587 }
Steven Moreland40786312016-08-16 10:29:40 -0700588 }
589
590 out << "\n";
591
Martijn Coenen93915102016-09-01 01:35:52 +0200592 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700593 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100594 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700595
596 out << "\n";
597
598 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700599
Yifan Hong244e82d2016-11-11 11:13:57 -0800600 status_t err = mRootScope->emitGlobalHwDeclarations(out);
601 if (err != OK) {
602 return err;
603 }
Steven Moreland40786312016-08-16 10:29:40 -0700604
605 enterLeaveNamespace(out, false /* enter */);
606
607 out << "\n#endif // " << guard << "\n";
608
609 return OK;
610}
611
Andreas Huber881227d2016-08-02 14:20:21 -0700612status_t AST::emitTypeDeclarations(Formatter &out) const {
613 return mRootScope->emitTypeDeclarations(out);
614}
615
Yifan Hong7a118f52016-12-07 11:21:15 -0800616static void wrapPassthroughArg(Formatter &out,
617 const TypedVar *arg, bool addPrefixToName,
618 std::function<void(void)> handleError) {
619 if (!arg->type().isInterface()) {
620 return;
621 }
622 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
623 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
624 + arg->name();
625 const Interface &iface = static_cast<const Interface &>(arg->type());
626 out << iface.getCppStackType() << " " << wrappedName << ";\n";
627 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
628 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
629 out << wrappedName
630 << " = "
631 << iface.fqName().cppName()
Yifan Hong052425a2017-03-13 17:06:13 -0700632 << "::castFrom(::android::hardware::details::wrapPassthrough("
Yifan Hong7a118f52016-12-07 11:21:15 -0800633 << name << "));\n";
634 out.sIf(wrappedName + " == nullptr", [&] {
635 // Fatal error. Happens when the BsFoo class is not found in the binary
636 // or any dynamic libraries.
637 handleError();
638 }).endl();
639 }).sElse([&] {
640 out << wrappedName << " = " << name << ";\n";
641 }).endl().endl();
642}
643
Steven Moreland69e7c702016-09-09 11:16:32 -0700644status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700645 const Method *method) const {
646 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700647
648 out << " {\n";
649 out.indent();
650
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800651 if (method->isHidlReserved()
652 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
653 method->cppImpl(IMPL_PASSTHROUGH, out);
654 out.unindent();
655 out << "}\n\n";
656 return OK;
657 }
658
Steven Moreland69e7c702016-09-09 11:16:32 -0700659 const bool returnsValue = !method->results().empty();
660 const TypedVar *elidedReturn = method->canElideCallback();
661
Steven Moreland67f67b42016-09-29 08:59:02 -0700662 if (returnsValue && elidedReturn == nullptr) {
663 generateCheckNonNull(out, "_hidl_cb");
664 }
665
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700666 generateCppInstrumentationCall(
667 out,
668 InstrumentationEvent::PASSTHROUGH_ENTRY,
669 method);
670
Yifan Hong7a118f52016-12-07 11:21:15 -0800671
672 for (const auto &arg : method->args()) {
673 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
674 out << "return ::android::hardware::Status::fromExceptionCode(\n";
675 out.indent(2, [&] {
676 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800677 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800678 });
679 });
680 }
681
682 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700683 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700684
685 if (method->isOneway()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800686 out << "addOnewayTask([this, &_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700687 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800688 out << ", "
689 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
690 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700691 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700692 out << "] {\n";
693 out.indent();
694 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700695 }
696
697 out << "mImpl->"
698 << method->name()
699 << "(";
700
Yifan Hong7d234ea2017-03-30 15:40:22 -0700701 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800702 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700703 });
Steven Moreland69e7c702016-09-09 11:16:32 -0700704 if (returnsValue && elidedReturn == nullptr) {
705 if (!method->args().empty()) {
706 out << ", ";
707 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800708 out << "[&](";
Yifan Hong7d234ea2017-03-30 15:40:22 -0700709 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800710 out << "const auto &_hidl_out_"
711 << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700712 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800713
714 out << ") {\n";
715 out.indent();
716 status_t status = generateCppInstrumentationCall(
717 out,
718 InstrumentationEvent::PASSTHROUGH_EXIT,
719 method);
720 if (status != OK) {
721 return status;
722 }
723
Yifan Hong7a118f52016-12-07 11:21:15 -0800724 for (const auto &arg : method->results()) {
725 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
726 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
727 out.indent(2, [&] {
728 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800729 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800730 });
731 out << "return;\n";
732 });
733 }
734
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800735 out << "_hidl_cb(";
Yifan Hong7d234ea2017-03-30 15:40:22 -0700736 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800737 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
738 << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700739 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800740 out << ");\n";
741 out.unindent();
742 out << "});\n\n";
743 } else {
744 out << ");\n\n";
745 if (elidedReturn != nullptr) {
746 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800747 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800748 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000749 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800750 }
751 status_t status = generateCppInstrumentationCall(
752 out,
753 InstrumentationEvent::PASSTHROUGH_EXIT,
754 method);
755 if (status != OK) {
756 return status;
757 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700758 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700759
760 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700761 out.unindent();
762 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700763 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700764
765 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700766
767 out.unindent();
768 out << "}\n";
769
770 return OK;
771}
772
Yifan Hong068c5522016-10-31 14:07:25 -0700773status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700774
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700775 const Interface *iface = mRootScope->getInterface();
776
Yifan Hong10fe0b52016-10-19 14:20:17 -0700777 const Interface *prevIterface = nullptr;
778 for (const auto &tuple : iface->allMethodsFromRoot()) {
779 const Method *method = tuple.method();
780 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700781
Yifan Hong10fe0b52016-10-19 14:20:17 -0700782 if(prevIterface != superInterface) {
783 if (prevIterface != nullptr) {
784 out << "\n";
785 }
786 out << "// Methods from "
787 << superInterface->fullName()
788 << " follow.\n";
789 prevIterface = superInterface;
790 }
Yifan Hong068c5522016-10-31 14:07:25 -0700791 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700792
Yifan Hong10fe0b52016-10-19 14:20:17 -0700793 if (err != OK) {
794 return err;
795 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700796 }
797
Yifan Hong10fe0b52016-10-19 14:20:17 -0700798 out << "\n";
799
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700800 return OK;
801}
802
Andreas Huberb82318c2016-08-02 14:45:54 -0700803status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700804 std::string ifaceName;
805 if (!AST::isInterface(&ifaceName)) {
806 // types.hal does not get a stub header.
807 return OK;
808 }
809
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700810 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800811 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700812
Andreas Huberb82318c2016-08-02 14:45:54 -0700813 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700814 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700815 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700816 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700817 path.append(".h");
818
Andreas Huberd2943e12016-08-05 11:59:31 -0700819 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700820 FILE *file = fopen(path.c_str(), "w");
821
822 if (file == NULL) {
823 return -errno;
824 }
825
826 Formatter out(file);
827
Steven Moreland40786312016-08-16 10:29:40 -0700828 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700829
830 out << "#ifndef " << guard << "\n";
831 out << "#define " << guard << "\n\n";
832
Yifan Hongeefe4f22017-01-04 15:32:42 -0800833 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700834 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700835
836 enterLeaveNamespace(out, true /* enter */);
837 out << "\n";
838
839 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800840 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100841 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800842 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000843 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100844 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800845 out << " : public "
846 << gIBaseFqName.getInterfaceStubFqName().cppName()
847 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100848 }
Andreas Huber881227d2016-08-02 14:20:21 -0700849
850 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800851 out << "explicit "
852 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700853 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100854 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800855 out << "explicit "
856 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100857 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800858 << " const std::string& HidlInstrumentor_package,"
859 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700860 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700861 out << "::android::status_t onTransact(\n";
862 out.indent();
863 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700864 out << "uint32_t _hidl_code,\n";
865 out << "const ::android::hardware::Parcel &_hidl_data,\n";
866 out << "::android::hardware::Parcel *_hidl_reply,\n";
867 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700868 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700869 out.unindent();
870 out.unindent();
871
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100872 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
873 out.unindent();
874 out << "private:\n";
875 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800876
877 status_t err = generateMethods(out, [&](const Method *method, const Interface *iface) {
878 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
879 return OK;
880 }
881 const bool returnsValue = !method->results().empty();
882 const TypedVar *elidedReturn = method->canElideCallback();
883
884 if (elidedReturn == nullptr && returnsValue) {
885 out << "using " << method->name() << "_cb = "
886 << iface->fqName().cppName()
887 << "::" << method->name() << "_cb;\n";
888 }
889 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800890 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800891 return OK;
892 });
893 if (err != OK) {
894 return err;
895 }
896
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100897 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700898 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700899 out << "};\n\n";
900
901 enterLeaveNamespace(out, false /* enter */);
902
903 out << "\n#endif // " << guard << "\n";
904
905 return OK;
906}
907
Andreas Huberb82318c2016-08-02 14:45:54 -0700908status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700909 std::string ifaceName;
910 if (!AST::isInterface(&ifaceName)) {
911 // types.hal does not get a proxy header.
912 return OK;
913 }
914
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700915 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800916 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700917
Andreas Huberb82318c2016-08-02 14:45:54 -0700918 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700919 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700920 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800921 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700922 path.append(".h");
923
Andreas Huberd2943e12016-08-05 11:59:31 -0700924 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700925 FILE *file = fopen(path.c_str(), "w");
926
927 if (file == NULL) {
928 return -errno;
929 }
930
931 Formatter out(file);
932
Yifan Hongeefe4f22017-01-04 15:32:42 -0800933 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700934
935 out << "#ifndef " << guard << "\n";
936 out << "#define " << guard << "\n\n";
937
Martijn Coenen115d4282016-12-19 05:14:04 +0100938 out << "#include <hidl/HidlTransportSupport.h>\n\n";
939
Andreas Huber881227d2016-08-02 14:20:21 -0700940 std::vector<std::string> packageComponents;
941 getPackageAndVersionComponents(
942 &packageComponents, false /* cpp_compatible */);
943
Yifan Hongeefe4f22017-01-04 15:32:42 -0800944 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700945 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700946
947 enterLeaveNamespace(out, true /* enter */);
948 out << "\n";
949
950 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800951 << proxyName
952 << " : public ::android::hardware::BpInterface<"
953 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000954 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700955
956 out.indent();
957
Yifan Hongeefe4f22017-01-04 15:32:42 -0800958 out << "explicit "
959 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700960 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700961 << "\n\n";
962
Yifan Hong10fe0b52016-10-19 14:20:17 -0700963 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700964
Yifan Hong068c5522016-10-31 14:07:25 -0700965 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
966 method->generateCppSignature(out);
967 out << " override;\n";
968 return OK;
969 });
Steven Moreland9c387612016-09-07 09:54:26 -0700970
971 if (err != OK) {
972 return err;
973 }
Andreas Huber881227d2016-08-02 14:20:21 -0700974
975 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100976 out << "private:\n";
977 out.indent();
978 out << "std::mutex _hidl_mMutex;\n"
979 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
980 << " _hidl_mDeathRecipients;\n";
981 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700982 out << "};\n\n";
983
984 enterLeaveNamespace(out, false /* enter */);
985
986 out << "\n#endif // " << guard << "\n";
987
988 return OK;
989}
990
Andreas Huberb82318c2016-08-02 14:45:54 -0700991status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700992
Andreas Huberb82318c2016-08-02 14:45:54 -0700993 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700994 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700995 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700996
997 std::string ifaceName;
998 std::string baseName;
999
Yifan Hongfe95aa22016-10-19 17:26:45 -07001000 const Interface *iface = nullptr;
1001 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -07001002 if (!AST::isInterface(&ifaceName)) {
1003 baseName = "types";
1004 isInterface = false;
1005 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001006 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -07001007 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001008 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -07001009 }
1010
1011 path.append(baseName);
1012
1013 if (baseName != "types") {
1014 path.append("All");
1015 }
1016
1017 path.append(".cpp");
1018
Andreas Huberd2943e12016-08-05 11:59:31 -07001019 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -07001020 FILE *file = fopen(path.c_str(), "w");
1021
1022 if (file == NULL) {
1023 return -errno;
1024 }
1025
1026 Formatter out(file);
1027
Steven Moreland623c0042017-01-13 14:42:29 -08001028 out << "#define LOG_TAG \""
1029 << mPackage.string() << "::" << baseName
1030 << "\"\n\n";
1031
Steven Moreland05cd4232016-11-21 16:01:12 -08001032 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001033 out << "#include <cutils/trace.h>\n";
1034 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001035 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -07001036 // This is a no-op for IServiceManager itself.
1037 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
1038
Steven Morelandbec74ed2017-01-25 17:42:35 -08001039 // TODO(b/34274385) remove this
1040 out << "#include <hidl/LegacySupport.h>\n";
1041
Yifan Hongeefe4f22017-01-04 15:32:42 -08001042 generateCppPackageInclude(out, mPackage, iface->getProxyName());
1043 generateCppPackageInclude(out, mPackage, iface->getStubName());
1044 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001045
1046 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -07001047 generateCppPackageInclude(out,
1048 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -08001049 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001050 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -08001051
1052 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001053 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -07001054 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -08001055 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -07001056 }
1057
1058 out << "\n";
1059
1060 enterLeaveNamespace(out, true /* enter */);
1061 out << "\n";
1062
1063 status_t err = generateTypeSource(out, ifaceName);
1064
1065 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001066 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001067
1068 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -08001069 out << "const char* "
1070 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -07001071 << "::descriptor(\""
1072 << iface->fqName().string()
1073 << "\");\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +01001074 out << "__attribute__((constructor))";
1075 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001076 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001077 out << "::android::hardware::details::gBnConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001078 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001079 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001080 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001081 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001082 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001083 out << "return new "
1084 << iface->getStubName()
1085 << "(reinterpret_cast<"
1086 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001087 << " *>(iIntf));\n";
1088 });
Yifan Hongb04de382017-02-06 15:31:52 -08001089 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001090 });
Yifan Honga159f3b2017-03-16 14:53:51 -07001091 out << "::android::hardware::details::gBsConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001092 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001093 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001094 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001095 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -08001096 << gIBaseFqName.cppName()
1097 << "> {\n";
1098 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001099 out << "return new "
1100 << iface->getPassthroughName()
1101 << "(reinterpret_cast<"
1102 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001103 << " *>(iIntf));\n";
1104 });
Yifan Hongb04de382017-02-06 15:31:52 -08001105 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001106 });
Yifan Hong158655a2016-11-08 12:34:07 -08001107 });
Martijn Coenen8adcb652017-02-03 17:37:36 +01001108 out << "};\n\n";
1109 out << "__attribute__((destructor))";
1110 out << "static void static_destructor() {\n";
1111 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001112 out << "::android::hardware::details::gBnConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001113 << iface->localName()
1114 << "::descriptor);\n";
Yifan Honga159f3b2017-03-16 14:53:51 -07001115 out << "::android::hardware::details::gBsConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001116 << iface->localName()
1117 << "::descriptor);\n";
1118 });
1119 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001120
Yifan Hongfe95aa22016-10-19 17:26:45 -07001121 err = generateInterfaceSource(out);
1122 }
1123
1124 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001125 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001126 }
1127
1128 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001129 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001130 }
1131
Steven Moreland40786312016-08-16 10:29:40 -07001132 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001133 err = generatePassthroughSource(out);
1134 }
1135
1136 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001137 const Interface *iface = mRootScope->getInterface();
1138
Yifan Hongc8934042016-11-17 17:10:52 -08001139 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001140 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001141 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001142 std::string package = iface->fqName().package()
1143 + iface->fqName().atVersion();
1144
Yifan Hongeefe4f22017-01-04 15:32:42 -08001145 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001146 }
Steven Moreland40786312016-08-16 10:29:40 -07001147 }
1148
Andreas Huber881227d2016-08-02 14:20:21 -07001149 enterLeaveNamespace(out, false /* enter */);
1150
1151 return err;
1152}
1153
Steven Moreland67f67b42016-09-29 08:59:02 -07001154// static
1155void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001156 out.sIf(nonNull + " == nullptr", [&] {
1157 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1158 out.indent(2, [&] {
1159 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1160 });
1161 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001162}
1163
Andreas Huber881227d2016-08-02 14:20:21 -07001164status_t AST::generateTypeSource(
1165 Formatter &out, const std::string &ifaceName) const {
1166 return mRootScope->emitTypeDefinitions(out, ifaceName);
1167}
1168
Andreas Hubere7ff2282016-08-16 13:50:03 -07001169void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001170 Formatter &out,
1171 const std::vector<TypedVar *> &args,
1172 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001173 if (args.empty()) {
1174 return;
1175 }
1176
1177 for (const auto &arg : args) {
1178 const Type &type = arg->type();
1179
Yifan Hong3b320f82016-11-01 15:15:54 -07001180 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001181 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001182 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001183 << ";\n";
1184 }
1185
1186 out << "\n";
1187}
1188
Andreas Huber881227d2016-08-02 14:20:21 -07001189void AST::emitCppReaderWriter(
1190 Formatter &out,
1191 const std::string &parcelObj,
1192 bool parcelObjIsPointer,
1193 const TypedVar *arg,
1194 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001195 Type::ErrorMode mode,
1196 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001197 const Type &type = arg->type();
1198
Andreas Huber881227d2016-08-02 14:20:21 -07001199 type.emitReaderWriter(
1200 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001201 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001202 parcelObj,
1203 parcelObjIsPointer,
1204 isReader,
1205 mode);
1206}
1207
Yifan Hongbf459bc2016-08-23 16:50:37 -07001208void AST::emitCppResolveReferences(
1209 Formatter &out,
1210 const std::string &parcelObj,
1211 bool parcelObjIsPointer,
1212 const TypedVar *arg,
1213 bool isReader,
1214 Type::ErrorMode mode,
1215 bool addPrefixToName) const {
1216 const Type &type = arg->type();
1217 if(type.needsResolveReferences()) {
1218 type.emitResolveReferences(
1219 out,
1220 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1221 isReader, // nameIsPointer
1222 parcelObj,
1223 parcelObjIsPointer,
1224 isReader,
1225 mode);
1226 }
1227}
1228
Yifan Hong068c5522016-10-31 14:07:25 -07001229status_t AST::generateProxyMethodSource(Formatter &out,
1230 const std::string &klassName,
1231 const Method *method,
1232 const Interface *superInterface) const {
1233
1234 method->generateCppSignature(out,
1235 klassName,
1236 true /* specify namespaces */);
1237
1238 const bool returnsValue = !method->results().empty();
1239 const TypedVar *elidedReturn = method->canElideCallback();
1240
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001241 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001242
1243 out.indent();
1244
Martijn Coenen115d4282016-12-19 05:14:04 +01001245 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1246 method->cppImpl(IMPL_PROXY, out);
1247 out.unindent();
1248 out << "}\n\n";
1249 return OK;
1250 }
1251
Yifan Hong068c5522016-10-31 14:07:25 -07001252 if (returnsValue && elidedReturn == nullptr) {
1253 generateCheckNonNull(out, "_hidl_cb");
1254 }
1255
1256 status_t status = generateCppInstrumentationCall(
1257 out,
1258 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001259 method);
1260 if (status != OK) {
1261 return status;
1262 }
1263
1264 out << "::android::hardware::Parcel _hidl_data;\n";
1265 out << "::android::hardware::Parcel _hidl_reply;\n";
1266 out << "::android::status_t _hidl_err;\n";
1267 out << "::android::hardware::Status _hidl_status;\n\n";
1268
1269 declareCppReaderLocals(
1270 out, method->results(), true /* forResults */);
1271
1272 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001273 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001274 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001275 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1276
Martijn Coenenfff73352017-01-04 16:36:31 +01001277 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001278 // First DFS: write all buffers and resolve pointers for parent
1279 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001280 if (arg->type().isInterface()) {
1281 hasInterfaceArgument = true;
1282 }
Yifan Hong068c5522016-10-31 14:07:25 -07001283 emitCppReaderWriter(
1284 out,
1285 "_hidl_data",
1286 false /* parcelObjIsPointer */,
1287 arg,
1288 false /* reader */,
1289 Type::ErrorMode_Goto,
1290 false /* addPrefixToName */);
1291 }
1292
1293 // Second DFS: resolve references.
1294 for (const auto &arg : method->args()) {
1295 emitCppResolveReferences(
1296 out,
1297 "_hidl_data",
1298 false /* parcelObjIsPointer */,
1299 arg,
1300 false /* reader */,
1301 Type::ErrorMode_Goto,
1302 false /* addPrefixToName */);
1303 }
1304
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001305 if (hasInterfaceArgument) {
1306 // Start binder threadpool to handle incoming transactions
1307 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1308 }
Yifan Hong068c5522016-10-31 14:07:25 -07001309 out << "_hidl_err = remote()->transact("
1310 << method->getSerialId()
1311 << " /* "
1312 << method->name()
1313 << " */, _hidl_data, &_hidl_reply";
1314
1315 if (method->isOneway()) {
1316 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1317 }
1318 out << ");\n";
1319
1320 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1321
1322 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001323 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001324 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1325 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1326
1327
1328 // First DFS: write all buffers and resolve pointers for parent
1329 for (const auto &arg : method->results()) {
1330 emitCppReaderWriter(
1331 out,
1332 "_hidl_reply",
1333 false /* parcelObjIsPointer */,
1334 arg,
1335 true /* reader */,
1336 Type::ErrorMode_Goto,
1337 true /* addPrefixToName */);
1338 }
1339
1340 // Second DFS: resolve references.
1341 for (const auto &arg : method->results()) {
1342 emitCppResolveReferences(
1343 out,
1344 "_hidl_reply",
1345 false /* parcelObjIsPointer */,
1346 arg,
1347 true /* reader */,
1348 Type::ErrorMode_Goto,
1349 true /* addPrefixToName */);
1350 }
1351
1352 if (returnsValue && elidedReturn == nullptr) {
1353 out << "_hidl_cb(";
1354
Yifan Hong7d234ea2017-03-30 15:40:22 -07001355 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001356 if (arg->type().resultNeedsDeref()) {
1357 out << "*";
1358 }
1359 out << "_hidl_out_" << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001360 });
Yifan Hong068c5522016-10-31 14:07:25 -07001361
1362 out << ");\n\n";
1363 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001364 }
1365 status = generateCppInstrumentationCall(
1366 out,
1367 InstrumentationEvent::CLIENT_API_EXIT,
1368 method);
1369 if (status != OK) {
1370 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001371 }
1372
1373 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001374 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1375 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001376 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001377 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1378 } else {
1379 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1380 out << "return ::android::hardware::Return<void>();\n\n";
1381 }
1382
1383 out.unindent();
1384 out << "_hidl_error:\n";
1385 out.indent();
1386 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1387 out << "return ::android::hardware::Return<";
1388 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001389 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001390 } else {
1391 out << "void";
1392 }
1393 out << ">(_hidl_status);\n";
1394
1395 out.unindent();
1396 out << "}\n\n";
1397 return OK;
1398}
1399
Andreas Huber881227d2016-08-02 14:20:21 -07001400status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001401 Formatter &out, const FQName &fqName) const {
1402 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001403
1404 out << klassName
1405 << "::"
1406 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001407 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001408
1409 out.indent();
1410 out.indent();
1411
1412 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001413 << "<"
1414 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001415 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001416 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001417 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001418 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001419 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001420 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001421
Andreas Huber881227d2016-08-02 14:20:21 -07001422 out.unindent();
1423 out.unindent();
1424 out << "}\n\n";
1425
Yifan Hong068c5522016-10-31 14:07:25 -07001426 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1427 return generateProxyMethodSource(out, klassName, method, superInterface);
1428 });
Andreas Huber881227d2016-08-02 14:20:21 -07001429
Yifan Hong068c5522016-10-31 14:07:25 -07001430 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001431}
1432
1433status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001434 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001435 const Interface *iface) const {
1436 const std::string interfaceName = iface->localName();
1437 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001438
Steven Moreland40786312016-08-16 10:29:40 -07001439 out << klassName
1440 << "::"
1441 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001442 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001443
1444 out.indent();
1445 out.indent();
1446
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001447 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001448 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001449 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001450 out << ": "
1451 << gIBaseFqName.getInterfaceStubFqName().cppName()
1452 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001453 }
1454
1455 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001456 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001457 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001458 << "\") { \n";
1459 out.indent();
1460 out << "_hidl_mImpl = _hidl_impl;\n";
1461 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001462
1463 out.unindent();
1464 out.unindent();
1465 out << "}\n\n";
1466
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001467 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001468 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001469 // class properly.
1470 out << klassName
1471 << "::"
1472 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001473 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1474 << " const std::string &HidlInstrumentor_package,"
1475 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001476
1477 out.indent();
1478 out.indent();
1479
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001480 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001481 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001482 out.indent();
1483 out << "_hidl_mImpl = _hidl_impl;\n";
1484 out.unindent();
1485
1486 out.unindent();
1487 out.unindent();
1488 out << "}\n\n";
1489 }
1490
Yifan Hongbcffce22017-02-01 15:52:06 -08001491 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1492 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1493 return OK;
1494 }
1495 method->generateCppSignature(out, iface->getStubName());
1496 out << " ";
1497 out.block([&] {
1498 method->cppImpl(IMPL_STUB_IMPL, out);
1499 }).endl();
1500 return OK;
1501 });
Steven Moreland60818632017-02-04 00:33:42 -08001502 if (err != OK) {
1503 return err;
1504 }
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001505
Andreas Huber881227d2016-08-02 14:20:21 -07001506 out << "::android::status_t " << klassName << "::onTransact(\n";
1507
1508 out.indent();
1509 out.indent();
1510
Iliyan Malchev549e2592016-08-10 08:59:12 -07001511 out << "uint32_t _hidl_code,\n"
1512 << "const ::android::hardware::Parcel &_hidl_data,\n"
1513 << "::android::hardware::Parcel *_hidl_reply,\n"
1514 << "uint32_t _hidl_flags,\n"
1515 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001516
1517 out.unindent();
1518
Iliyan Malchev549e2592016-08-10 08:59:12 -07001519 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001520 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001521 out.indent();
1522
Yifan Hong10fe0b52016-10-19 14:20:17 -07001523 for (const auto &tuple : iface->allMethodsFromRoot()) {
1524 const Method *method = tuple.method();
1525 const Interface *superInterface = tuple.interface();
1526 out << "case "
1527 << method->getSerialId()
1528 << " /* "
1529 << method->name()
1530 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001531
Yifan Hong10fe0b52016-10-19 14:20:17 -07001532 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001533
Yifan Hong10fe0b52016-10-19 14:20:17 -07001534 status_t err =
1535 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001536
Yifan Hong10fe0b52016-10-19 14:20:17 -07001537 if (err != OK) {
1538 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001539 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001540
1541 out.unindent();
1542 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001543 }
1544
1545 out << "default:\n{\n";
1546 out.indent();
1547
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001548 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001549
1550 out.indent();
1551 out.indent();
1552
Iliyan Malchev549e2592016-08-10 08:59:12 -07001553 out << "_hidl_code, _hidl_data, _hidl_reply, "
1554 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001555
1556 out.unindent();
1557 out.unindent();
1558
1559 out.unindent();
1560 out << "}\n";
1561
1562 out.unindent();
1563 out << "}\n\n";
1564
Yifan Honga018ed52016-12-13 16:35:08 -08001565 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1566 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1567 out.indent(2, [&] {
1568 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1569 out << "_hidl_reply);\n";
1570 });
1571 });
Andreas Huber881227d2016-08-02 14:20:21 -07001572
Iliyan Malchev549e2592016-08-10 08:59:12 -07001573 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001574
1575 out.unindent();
1576 out << "}\n\n";
1577
1578 return OK;
1579}
1580
1581status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001582 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001583 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1584 method->cppImpl(IMPL_STUB, out);
1585 out << "break;\n";
1586 return OK;
1587 }
1588
Yifan Hongeefe4f22017-01-04 15:32:42 -08001589 out << "if (!_hidl_data.enforceInterface("
1590 << iface->fullName()
1591 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001592
Andreas Huber881227d2016-08-02 14:20:21 -07001593 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001594 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001595 out << "break;\n";
1596 out.unindent();
1597 out << "}\n\n";
1598
Andreas Huber5e44a292016-09-27 14:52:39 -07001599 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001600
Yifan Hongbf459bc2016-08-23 16:50:37 -07001601 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001602 for (const auto &arg : method->args()) {
1603 emitCppReaderWriter(
1604 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001605 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001606 false /* parcelObjIsPointer */,
1607 arg,
1608 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001609 Type::ErrorMode_Break,
1610 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001611 }
1612
Yifan Hongbf459bc2016-08-23 16:50:37 -07001613 // Second DFS: resolve references
1614 for (const auto &arg : method->args()) {
1615 emitCppResolveReferences(
1616 out,
1617 "_hidl_data",
1618 false /* parcelObjIsPointer */,
1619 arg,
1620 true /* reader */,
1621 Type::ErrorMode_Break,
1622 false /* addPrefixToName */);
1623 }
1624
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001625 status_t status = generateCppInstrumentationCall(
1626 out,
1627 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001628 method);
1629 if (status != OK) {
1630 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001631 }
1632
Andreas Huber881227d2016-08-02 14:20:21 -07001633 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001634 const TypedVar *elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -08001635 const std::string callee =
1636 (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL))
1637 ? "this" : "_hidl_mImpl";
Andreas Huber881227d2016-08-02 14:20:21 -07001638
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001639 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001640 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001641 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001642 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001643 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001644 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001645 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001646
Yifan Hong7d234ea2017-03-30 15:40:22 -07001647 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001648 if (arg->type().resultNeedsDeref()) {
1649 out << "*";
1650 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001651 out << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001652 });
Andreas Huber881227d2016-08-02 14:20:21 -07001653
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001654 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001655 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1656 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001657
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001658 elidedReturn->type().emitReaderWriter(
1659 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001660 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001661 "_hidl_reply",
1662 true, /* parcelObjIsPointer */
1663 false, /* isReader */
1664 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001665
Yifan Hongbf459bc2016-08-23 16:50:37 -07001666 emitCppResolveReferences(
1667 out,
1668 "_hidl_reply",
1669 true /* parcelObjIsPointer */,
1670 elidedReturn,
1671 false /* reader */,
1672 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001673 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001674
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001675 status_t status = generateCppInstrumentationCall(
1676 out,
1677 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001678 method);
1679 if (status != OK) {
1680 return status;
1681 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001682
Iliyan Malchev549e2592016-08-10 08:59:12 -07001683 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001684 } else {
1685 if (returnsValue) {
1686 out << "bool _hidl_callbackCalled = false;\n\n";
1687 }
Andreas Huber881227d2016-08-02 14:20:21 -07001688
Yifan Hongcd2ae452017-01-31 14:33:40 -08001689 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001690
Yifan Hong7d234ea2017-03-30 15:40:22 -07001691 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001692 if (arg->type().resultNeedsDeref()) {
1693 out << "*";
1694 }
1695
1696 out << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001697 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001698
1699 if (returnsValue) {
Yifan Hong7d234ea2017-03-30 15:40:22 -07001700 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001701 out << ", ";
1702 }
1703
1704 out << "[&](";
1705
Yifan Hong7d234ea2017-03-30 15:40:22 -07001706 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001707 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001708 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001709
1710 out << ") {\n";
1711 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001712 out << "if (_hidl_callbackCalled) {\n";
1713 out.indent();
1714 out << "LOG_ALWAYS_FATAL(\""
1715 << method->name()
1716 << ": _hidl_cb called a second time, but must be called once.\");\n";
1717 out.unindent();
1718 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001719 out << "_hidl_callbackCalled = true;\n\n";
1720
Yifan Hong859e53f2016-11-14 19:08:24 -08001721 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1722 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001723
Yifan Hongbf459bc2016-08-23 16:50:37 -07001724 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001725 for (const auto &arg : method->results()) {
1726 emitCppReaderWriter(
1727 out,
1728 "_hidl_reply",
1729 true /* parcelObjIsPointer */,
1730 arg,
1731 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001732 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001733 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001734 }
1735
Yifan Hongbf459bc2016-08-23 16:50:37 -07001736 // Second DFS: resolve references
1737 for (const auto &arg : method->results()) {
1738 emitCppResolveReferences(
1739 out,
1740 "_hidl_reply",
1741 true /* parcelObjIsPointer */,
1742 arg,
1743 false /* reader */,
1744 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001745 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001746 }
1747
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001748 status_t status = generateCppInstrumentationCall(
1749 out,
1750 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001751 method);
1752 if (status != OK) {
1753 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001754 }
1755
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001756 out << "_hidl_cb(*_hidl_reply);\n";
1757
1758 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001759 out << "});\n\n";
1760 } else {
1761 out << ");\n\n";
1762 status_t status = generateCppInstrumentationCall(
1763 out,
1764 InstrumentationEvent::SERVER_API_EXIT,
1765 method);
1766 if (status != OK) {
1767 return status;
1768 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001769 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001770
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001771 if (returnsValue) {
1772 out << "if (!_hidl_callbackCalled) {\n";
1773 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001774 out << "LOG_ALWAYS_FATAL(\""
1775 << method->name()
1776 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001777 out.unindent();
1778 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001779 } else {
1780 out << "::android::hardware::writeToParcel("
1781 << "::android::hardware::Status::ok(), "
1782 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001783 }
Andreas Huber881227d2016-08-02 14:20:21 -07001784 }
1785
1786 out << "break;\n";
1787
1788 return OK;
1789}
1790
Steven Moreland69e7c702016-09-09 11:16:32 -07001791status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1792 std::string ifaceName;
1793 if (!AST::isInterface(&ifaceName)) {
1794 // types.hal does not get a stub header.
1795 return OK;
1796 }
1797
1798 const Interface *iface = mRootScope->getInterface();
1799
Yifan Hongeefe4f22017-01-04 15:32:42 -08001800 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001801
1802 bool supportOneway = iface->hasOnewayMethods();
1803
1804 std::string path = outputPath;
1805 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1806 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1807 path.append(klassName);
1808 path.append(".h");
1809
1810 CHECK(Coordinator::MakeParentHierarchy(path));
1811 FILE *file = fopen(path.c_str(), "w");
1812
1813 if (file == NULL) {
1814 return -errno;
1815 }
1816
1817 Formatter out(file);
1818
1819 const std::string guard = makeHeaderGuard(klassName);
1820
1821 out << "#ifndef " << guard << "\n";
1822 out << "#define " << guard << "\n\n";
1823
1824 std::vector<std::string> packageComponents;
1825 getPackageAndVersionComponents(
1826 &packageComponents, false /* cpp_compatible */);
1827
Yifan Hongb0949432016-12-15 15:32:24 -08001828 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001829 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001830
1831 generateCppPackageInclude(out, mPackage, ifaceName);
1832 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001833
Yifan Hong7a118f52016-12-07 11:21:15 -08001834 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001835 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001836 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001837 }
1838
1839 enterLeaveNamespace(out, true /* enter */);
1840 out << "\n";
1841
1842 out << "struct "
1843 << klassName
1844 << " : " << ifaceName
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001845 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001846
1847 out.indent();
1848 out << "explicit "
1849 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001850 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001851 << ifaceName
1852 << "> impl);\n";
1853
Yifan Hong068c5522016-10-31 14:07:25 -07001854 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1855 return generatePassthroughMethod(out, method);
1856 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001857
1858 if (err != OK) {
1859 return err;
1860 }
1861
1862 out.unindent();
1863 out << "private:\n";
1864 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001865 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001866
1867 if (supportOneway) {
Yifan Hongef91d362017-03-20 17:18:13 -07001868 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001869
1870 out << "\n";
1871
1872 out << "::android::hardware::Return<void> addOnewayTask("
1873 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001874 }
1875
1876 out.unindent();
1877
1878 out << "};\n\n";
1879
1880 enterLeaveNamespace(out, false /* enter */);
1881
1882 out << "\n#endif // " << guard << "\n";
1883
1884 return OK;
1885}
1886
Yifan Hongfe95aa22016-10-19 17:26:45 -07001887status_t AST::generateInterfaceSource(Formatter &out) const {
1888 const Interface *iface = mRootScope->getInterface();
1889
Yifan Hong2d7126b2016-10-20 15:12:57 -07001890 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001891 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001892
Steven Morelandd4b068a2017-03-20 06:30:51 -07001893 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1894 bool reserved = method->isHidlReserved();
1895
1896 if (!reserved) {
1897 out << "// no default implementation for: ";
1898 }
1899 method->generateCppSignature(out, iface->localName());
1900 if (reserved) {
1901 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001902 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001903 }).endl();
1904 }
1905
1906 out << "\n";
1907
1908 return OK;
1909 });
1910 if (err != OK) {
1911 return err;
1912 }
1913
Yifan Hong3d746092016-12-07 14:26:33 -08001914 for (const Interface *superType : iface->typeChain()) {
Yifan Hong7783bb02017-03-29 03:39:09 -07001915 out << "// static \n::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -08001916 << childTypeResult
Yifan Hong7783bb02017-03-29 03:39:09 -07001917 << "> "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001918 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001919 << "::castFrom("
1920 << superType->getCppArgumentType()
Yifan Hong7783bb02017-03-29 03:39:09 -07001921 << " parent, bool "
1922 << (iface == superType ? "/* emitError */" : "emitError")
1923 << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001924 out.indent();
1925 if (iface == superType) {
1926 out << "return parent;\n";
1927 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001928 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001929 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001930 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001931 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001932 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001933 << ">(\n";
1934 out.indent();
1935 out.indent();
1936 out << "parent, \""
1937 << iface->fqName().string()
Yifan Hong7783bb02017-03-29 03:39:09 -07001938 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001939 out.unindent();
1940 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001941 }
Yifan Hong3d746092016-12-07 14:26:33 -08001942 out.unindent();
1943 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001944 }
1945
1946 return OK;
1947}
1948
Steven Moreland69e7c702016-09-09 11:16:32 -07001949status_t AST::generatePassthroughSource(Formatter &out) const {
1950 const Interface *iface = mRootScope->getInterface();
1951
Yifan Hongeefe4f22017-01-04 15:32:42 -08001952 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001953
1954 out << klassName
1955 << "::"
1956 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001957 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001958 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001959 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001960 << mPackage.string()
1961 << "\", \""
1962 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001963 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001964 if (iface->hasOnewayMethods()) {
1965 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001966 out.indent([&] {
Yifan Hongf01dad42017-03-20 19:03:11 -07001967 out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001968 });
1969 }
1970 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001971
1972 if (iface->hasOnewayMethods()) {
1973 out << "::android::hardware::Return<void> "
1974 << klassName
1975 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1976 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001977 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001978 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001979 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1980 out.indent();
1981 out.indent();
1982 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1983 out.unindent();
1984 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001985 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001986 out << "}\n";
1987
Steven Morelandd366c262016-10-11 15:29:10 -07001988 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001989
1990 out.unindent();
1991 out << "}\n\n";
1992
1993
1994 }
1995
1996 return OK;
1997}
1998
Martijn Coenen7b295242016-11-04 16:52:56 +01001999status_t AST::generateCppAtraceCall(Formatter &out,
2000 InstrumentationEvent event,
2001 const Method *method) const {
2002 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08002003 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01002004 switch (event) {
2005 case SERVER_API_ENTRY:
2006 {
2007 out << "atrace_begin(ATRACE_TAG_HAL, \""
2008 << baseString + "::server\");\n";
2009 break;
2010 }
2011 case CLIENT_API_ENTRY:
2012 {
2013 out << "atrace_begin(ATRACE_TAG_HAL, \""
2014 << baseString + "::client\");\n";
2015 break;
2016 }
2017 case PASSTHROUGH_ENTRY:
2018 {
2019 out << "atrace_begin(ATRACE_TAG_HAL, \""
2020 << baseString + "::passthrough\");\n";
2021 break;
2022 }
2023 case SERVER_API_EXIT:
2024 case CLIENT_API_EXIT:
2025 case PASSTHROUGH_EXIT:
2026 {
2027 out << "atrace_end(ATRACE_TAG_HAL);\n";
2028 break;
2029 }
2030 default:
2031 {
2032 LOG(ERROR) << "Unsupported instrumentation event: " << event;
2033 return UNKNOWN_ERROR;
2034 }
2035 }
2036
2037 return OK;
2038}
2039
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002040status_t AST::generateCppInstrumentationCall(
2041 Formatter &out,
2042 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07002043 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01002044 status_t err = generateCppAtraceCall(out, event, method);
2045 if (err != OK) {
2046 return err;
2047 }
2048
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002049 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
2050 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002051 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002052 std::string event_str = "";
2053 switch (event) {
2054 case SERVER_API_ENTRY:
2055 {
2056 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
2057 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002058 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002059 << (arg->type().resultNeedsDeref() ? "" : "&")
2060 << arg->name()
2061 << ");\n";
2062 }
2063 break;
2064 }
2065 case SERVER_API_EXIT:
2066 {
2067 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07002068 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002069 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07002070 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002071 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002072 }
2073 break;
2074 }
2075 case CLIENT_API_ENTRY:
2076 {
2077 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2078 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002079 out << "_hidl_args.push_back((void *)&"
2080 << arg->name()
2081 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002082 }
2083 break;
2084 }
2085 case CLIENT_API_EXIT:
2086 {
2087 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2088 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002089 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002090 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002091 << "_hidl_out_"
2092 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002093 << ");\n";
2094 }
2095 break;
2096 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002097 case PASSTHROUGH_ENTRY:
2098 {
2099 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2100 for (const auto &arg : method->args()) {
2101 out << "_hidl_args.push_back((void *)&"
2102 << arg->name()
2103 << ");\n";
2104 }
2105 break;
2106 }
2107 case PASSTHROUGH_EXIT:
2108 {
2109 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002110 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002111 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002112 << arg->name()
2113 << ");\n";
2114 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002115 break;
2116 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002117 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002118 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002119 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002120 return UNKNOWN_ERROR;
2121 }
2122 }
2123
Steven Moreland031ccf12016-10-31 15:54:38 -07002124 const Interface *iface = mRootScope->getInterface();
2125
Steven Moreland1ab31442016-11-03 18:37:51 -07002126 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002127 out.indent();
2128 out << "callback("
2129 << event_str
2130 << ", \""
2131 << mPackage.package()
2132 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002133 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002134 << "\", \""
2135 << iface->localName()
2136 << "\", \""
2137 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002138 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002139 out.unindent();
2140 out << "}\n";
2141 out.unindent();
2142 out << "}\n\n";
2143
2144 return OK;
2145}
2146
Andreas Huber881227d2016-08-02 14:20:21 -07002147} // namespace android