blob: d730f0c391d6da681e8628b55dfc5723187459c8 [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([&] {
Steven Morelanda9582e62017-04-09 10:54:50 -0700325 out << "::android::hardware::details::onRegistration(\""
326 << fqName.getPackageAndVersion().string() << "\", \""
327 << interfaceName
328 << "\", serviceName);\n\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800329 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
330 out.indent(2, [&] {
331 out << "= ::android::hardware::defaultServiceManager();\n";
332 });
333 out.sIf("sm == nullptr", [&] {
334 out << "return ::android::INVALID_OPERATION;\n";
335 }).endl();
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100336 out << "::android::hardware::Return<bool> ret = "
337 << "sm->add(serviceName.c_str(), this);\n"
338 << "return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800339 }).endl().endl();
340
Yifan Hongeefe4f22017-01-04 15:32:42 -0800341 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800342 out.indent(2, [&] {
343 out << "const std::string &serviceName,\n"
344 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
345 << "&notification) ";
346 });
347 out.block([&] {
348 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
349 out.indent(2, [&] {
350 out << "= ::android::hardware::defaultServiceManager();\n";
351 });
352 out.sIf("sm == nullptr", [&] {
353 out << "return false;\n";
354 }).endl();
355 out << "::android::hardware::Return<bool> success =\n";
356 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800357 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800358 out.indent(2, [&] {
359 out << "serviceName, notification);\n";
360 });
361 });
362 out << "return success.isOk() && success;\n";
363 }).endl().endl();
364}
365
Andreas Huberb82318c2016-08-02 14:45:54 -0700366status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700367
Andreas Huberb82318c2016-08-02 14:45:54 -0700368 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700369 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700370 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700371
372 std::string ifaceName;
373 bool isInterface = true;
374 if (!AST::isInterface(&ifaceName)) {
375 ifaceName = "types";
376 isInterface = false;
377 }
378 path.append(ifaceName);
379 path.append(".h");
380
Andreas Huberd2943e12016-08-05 11:59:31 -0700381 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700382 FILE *file = fopen(path.c_str(), "w");
383
384 if (file == NULL) {
385 return -errno;
386 }
387
388 Formatter out(file);
389
390 const std::string guard = makeHeaderGuard(ifaceName);
391
392 out << "#ifndef " << guard << "\n";
393 out << "#define " << guard << "\n\n";
394
Andreas Huber737080b2016-08-02 15:38:04 -0700395 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700396 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700397 }
398
399 if (!mImportedNames.empty()) {
400 out << "\n";
401 }
402
Steven Moreland0693f312016-11-09 15:06:14 -0800403 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800404 if (isIBase()) {
405 out << "// skipped #include IServiceNotification.h\n\n";
406 } else {
407 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
408 }
Steven Moreland0693f312016-11-09 15:06:14 -0800409 }
410
Yifan Hongc8934042016-11-17 17:10:52 -0800411 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700412 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700413
414 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200415 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700416 }
417
Martijn Coenenaf712c02016-11-16 15:26:27 +0100418 out << "#include <utils/NativeHandle.h>\n";
419 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700420
421 enterLeaveNamespace(out, true /* enter */);
422 out << "\n";
423
424 if (isInterface) {
425 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700426 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700427
428 const Interface *iface = mRootScope->getInterface();
429 const Interface *superType = iface->superType();
430
Steven Moreland40786312016-08-16 10:29:40 -0700431 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800432 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700433 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000434 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700435 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700436 }
437
438 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700439
440 out.indent();
441
Andreas Huber881227d2016-08-02 14:20:21 -0700442 }
443
444 status_t err = emitTypeDeclarations(out);
445
446 if (err != OK) {
447 return err;
448 }
449
450 if (isInterface) {
451 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800452
Yifan Hongc8934042016-11-17 17:10:52 -0800453 out << "virtual bool isRemote() const ";
454 if (!isIBase()) {
455 out << "override ";
456 }
457 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800458
Andreas Huber881227d2016-08-02 14:20:21 -0700459 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700460 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700461
Andreas Huber881227d2016-08-02 14:20:21 -0700462 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800463 const TypedVar *elidedReturn = method->canElideCallback();
464
465 if (elidedReturn == nullptr && returnsValue) {
466 out << "using "
467 << method->name()
Yifan Hong7d234ea2017-03-30 15:40:22 -0700468 << "_cb = std::function<void(";
469 method->emitCppResultSignature(out, true /* specify namespaces */);
470 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800471 }
Andreas Huber881227d2016-08-02 14:20:21 -0700472
Andreas Huber3599d922016-08-09 10:42:57 -0700473 method->dumpAnnotations(out);
474
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700475 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700476 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700477 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700478 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700479 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700480 }
481
482 out << method->name()
Yifan Hong7d234ea2017-03-30 15:40:22 -0700483 << "(";
484 method->emitCppArgSignature(out, true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700485
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700486 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700487 if (!method->args().empty()) {
488 out << ", ";
489 }
490
Steven Moreland67f67b42016-09-29 08:59:02 -0700491 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700492 }
493
Yifan Hong10fe0b52016-10-19 14:20:17 -0700494 out << ")";
495 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800496 if (!isIBase()) {
497 out << " override";
498 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700499 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700500 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700501 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700502 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700503 }
Steven Moreland40786312016-08-16 10:29:40 -0700504
Yifan Hong3d746092016-12-07 14:26:33 -0800505 out << "// cast static functions\n";
506 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700507
Yifan Hong3d746092016-12-07 14:26:33 -0800508 for (const Interface *superType : iface->typeChain()) {
Yifan Hong7783bb02017-03-29 03:39:09 -0700509 out << "static ::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -0800510 << childTypeResult
Yifan Hong7783bb02017-03-29 03:39:09 -0700511 << "> castFrom("
Yifan Hong3d746092016-12-07 14:26:33 -0800512 << superType->getCppArgumentType()
513 << " parent"
Yifan Hong7783bb02017-03-29 03:39:09 -0700514 << ", bool emitError = false);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700515 }
516
Steven Morelandd39133b2016-11-11 12:30:08 -0800517 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700518
Yifan Hongc8934042016-11-17 17:10:52 -0800519 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800520 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800521 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800522 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800523 }
Andreas Huber881227d2016-08-02 14:20:21 -0700524 }
525
526 if (isInterface) {
527 out.unindent();
528
Andreas Hubere3f769a2016-10-10 10:54:44 -0700529 out << "};\n\n";
530 }
531
532 err = mRootScope->emitGlobalTypeDeclarations(out);
533
534 if (err != OK) {
535 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700536 }
537
538 out << "\n";
539 enterLeaveNamespace(out, false /* enter */);
540
541 out << "\n#endif // " << guard << "\n";
542
543 return OK;
544}
545
Steven Moreland40786312016-08-16 10:29:40 -0700546status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
547 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800548 bool isInterface = AST::isInterface(&ifaceName);
549 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800550 std::string klassName{};
551
552 if(isInterface) {
553 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800554 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800555 } else {
556 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700557 }
558
Steven Moreland40786312016-08-16 10:29:40 -0700559 std::string path = outputPath;
560 path.append(mCoordinator->convertPackageRootToPath(mPackage));
561 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
562 path.append(klassName + ".h");
563
Yifan Hong244e82d2016-11-11 11:13:57 -0800564 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700565
566 if (file == NULL) {
567 return -errno;
568 }
569
570 Formatter out(file);
571
572 const std::string guard = makeHeaderGuard(klassName);
573
574 out << "#ifndef " << guard << "\n";
575 out << "#define " << guard << "\n\n";
576
Yifan Hong244e82d2016-11-11 11:13:57 -0800577 if (isInterface) {
578 generateCppPackageInclude(out, mPackage, ifaceName);
579 } else {
580 generateCppPackageInclude(out, mPackage, "types");
581 }
Steven Moreland40786312016-08-16 10:29:40 -0700582
Steven Morelandee88eed2016-10-31 17:49:00 -0700583 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700584
585 for (const auto &item : mImportedNames) {
586 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800587 generateCppPackageInclude(out, item, "hwtypes");
588 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800589 generateCppPackageInclude(out, item, item.getInterfaceStubName());
590 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700591 }
Steven Moreland40786312016-08-16 10:29:40 -0700592 }
593
594 out << "\n";
595
Martijn Coenen93915102016-09-01 01:35:52 +0200596 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700597 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100598 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700599
600 out << "\n";
601
602 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700603
Yifan Hong244e82d2016-11-11 11:13:57 -0800604 status_t err = mRootScope->emitGlobalHwDeclarations(out);
605 if (err != OK) {
606 return err;
607 }
Steven Moreland40786312016-08-16 10:29:40 -0700608
609 enterLeaveNamespace(out, false /* enter */);
610
611 out << "\n#endif // " << guard << "\n";
612
613 return OK;
614}
615
Andreas Huber881227d2016-08-02 14:20:21 -0700616status_t AST::emitTypeDeclarations(Formatter &out) const {
617 return mRootScope->emitTypeDeclarations(out);
618}
619
Yifan Hong7a118f52016-12-07 11:21:15 -0800620static void wrapPassthroughArg(Formatter &out,
621 const TypedVar *arg, bool addPrefixToName,
622 std::function<void(void)> handleError) {
623 if (!arg->type().isInterface()) {
624 return;
625 }
626 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
627 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
628 + arg->name();
629 const Interface &iface = static_cast<const Interface &>(arg->type());
630 out << iface.getCppStackType() << " " << wrappedName << ";\n";
631 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
632 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
633 out << wrappedName
634 << " = "
635 << iface.fqName().cppName()
Yifan Hong052425a2017-03-13 17:06:13 -0700636 << "::castFrom(::android::hardware::details::wrapPassthrough("
Yifan Hong7a118f52016-12-07 11:21:15 -0800637 << name << "));\n";
638 out.sIf(wrappedName + " == nullptr", [&] {
639 // Fatal error. Happens when the BsFoo class is not found in the binary
640 // or any dynamic libraries.
641 handleError();
642 }).endl();
643 }).sElse([&] {
644 out << wrappedName << " = " << name << ";\n";
645 }).endl().endl();
646}
647
Steven Moreland69e7c702016-09-09 11:16:32 -0700648status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700649 const Method *method) const {
650 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700651
652 out << " {\n";
653 out.indent();
654
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800655 if (method->isHidlReserved()
656 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
657 method->cppImpl(IMPL_PASSTHROUGH, out);
658 out.unindent();
659 out << "}\n\n";
660 return OK;
661 }
662
Steven Moreland69e7c702016-09-09 11:16:32 -0700663 const bool returnsValue = !method->results().empty();
664 const TypedVar *elidedReturn = method->canElideCallback();
665
Steven Moreland67f67b42016-09-29 08:59:02 -0700666 if (returnsValue && elidedReturn == nullptr) {
667 generateCheckNonNull(out, "_hidl_cb");
668 }
669
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700670 generateCppInstrumentationCall(
671 out,
672 InstrumentationEvent::PASSTHROUGH_ENTRY,
673 method);
674
Yifan Hong7a118f52016-12-07 11:21:15 -0800675
676 for (const auto &arg : method->args()) {
677 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
678 out << "return ::android::hardware::Status::fromExceptionCode(\n";
679 out.indent(2, [&] {
680 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800681 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800682 });
683 });
684 }
685
686 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700687 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700688
689 if (method->isOneway()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800690 out << "addOnewayTask([this, &_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700691 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800692 out << ", "
693 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
694 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700695 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700696 out << "] {\n";
697 out.indent();
698 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700699 }
700
701 out << "mImpl->"
702 << method->name()
703 << "(";
704
Yifan Hong7d234ea2017-03-30 15:40:22 -0700705 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800706 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700707 });
Steven Moreland69e7c702016-09-09 11:16:32 -0700708 if (returnsValue && elidedReturn == nullptr) {
709 if (!method->args().empty()) {
710 out << ", ";
711 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800712 out << "[&](";
Yifan Hong7d234ea2017-03-30 15:40:22 -0700713 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800714 out << "const auto &_hidl_out_"
715 << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700716 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800717
718 out << ") {\n";
719 out.indent();
720 status_t status = generateCppInstrumentationCall(
721 out,
722 InstrumentationEvent::PASSTHROUGH_EXIT,
723 method);
724 if (status != OK) {
725 return status;
726 }
727
Yifan Hong7a118f52016-12-07 11:21:15 -0800728 for (const auto &arg : method->results()) {
729 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
730 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
731 out.indent(2, [&] {
732 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800733 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800734 });
735 out << "return;\n";
736 });
737 }
738
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800739 out << "_hidl_cb(";
Yifan Hong7d234ea2017-03-30 15:40:22 -0700740 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800741 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
742 << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700743 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800744 out << ");\n";
745 out.unindent();
746 out << "});\n\n";
747 } else {
748 out << ");\n\n";
749 if (elidedReturn != nullptr) {
750 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800751 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800752 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000753 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800754 }
755 status_t status = generateCppInstrumentationCall(
756 out,
757 InstrumentationEvent::PASSTHROUGH_EXIT,
758 method);
759 if (status != OK) {
760 return status;
761 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700762 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700763
764 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700765 out.unindent();
766 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700767 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700768
769 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700770
771 out.unindent();
772 out << "}\n";
773
774 return OK;
775}
776
Yifan Hong068c5522016-10-31 14:07:25 -0700777status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700778
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700779 const Interface *iface = mRootScope->getInterface();
780
Yifan Hong10fe0b52016-10-19 14:20:17 -0700781 const Interface *prevIterface = nullptr;
782 for (const auto &tuple : iface->allMethodsFromRoot()) {
783 const Method *method = tuple.method();
784 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700785
Yifan Hong10fe0b52016-10-19 14:20:17 -0700786 if(prevIterface != superInterface) {
787 if (prevIterface != nullptr) {
788 out << "\n";
789 }
790 out << "// Methods from "
791 << superInterface->fullName()
792 << " follow.\n";
793 prevIterface = superInterface;
794 }
Yifan Hong068c5522016-10-31 14:07:25 -0700795 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700796
Yifan Hong10fe0b52016-10-19 14:20:17 -0700797 if (err != OK) {
798 return err;
799 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700800 }
801
Yifan Hong10fe0b52016-10-19 14:20:17 -0700802 out << "\n";
803
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700804 return OK;
805}
806
Andreas Huberb82318c2016-08-02 14:45:54 -0700807status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700808 std::string ifaceName;
809 if (!AST::isInterface(&ifaceName)) {
810 // types.hal does not get a stub header.
811 return OK;
812 }
813
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700814 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800815 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700816
Andreas Huberb82318c2016-08-02 14:45:54 -0700817 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700818 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700819 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700820 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700821 path.append(".h");
822
Andreas Huberd2943e12016-08-05 11:59:31 -0700823 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700824 FILE *file = fopen(path.c_str(), "w");
825
826 if (file == NULL) {
827 return -errno;
828 }
829
830 Formatter out(file);
831
Steven Moreland40786312016-08-16 10:29:40 -0700832 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700833
834 out << "#ifndef " << guard << "\n";
835 out << "#define " << guard << "\n\n";
836
Yifan Hongeefe4f22017-01-04 15:32:42 -0800837 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700838 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700839
840 enterLeaveNamespace(out, true /* enter */);
841 out << "\n";
842
843 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800844 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100845 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800846 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000847 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100848 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800849 out << " : public "
850 << gIBaseFqName.getInterfaceStubFqName().cppName()
851 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100852 }
Andreas Huber881227d2016-08-02 14:20:21 -0700853
854 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800855 out << "explicit "
856 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700857 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100858 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800859 out << "explicit "
860 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100861 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800862 << " const std::string& HidlInstrumentor_package,"
863 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700864 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700865 out << "::android::status_t onTransact(\n";
866 out.indent();
867 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700868 out << "uint32_t _hidl_code,\n";
869 out << "const ::android::hardware::Parcel &_hidl_data,\n";
870 out << "::android::hardware::Parcel *_hidl_reply,\n";
871 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700872 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700873 out.unindent();
874 out.unindent();
875
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100876 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
877 out.unindent();
878 out << "private:\n";
879 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800880
881 status_t err = generateMethods(out, [&](const Method *method, const Interface *iface) {
882 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
883 return OK;
884 }
885 const bool returnsValue = !method->results().empty();
886 const TypedVar *elidedReturn = method->canElideCallback();
887
888 if (elidedReturn == nullptr && returnsValue) {
889 out << "using " << method->name() << "_cb = "
890 << iface->fqName().cppName()
891 << "::" << method->name() << "_cb;\n";
892 }
893 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800894 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800895 return OK;
896 });
897 if (err != OK) {
898 return err;
899 }
900
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100901 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700902 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700903 out << "};\n\n";
904
905 enterLeaveNamespace(out, false /* enter */);
906
907 out << "\n#endif // " << guard << "\n";
908
909 return OK;
910}
911
Andreas Huberb82318c2016-08-02 14:45:54 -0700912status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700913 std::string ifaceName;
914 if (!AST::isInterface(&ifaceName)) {
915 // types.hal does not get a proxy header.
916 return OK;
917 }
918
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700919 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800920 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700921
Andreas Huberb82318c2016-08-02 14:45:54 -0700922 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700923 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700924 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800925 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700926 path.append(".h");
927
Andreas Huberd2943e12016-08-05 11:59:31 -0700928 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700929 FILE *file = fopen(path.c_str(), "w");
930
931 if (file == NULL) {
932 return -errno;
933 }
934
935 Formatter out(file);
936
Yifan Hongeefe4f22017-01-04 15:32:42 -0800937 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700938
939 out << "#ifndef " << guard << "\n";
940 out << "#define " << guard << "\n\n";
941
Martijn Coenen115d4282016-12-19 05:14:04 +0100942 out << "#include <hidl/HidlTransportSupport.h>\n\n";
943
Andreas Huber881227d2016-08-02 14:20:21 -0700944 std::vector<std::string> packageComponents;
945 getPackageAndVersionComponents(
946 &packageComponents, false /* cpp_compatible */);
947
Yifan Hongeefe4f22017-01-04 15:32:42 -0800948 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700949 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700950
951 enterLeaveNamespace(out, true /* enter */);
952 out << "\n";
953
954 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800955 << proxyName
956 << " : public ::android::hardware::BpInterface<"
957 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000958 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700959
960 out.indent();
961
Yifan Hongeefe4f22017-01-04 15:32:42 -0800962 out << "explicit "
963 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700964 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700965 << "\n\n";
966
Yifan Hong10fe0b52016-10-19 14:20:17 -0700967 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700968
Yifan Hong068c5522016-10-31 14:07:25 -0700969 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
970 method->generateCppSignature(out);
971 out << " override;\n";
972 return OK;
973 });
Steven Moreland9c387612016-09-07 09:54:26 -0700974
975 if (err != OK) {
976 return err;
977 }
Andreas Huber881227d2016-08-02 14:20:21 -0700978
979 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100980 out << "private:\n";
981 out.indent();
982 out << "std::mutex _hidl_mMutex;\n"
983 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
984 << " _hidl_mDeathRecipients;\n";
985 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700986 out << "};\n\n";
987
988 enterLeaveNamespace(out, false /* enter */);
989
990 out << "\n#endif // " << guard << "\n";
991
992 return OK;
993}
994
Andreas Huberb82318c2016-08-02 14:45:54 -0700995status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700996
Andreas Huberb82318c2016-08-02 14:45:54 -0700997 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700998 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700999 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -07001000
1001 std::string ifaceName;
1002 std::string baseName;
1003
Yifan Hongfe95aa22016-10-19 17:26:45 -07001004 const Interface *iface = nullptr;
1005 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -07001006 if (!AST::isInterface(&ifaceName)) {
1007 baseName = "types";
1008 isInterface = false;
1009 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001010 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -07001011 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001012 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -07001013 }
1014
1015 path.append(baseName);
1016
1017 if (baseName != "types") {
1018 path.append("All");
1019 }
1020
1021 path.append(".cpp");
1022
Andreas Huberd2943e12016-08-05 11:59:31 -07001023 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -07001024 FILE *file = fopen(path.c_str(), "w");
1025
1026 if (file == NULL) {
1027 return -errno;
1028 }
1029
1030 Formatter out(file);
1031
Steven Moreland623c0042017-01-13 14:42:29 -08001032 out << "#define LOG_TAG \""
1033 << mPackage.string() << "::" << baseName
1034 << "\"\n\n";
1035
Steven Moreland05cd4232016-11-21 16:01:12 -08001036 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001037 out << "#include <cutils/trace.h>\n";
1038 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001039 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -07001040 // This is a no-op for IServiceManager itself.
1041 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
1042
Steven Morelandbec74ed2017-01-25 17:42:35 -08001043 // TODO(b/34274385) remove this
1044 out << "#include <hidl/LegacySupport.h>\n";
1045
Yifan Hongeefe4f22017-01-04 15:32:42 -08001046 generateCppPackageInclude(out, mPackage, iface->getProxyName());
1047 generateCppPackageInclude(out, mPackage, iface->getStubName());
1048 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001049
1050 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -07001051 generateCppPackageInclude(out,
1052 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -08001053 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001054 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -08001055
1056 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001057 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -07001058 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -08001059 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -07001060 }
1061
1062 out << "\n";
1063
1064 enterLeaveNamespace(out, true /* enter */);
1065 out << "\n";
1066
1067 status_t err = generateTypeSource(out, ifaceName);
1068
1069 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001070 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001071
1072 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -08001073 out << "const char* "
1074 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -07001075 << "::descriptor(\""
1076 << iface->fqName().string()
1077 << "\");\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +01001078 out << "__attribute__((constructor))";
1079 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001080 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001081 out << "::android::hardware::details::gBnConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001082 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001083 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001084 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001085 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001086 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001087 out << "return new "
1088 << iface->getStubName()
1089 << "(reinterpret_cast<"
1090 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001091 << " *>(iIntf));\n";
1092 });
Yifan Hongb04de382017-02-06 15:31:52 -08001093 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001094 });
Yifan Honga159f3b2017-03-16 14:53:51 -07001095 out << "::android::hardware::details::gBsConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001096 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001097 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001098 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001099 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -08001100 << gIBaseFqName.cppName()
1101 << "> {\n";
1102 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001103 out << "return new "
1104 << iface->getPassthroughName()
1105 << "(reinterpret_cast<"
1106 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001107 << " *>(iIntf));\n";
1108 });
Yifan Hongb04de382017-02-06 15:31:52 -08001109 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001110 });
Yifan Hong158655a2016-11-08 12:34:07 -08001111 });
Martijn Coenen8adcb652017-02-03 17:37:36 +01001112 out << "};\n\n";
1113 out << "__attribute__((destructor))";
1114 out << "static void static_destructor() {\n";
1115 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001116 out << "::android::hardware::details::gBnConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001117 << iface->localName()
1118 << "::descriptor);\n";
Yifan Honga159f3b2017-03-16 14:53:51 -07001119 out << "::android::hardware::details::gBsConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001120 << iface->localName()
1121 << "::descriptor);\n";
1122 });
1123 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001124
Yifan Hongfe95aa22016-10-19 17:26:45 -07001125 err = generateInterfaceSource(out);
1126 }
1127
1128 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001129 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001130 }
1131
1132 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001133 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001134 }
1135
Steven Moreland40786312016-08-16 10:29:40 -07001136 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001137 err = generatePassthroughSource(out);
1138 }
1139
1140 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001141 const Interface *iface = mRootScope->getInterface();
1142
Yifan Hongc8934042016-11-17 17:10:52 -08001143 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001144 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001145 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001146 std::string package = iface->fqName().package()
1147 + iface->fqName().atVersion();
1148
Yifan Hongeefe4f22017-01-04 15:32:42 -08001149 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001150 }
Steven Moreland40786312016-08-16 10:29:40 -07001151 }
1152
Andreas Huber881227d2016-08-02 14:20:21 -07001153 enterLeaveNamespace(out, false /* enter */);
1154
1155 return err;
1156}
1157
Steven Moreland67f67b42016-09-29 08:59:02 -07001158// static
1159void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001160 out.sIf(nonNull + " == nullptr", [&] {
1161 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1162 out.indent(2, [&] {
1163 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1164 });
1165 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001166}
1167
Andreas Huber881227d2016-08-02 14:20:21 -07001168status_t AST::generateTypeSource(
1169 Formatter &out, const std::string &ifaceName) const {
1170 return mRootScope->emitTypeDefinitions(out, ifaceName);
1171}
1172
Andreas Hubere7ff2282016-08-16 13:50:03 -07001173void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001174 Formatter &out,
1175 const std::vector<TypedVar *> &args,
1176 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001177 if (args.empty()) {
1178 return;
1179 }
1180
1181 for (const auto &arg : args) {
1182 const Type &type = arg->type();
1183
Yifan Hong3b320f82016-11-01 15:15:54 -07001184 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001185 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001186 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001187 << ";\n";
1188 }
1189
1190 out << "\n";
1191}
1192
Andreas Huber881227d2016-08-02 14:20:21 -07001193void AST::emitCppReaderWriter(
1194 Formatter &out,
1195 const std::string &parcelObj,
1196 bool parcelObjIsPointer,
1197 const TypedVar *arg,
1198 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001199 Type::ErrorMode mode,
1200 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001201 const Type &type = arg->type();
1202
Andreas Huber881227d2016-08-02 14:20:21 -07001203 type.emitReaderWriter(
1204 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001205 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001206 parcelObj,
1207 parcelObjIsPointer,
1208 isReader,
1209 mode);
1210}
1211
Yifan Hongbf459bc2016-08-23 16:50:37 -07001212void AST::emitCppResolveReferences(
1213 Formatter &out,
1214 const std::string &parcelObj,
1215 bool parcelObjIsPointer,
1216 const TypedVar *arg,
1217 bool isReader,
1218 Type::ErrorMode mode,
1219 bool addPrefixToName) const {
1220 const Type &type = arg->type();
1221 if(type.needsResolveReferences()) {
1222 type.emitResolveReferences(
1223 out,
1224 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1225 isReader, // nameIsPointer
1226 parcelObj,
1227 parcelObjIsPointer,
1228 isReader,
1229 mode);
1230 }
1231}
1232
Yifan Hong068c5522016-10-31 14:07:25 -07001233status_t AST::generateProxyMethodSource(Formatter &out,
1234 const std::string &klassName,
1235 const Method *method,
1236 const Interface *superInterface) const {
1237
1238 method->generateCppSignature(out,
1239 klassName,
1240 true /* specify namespaces */);
1241
1242 const bool returnsValue = !method->results().empty();
1243 const TypedVar *elidedReturn = method->canElideCallback();
1244
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001245 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001246
1247 out.indent();
1248
Martijn Coenen115d4282016-12-19 05:14:04 +01001249 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1250 method->cppImpl(IMPL_PROXY, out);
1251 out.unindent();
1252 out << "}\n\n";
1253 return OK;
1254 }
1255
Yifan Hong068c5522016-10-31 14:07:25 -07001256 if (returnsValue && elidedReturn == nullptr) {
1257 generateCheckNonNull(out, "_hidl_cb");
1258 }
1259
1260 status_t status = generateCppInstrumentationCall(
1261 out,
1262 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001263 method);
1264 if (status != OK) {
1265 return status;
1266 }
1267
1268 out << "::android::hardware::Parcel _hidl_data;\n";
1269 out << "::android::hardware::Parcel _hidl_reply;\n";
1270 out << "::android::status_t _hidl_err;\n";
1271 out << "::android::hardware::Status _hidl_status;\n\n";
1272
1273 declareCppReaderLocals(
1274 out, method->results(), true /* forResults */);
1275
1276 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001277 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001278 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001279 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1280
Martijn Coenenfff73352017-01-04 16:36:31 +01001281 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001282 // First DFS: write all buffers and resolve pointers for parent
1283 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001284 if (arg->type().isInterface()) {
1285 hasInterfaceArgument = true;
1286 }
Yifan Hong068c5522016-10-31 14:07:25 -07001287 emitCppReaderWriter(
1288 out,
1289 "_hidl_data",
1290 false /* parcelObjIsPointer */,
1291 arg,
1292 false /* reader */,
1293 Type::ErrorMode_Goto,
1294 false /* addPrefixToName */);
1295 }
1296
1297 // Second DFS: resolve references.
1298 for (const auto &arg : method->args()) {
1299 emitCppResolveReferences(
1300 out,
1301 "_hidl_data",
1302 false /* parcelObjIsPointer */,
1303 arg,
1304 false /* reader */,
1305 Type::ErrorMode_Goto,
1306 false /* addPrefixToName */);
1307 }
1308
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001309 if (hasInterfaceArgument) {
1310 // Start binder threadpool to handle incoming transactions
1311 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1312 }
Yifan Hong068c5522016-10-31 14:07:25 -07001313 out << "_hidl_err = remote()->transact("
1314 << method->getSerialId()
1315 << " /* "
1316 << method->name()
1317 << " */, _hidl_data, &_hidl_reply";
1318
1319 if (method->isOneway()) {
1320 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1321 }
1322 out << ");\n";
1323
1324 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1325
1326 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001327 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001328 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1329 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1330
1331
1332 // First DFS: write all buffers and resolve pointers for parent
1333 for (const auto &arg : method->results()) {
1334 emitCppReaderWriter(
1335 out,
1336 "_hidl_reply",
1337 false /* parcelObjIsPointer */,
1338 arg,
1339 true /* reader */,
1340 Type::ErrorMode_Goto,
1341 true /* addPrefixToName */);
1342 }
1343
1344 // Second DFS: resolve references.
1345 for (const auto &arg : method->results()) {
1346 emitCppResolveReferences(
1347 out,
1348 "_hidl_reply",
1349 false /* parcelObjIsPointer */,
1350 arg,
1351 true /* reader */,
1352 Type::ErrorMode_Goto,
1353 true /* addPrefixToName */);
1354 }
1355
1356 if (returnsValue && elidedReturn == nullptr) {
1357 out << "_hidl_cb(";
1358
Yifan Hong7d234ea2017-03-30 15:40:22 -07001359 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001360 if (arg->type().resultNeedsDeref()) {
1361 out << "*";
1362 }
1363 out << "_hidl_out_" << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001364 });
Yifan Hong068c5522016-10-31 14:07:25 -07001365
1366 out << ");\n\n";
1367 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001368 }
1369 status = generateCppInstrumentationCall(
1370 out,
1371 InstrumentationEvent::CLIENT_API_EXIT,
1372 method);
1373 if (status != OK) {
1374 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001375 }
1376
1377 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001378 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1379 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001380 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001381 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1382 } else {
1383 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1384 out << "return ::android::hardware::Return<void>();\n\n";
1385 }
1386
1387 out.unindent();
1388 out << "_hidl_error:\n";
1389 out.indent();
1390 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1391 out << "return ::android::hardware::Return<";
1392 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001393 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001394 } else {
1395 out << "void";
1396 }
1397 out << ">(_hidl_status);\n";
1398
1399 out.unindent();
1400 out << "}\n\n";
1401 return OK;
1402}
1403
Andreas Huber881227d2016-08-02 14:20:21 -07001404status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001405 Formatter &out, const FQName &fqName) const {
1406 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001407
1408 out << klassName
1409 << "::"
1410 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001411 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001412
1413 out.indent();
1414 out.indent();
1415
1416 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001417 << "<"
1418 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001419 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001420 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001421 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001422 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001423 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001424 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001425
Andreas Huber881227d2016-08-02 14:20:21 -07001426 out.unindent();
1427 out.unindent();
1428 out << "}\n\n";
1429
Yifan Hong068c5522016-10-31 14:07:25 -07001430 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1431 return generateProxyMethodSource(out, klassName, method, superInterface);
1432 });
Andreas Huber881227d2016-08-02 14:20:21 -07001433
Yifan Hong068c5522016-10-31 14:07:25 -07001434 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001435}
1436
1437status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001438 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001439 const Interface *iface) const {
1440 const std::string interfaceName = iface->localName();
1441 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001442
Steven Moreland40786312016-08-16 10:29:40 -07001443 out << klassName
1444 << "::"
1445 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001446 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001447
1448 out.indent();
1449 out.indent();
1450
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001451 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001452 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001453 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001454 out << ": "
1455 << gIBaseFqName.getInterfaceStubFqName().cppName()
1456 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001457 }
1458
1459 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001460 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001461 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001462 << "\") { \n";
1463 out.indent();
1464 out << "_hidl_mImpl = _hidl_impl;\n";
1465 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001466
1467 out.unindent();
1468 out.unindent();
1469 out << "}\n\n";
1470
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001471 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001472 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001473 // class properly.
1474 out << klassName
1475 << "::"
1476 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001477 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1478 << " const std::string &HidlInstrumentor_package,"
1479 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001480
1481 out.indent();
1482 out.indent();
1483
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001484 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001485 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001486 out.indent();
1487 out << "_hidl_mImpl = _hidl_impl;\n";
1488 out.unindent();
1489
1490 out.unindent();
1491 out.unindent();
1492 out << "}\n\n";
1493 }
1494
Yifan Hongbcffce22017-02-01 15:52:06 -08001495 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1496 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1497 return OK;
1498 }
1499 method->generateCppSignature(out, iface->getStubName());
1500 out << " ";
1501 out.block([&] {
1502 method->cppImpl(IMPL_STUB_IMPL, out);
1503 }).endl();
1504 return OK;
1505 });
Steven Moreland60818632017-02-04 00:33:42 -08001506 if (err != OK) {
1507 return err;
1508 }
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001509
Andreas Huber881227d2016-08-02 14:20:21 -07001510 out << "::android::status_t " << klassName << "::onTransact(\n";
1511
1512 out.indent();
1513 out.indent();
1514
Iliyan Malchev549e2592016-08-10 08:59:12 -07001515 out << "uint32_t _hidl_code,\n"
1516 << "const ::android::hardware::Parcel &_hidl_data,\n"
1517 << "::android::hardware::Parcel *_hidl_reply,\n"
1518 << "uint32_t _hidl_flags,\n"
1519 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001520
1521 out.unindent();
1522
Iliyan Malchev549e2592016-08-10 08:59:12 -07001523 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001524 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001525 out.indent();
1526
Yifan Hong10fe0b52016-10-19 14:20:17 -07001527 for (const auto &tuple : iface->allMethodsFromRoot()) {
1528 const Method *method = tuple.method();
1529 const Interface *superInterface = tuple.interface();
1530 out << "case "
1531 << method->getSerialId()
1532 << " /* "
1533 << method->name()
1534 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001535
Yifan Hong10fe0b52016-10-19 14:20:17 -07001536 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001537
Yifan Hong10fe0b52016-10-19 14:20:17 -07001538 status_t err =
1539 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001540
Yifan Hong10fe0b52016-10-19 14:20:17 -07001541 if (err != OK) {
1542 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001543 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001544
1545 out.unindent();
1546 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001547 }
1548
1549 out << "default:\n{\n";
1550 out.indent();
1551
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001552 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001553
1554 out.indent();
1555 out.indent();
1556
Iliyan Malchev549e2592016-08-10 08:59:12 -07001557 out << "_hidl_code, _hidl_data, _hidl_reply, "
1558 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001559
1560 out.unindent();
1561 out.unindent();
1562
1563 out.unindent();
1564 out << "}\n";
1565
1566 out.unindent();
1567 out << "}\n\n";
1568
Yifan Honga018ed52016-12-13 16:35:08 -08001569 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1570 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1571 out.indent(2, [&] {
1572 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1573 out << "_hidl_reply);\n";
1574 });
1575 });
Andreas Huber881227d2016-08-02 14:20:21 -07001576
Iliyan Malchev549e2592016-08-10 08:59:12 -07001577 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001578
1579 out.unindent();
1580 out << "}\n\n";
1581
1582 return OK;
1583}
1584
1585status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001586 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001587 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1588 method->cppImpl(IMPL_STUB, out);
1589 out << "break;\n";
1590 return OK;
1591 }
1592
Yifan Hongeefe4f22017-01-04 15:32:42 -08001593 out << "if (!_hidl_data.enforceInterface("
1594 << iface->fullName()
1595 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001596
Andreas Huber881227d2016-08-02 14:20:21 -07001597 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001598 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001599 out << "break;\n";
1600 out.unindent();
1601 out << "}\n\n";
1602
Andreas Huber5e44a292016-09-27 14:52:39 -07001603 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001604
Yifan Hongbf459bc2016-08-23 16:50:37 -07001605 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001606 for (const auto &arg : method->args()) {
1607 emitCppReaderWriter(
1608 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001609 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001610 false /* parcelObjIsPointer */,
1611 arg,
1612 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001613 Type::ErrorMode_Break,
1614 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001615 }
1616
Yifan Hongbf459bc2016-08-23 16:50:37 -07001617 // Second DFS: resolve references
1618 for (const auto &arg : method->args()) {
1619 emitCppResolveReferences(
1620 out,
1621 "_hidl_data",
1622 false /* parcelObjIsPointer */,
1623 arg,
1624 true /* reader */,
1625 Type::ErrorMode_Break,
1626 false /* addPrefixToName */);
1627 }
1628
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001629 status_t status = generateCppInstrumentationCall(
1630 out,
1631 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001632 method);
1633 if (status != OK) {
1634 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001635 }
1636
Andreas Huber881227d2016-08-02 14:20:21 -07001637 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001638 const TypedVar *elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -08001639 const std::string callee =
1640 (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL))
1641 ? "this" : "_hidl_mImpl";
Andreas Huber881227d2016-08-02 14:20:21 -07001642
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001643 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001644 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001645 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001646 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001647 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001648 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001649 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001650
Yifan Hong7d234ea2017-03-30 15:40:22 -07001651 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001652 if (arg->type().resultNeedsDeref()) {
1653 out << "*";
1654 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001655 out << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001656 });
Andreas Huber881227d2016-08-02 14:20:21 -07001657
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001658 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001659 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1660 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001661
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001662 elidedReturn->type().emitReaderWriter(
1663 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001664 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001665 "_hidl_reply",
1666 true, /* parcelObjIsPointer */
1667 false, /* isReader */
1668 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001669
Yifan Hongbf459bc2016-08-23 16:50:37 -07001670 emitCppResolveReferences(
1671 out,
1672 "_hidl_reply",
1673 true /* parcelObjIsPointer */,
1674 elidedReturn,
1675 false /* reader */,
1676 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001677 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001678
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001679 status_t status = generateCppInstrumentationCall(
1680 out,
1681 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001682 method);
1683 if (status != OK) {
1684 return status;
1685 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001686
Iliyan Malchev549e2592016-08-10 08:59:12 -07001687 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001688 } else {
1689 if (returnsValue) {
1690 out << "bool _hidl_callbackCalled = false;\n\n";
1691 }
Andreas Huber881227d2016-08-02 14:20:21 -07001692
Yifan Hongcd2ae452017-01-31 14:33:40 -08001693 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001694
Yifan Hong7d234ea2017-03-30 15:40:22 -07001695 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001696 if (arg->type().resultNeedsDeref()) {
1697 out << "*";
1698 }
1699
1700 out << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001701 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001702
1703 if (returnsValue) {
Yifan Hong7d234ea2017-03-30 15:40:22 -07001704 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001705 out << ", ";
1706 }
1707
1708 out << "[&](";
1709
Yifan Hong7d234ea2017-03-30 15:40:22 -07001710 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001711 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001712 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001713
1714 out << ") {\n";
1715 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001716 out << "if (_hidl_callbackCalled) {\n";
1717 out.indent();
1718 out << "LOG_ALWAYS_FATAL(\""
1719 << method->name()
1720 << ": _hidl_cb called a second time, but must be called once.\");\n";
1721 out.unindent();
1722 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001723 out << "_hidl_callbackCalled = true;\n\n";
1724
Yifan Hong859e53f2016-11-14 19:08:24 -08001725 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1726 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001727
Yifan Hongbf459bc2016-08-23 16:50:37 -07001728 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001729 for (const auto &arg : method->results()) {
1730 emitCppReaderWriter(
1731 out,
1732 "_hidl_reply",
1733 true /* parcelObjIsPointer */,
1734 arg,
1735 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001736 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001737 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001738 }
1739
Yifan Hongbf459bc2016-08-23 16:50:37 -07001740 // Second DFS: resolve references
1741 for (const auto &arg : method->results()) {
1742 emitCppResolveReferences(
1743 out,
1744 "_hidl_reply",
1745 true /* parcelObjIsPointer */,
1746 arg,
1747 false /* reader */,
1748 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001749 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001750 }
1751
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001752 status_t status = generateCppInstrumentationCall(
1753 out,
1754 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001755 method);
1756 if (status != OK) {
1757 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001758 }
1759
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001760 out << "_hidl_cb(*_hidl_reply);\n";
1761
1762 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001763 out << "});\n\n";
1764 } else {
1765 out << ");\n\n";
1766 status_t status = generateCppInstrumentationCall(
1767 out,
1768 InstrumentationEvent::SERVER_API_EXIT,
1769 method);
1770 if (status != OK) {
1771 return status;
1772 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001773 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001774
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001775 if (returnsValue) {
1776 out << "if (!_hidl_callbackCalled) {\n";
1777 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001778 out << "LOG_ALWAYS_FATAL(\""
1779 << method->name()
1780 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001781 out.unindent();
1782 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001783 } else {
1784 out << "::android::hardware::writeToParcel("
1785 << "::android::hardware::Status::ok(), "
1786 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001787 }
Andreas Huber881227d2016-08-02 14:20:21 -07001788 }
1789
1790 out << "break;\n";
1791
1792 return OK;
1793}
1794
Steven Moreland69e7c702016-09-09 11:16:32 -07001795status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1796 std::string ifaceName;
1797 if (!AST::isInterface(&ifaceName)) {
1798 // types.hal does not get a stub header.
1799 return OK;
1800 }
1801
1802 const Interface *iface = mRootScope->getInterface();
1803
Yifan Hongeefe4f22017-01-04 15:32:42 -08001804 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001805
1806 bool supportOneway = iface->hasOnewayMethods();
1807
1808 std::string path = outputPath;
1809 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1810 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1811 path.append(klassName);
1812 path.append(".h");
1813
1814 CHECK(Coordinator::MakeParentHierarchy(path));
1815 FILE *file = fopen(path.c_str(), "w");
1816
1817 if (file == NULL) {
1818 return -errno;
1819 }
1820
1821 Formatter out(file);
1822
1823 const std::string guard = makeHeaderGuard(klassName);
1824
1825 out << "#ifndef " << guard << "\n";
1826 out << "#define " << guard << "\n\n";
1827
1828 std::vector<std::string> packageComponents;
1829 getPackageAndVersionComponents(
1830 &packageComponents, false /* cpp_compatible */);
1831
Yifan Hongb0949432016-12-15 15:32:24 -08001832 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001833 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001834
1835 generateCppPackageInclude(out, mPackage, ifaceName);
1836 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001837
Yifan Hong7a118f52016-12-07 11:21:15 -08001838 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001839 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001840 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001841 }
1842
1843 enterLeaveNamespace(out, true /* enter */);
1844 out << "\n";
1845
1846 out << "struct "
1847 << klassName
1848 << " : " << ifaceName
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001849 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001850
1851 out.indent();
1852 out << "explicit "
1853 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001854 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001855 << ifaceName
1856 << "> impl);\n";
1857
Yifan Hong068c5522016-10-31 14:07:25 -07001858 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1859 return generatePassthroughMethod(out, method);
1860 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001861
1862 if (err != OK) {
1863 return err;
1864 }
1865
1866 out.unindent();
1867 out << "private:\n";
1868 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001869 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001870
1871 if (supportOneway) {
Yifan Hongef91d362017-03-20 17:18:13 -07001872 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001873
1874 out << "\n";
1875
1876 out << "::android::hardware::Return<void> addOnewayTask("
1877 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001878 }
1879
1880 out.unindent();
1881
1882 out << "};\n\n";
1883
1884 enterLeaveNamespace(out, false /* enter */);
1885
1886 out << "\n#endif // " << guard << "\n";
1887
1888 return OK;
1889}
1890
Yifan Hongfe95aa22016-10-19 17:26:45 -07001891status_t AST::generateInterfaceSource(Formatter &out) const {
1892 const Interface *iface = mRootScope->getInterface();
1893
Yifan Hong2d7126b2016-10-20 15:12:57 -07001894 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001895 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001896
Steven Morelandd4b068a2017-03-20 06:30:51 -07001897 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1898 bool reserved = method->isHidlReserved();
1899
1900 if (!reserved) {
1901 out << "// no default implementation for: ";
1902 }
1903 method->generateCppSignature(out, iface->localName());
1904 if (reserved) {
1905 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001906 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001907 }).endl();
1908 }
1909
1910 out << "\n";
1911
1912 return OK;
1913 });
1914 if (err != OK) {
1915 return err;
1916 }
1917
Yifan Hong3d746092016-12-07 14:26:33 -08001918 for (const Interface *superType : iface->typeChain()) {
Yifan Hong7783bb02017-03-29 03:39:09 -07001919 out << "// static \n::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -08001920 << childTypeResult
Yifan Hong7783bb02017-03-29 03:39:09 -07001921 << "> "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001922 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001923 << "::castFrom("
1924 << superType->getCppArgumentType()
Yifan Hong7783bb02017-03-29 03:39:09 -07001925 << " parent, bool "
1926 << (iface == superType ? "/* emitError */" : "emitError")
1927 << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001928 out.indent();
1929 if (iface == superType) {
1930 out << "return parent;\n";
1931 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001932 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001933 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001934 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001935 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001936 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001937 << ">(\n";
1938 out.indent();
1939 out.indent();
1940 out << "parent, \""
1941 << iface->fqName().string()
Yifan Hong7783bb02017-03-29 03:39:09 -07001942 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001943 out.unindent();
1944 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001945 }
Yifan Hong3d746092016-12-07 14:26:33 -08001946 out.unindent();
1947 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001948 }
1949
1950 return OK;
1951}
1952
Steven Moreland69e7c702016-09-09 11:16:32 -07001953status_t AST::generatePassthroughSource(Formatter &out) const {
1954 const Interface *iface = mRootScope->getInterface();
1955
Yifan Hongeefe4f22017-01-04 15:32:42 -08001956 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001957
1958 out << klassName
1959 << "::"
1960 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001961 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001962 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001963 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001964 << mPackage.string()
1965 << "\", \""
1966 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001967 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001968 if (iface->hasOnewayMethods()) {
1969 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001970 out.indent([&] {
Yifan Hongf01dad42017-03-20 19:03:11 -07001971 out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001972 });
1973 }
1974 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001975
1976 if (iface->hasOnewayMethods()) {
1977 out << "::android::hardware::Return<void> "
1978 << klassName
1979 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1980 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001981 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001982 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001983 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1984 out.indent();
1985 out.indent();
1986 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1987 out.unindent();
1988 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001989 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001990 out << "}\n";
1991
Steven Morelandd366c262016-10-11 15:29:10 -07001992 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001993
1994 out.unindent();
1995 out << "}\n\n";
1996
1997
1998 }
1999
2000 return OK;
2001}
2002
Martijn Coenen7b295242016-11-04 16:52:56 +01002003status_t AST::generateCppAtraceCall(Formatter &out,
2004 InstrumentationEvent event,
2005 const Method *method) const {
2006 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08002007 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01002008 switch (event) {
2009 case SERVER_API_ENTRY:
2010 {
2011 out << "atrace_begin(ATRACE_TAG_HAL, \""
2012 << baseString + "::server\");\n";
2013 break;
2014 }
2015 case CLIENT_API_ENTRY:
2016 {
2017 out << "atrace_begin(ATRACE_TAG_HAL, \""
2018 << baseString + "::client\");\n";
2019 break;
2020 }
2021 case PASSTHROUGH_ENTRY:
2022 {
2023 out << "atrace_begin(ATRACE_TAG_HAL, \""
2024 << baseString + "::passthrough\");\n";
2025 break;
2026 }
2027 case SERVER_API_EXIT:
2028 case CLIENT_API_EXIT:
2029 case PASSTHROUGH_EXIT:
2030 {
2031 out << "atrace_end(ATRACE_TAG_HAL);\n";
2032 break;
2033 }
2034 default:
2035 {
2036 LOG(ERROR) << "Unsupported instrumentation event: " << event;
2037 return UNKNOWN_ERROR;
2038 }
2039 }
2040
2041 return OK;
2042}
2043
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002044status_t AST::generateCppInstrumentationCall(
2045 Formatter &out,
2046 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07002047 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01002048 status_t err = generateCppAtraceCall(out, event, method);
2049 if (err != OK) {
2050 return err;
2051 }
2052
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002053 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
2054 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002055 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002056 std::string event_str = "";
2057 switch (event) {
2058 case SERVER_API_ENTRY:
2059 {
2060 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
2061 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002062 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002063 << (arg->type().resultNeedsDeref() ? "" : "&")
2064 << arg->name()
2065 << ");\n";
2066 }
2067 break;
2068 }
2069 case SERVER_API_EXIT:
2070 {
2071 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07002072 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002073 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07002074 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002075 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002076 }
2077 break;
2078 }
2079 case CLIENT_API_ENTRY:
2080 {
2081 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2082 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002083 out << "_hidl_args.push_back((void *)&"
2084 << arg->name()
2085 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002086 }
2087 break;
2088 }
2089 case CLIENT_API_EXIT:
2090 {
2091 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2092 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002093 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002094 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002095 << "_hidl_out_"
2096 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002097 << ");\n";
2098 }
2099 break;
2100 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002101 case PASSTHROUGH_ENTRY:
2102 {
2103 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2104 for (const auto &arg : method->args()) {
2105 out << "_hidl_args.push_back((void *)&"
2106 << arg->name()
2107 << ");\n";
2108 }
2109 break;
2110 }
2111 case PASSTHROUGH_EXIT:
2112 {
2113 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002114 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002115 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002116 << arg->name()
2117 << ");\n";
2118 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002119 break;
2120 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002121 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002122 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002123 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002124 return UNKNOWN_ERROR;
2125 }
2126 }
2127
Steven Moreland031ccf12016-10-31 15:54:38 -07002128 const Interface *iface = mRootScope->getInterface();
2129
Steven Moreland1ab31442016-11-03 18:37:51 -07002130 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002131 out.indent();
2132 out << "callback("
2133 << event_str
2134 << ", \""
2135 << mPackage.package()
2136 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002137 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002138 << "\", \""
2139 << iface->localName()
2140 << "\", \""
2141 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002142 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002143 out.unindent();
2144 out << "}\n";
2145 out.unindent();
2146 out << "}\n\n";
2147
2148 return OK;
2149}
2150
Andreas Huber881227d2016-08-02 14:20:21 -07002151} // namespace android