blob: 6d67a3d1e4ed49bfbef7fe3e77166c9047af63f9 [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"
Andreas Huber02ef12f2017-04-06 11:09:07 -070022#include "HidlTypeAssertion.h"
Andreas Huber881227d2016-08-02 14:20:21 -070023#include "Method.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070024#include "ScalarType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070025#include "Scope.h"
26
Andreas Huberdca261f2016-08-04 13:47:51 -070027#include <algorithm>
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070028#include <hidl-util/Formatter.h>
Steven Moreland5708edf2016-11-04 15:33:31 +000029#include <hidl-util/StringHelper.h>
Andreas Huber881227d2016-08-02 14:20:21 -070030#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070031#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070032#include <vector>
33
34namespace android {
35
Andreas Huberb82318c2016-08-02 14:45:54 -070036status_t AST::generateCpp(const std::string &outputPath) const {
Steven Moreland4f7b11c2017-05-09 14:32:53 -070037 status_t err = generateCppHeaders(outputPath);
38
39 if (err == OK) {
40 err = generateCppSources(outputPath);
41 }
42
43 return err;
44}
45
46status_t AST::generateCppHeaders(const std::string &outputPath) const {
Andreas Huberb82318c2016-08-02 14:45:54 -070047 status_t err = generateInterfaceHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070048
49 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070050 err = generateStubHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070051 }
52
53 if (err == OK) {
Steven Moreland40786312016-08-16 10:29:40 -070054 err = generateHwBinderHeader(outputPath);
55 }
56
57 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070058 err = generateProxyHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070059 }
60
61 if (err == OK) {
Yifan Hong7a118f52016-12-07 11:21:15 -080062 err = generatePassthroughHeader(outputPath);
Steven Moreland69e7c702016-09-09 11:16:32 -070063 }
64
Andreas Huber881227d2016-08-02 14:20:21 -070065 return err;
66}
67
Andreas Huber737080b2016-08-02 15:38:04 -070068void AST::getPackageComponents(
69 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070070 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070071}
72
73void AST::getPackageAndVersionComponents(
74 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070075 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070076}
77
Steven Moreland5708edf2016-11-04 15:33:31 +000078std::string AST::makeHeaderGuard(const std::string &baseName,
79 bool indicateGenerated) const {
80 std::string guard;
Andreas Huber881227d2016-08-02 14:20:21 -070081
Steven Moreland5708edf2016-11-04 15:33:31 +000082 if (indicateGenerated) {
83 guard += "HIDL_GENERATED_";
84 }
85
86 guard += StringHelper::Uppercase(mPackage.tokenName());
Andreas Huber881227d2016-08-02 14:20:21 -070087 guard += "_";
Steven Moreland5708edf2016-11-04 15:33:31 +000088 guard += StringHelper::Uppercase(baseName);
89 guard += "_H";
Andreas Huber881227d2016-08-02 14:20:21 -070090
91 return guard;
92}
93
Steven Morelandee88eed2016-10-31 17:49:00 -070094// static
95void AST::generateCppPackageInclude(
96 Formatter &out,
97 const FQName &package,
98 const std::string &klass) {
99
100 out << "#include <";
101
102 std::vector<std::string> components;
103 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
104
105 for (const auto &component : components) {
106 out << component << "/";
107 }
108
109 out << klass
110 << ".h>\n";
111}
112
Andreas Huber881227d2016-08-02 14:20:21 -0700113void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
114 std::vector<std::string> packageComponents;
115 getPackageAndVersionComponents(
116 &packageComponents, true /* cpp_compatible */);
117
118 if (enter) {
119 for (const auto &component : packageComponents) {
120 out << "namespace " << component << " {\n";
121 }
Andreas Huber0e00de42016-08-03 09:56:02 -0700122
Andreas Huber2831d512016-08-15 09:33:47 -0700123 out.setNamespace(mPackage.cppNamespace() + "::");
Andreas Huber881227d2016-08-02 14:20:21 -0700124 } else {
Andreas Huber0e00de42016-08-03 09:56:02 -0700125 out.setNamespace(std::string());
126
Andreas Huber881227d2016-08-02 14:20:21 -0700127 for (auto it = packageComponents.rbegin();
128 it != packageComponents.rend();
129 ++it) {
130 out << "} // namespace " << *it << "\n";
131 }
132 }
133}
134
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700135static void declareGetService(Formatter &out, const std::string &interfaceName, bool isTry) {
136 const std::string functionName = isTry ? "tryGetService" : "getService";
137
138 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800139 << "const std::string &serviceName=\"default\", bool getStub=false);\n";
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700140 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800141 << "const char serviceName[], bool getStub=false)"
142 << " { std::string str(serviceName ? serviceName : \"\");"
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700143 << " return " << functionName << "(str, getStub); }\n";
144 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800145 << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
146 // without c_str the std::string constructor is ambiguous
147 << " { std::string str(serviceName.c_str());"
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700148 << " return " << functionName << "(str, getStub); }\n";
149 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
150 << "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
151}
152
153static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
154 declareGetService(out, interfaceName, true /* isTry */);
155 declareGetService(out, interfaceName, false /* isTry */);
156
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800157 out << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800158 out << "static bool registerForNotifications(\n";
159 out.indent(2, [&] {
160 out << "const std::string &serviceName,\n"
161 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
162 << "&notification);\n";
163 });
164
165}
166
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700167static void implementGetService(Formatter &out,
168 const FQName &fqName,
169 bool isTry) {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800170
171 const std::string interfaceName = fqName.getInterfaceName();
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700172 const std::string functionName = isTry ? "tryGetService" : "getService";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800173
174 out << "// static\n"
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700175 << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
Yifan Hong31f07ff2017-03-21 18:56:35 +0000176 << "const std::string &serviceName, const bool getStub) ";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800177 out.block([&] {
Steven Moreland8146c322017-04-06 09:17:44 -0700178 out << "using ::android::hardware::defaultServiceManager;\n";
179 out << "using ::android::hardware::details::waitForHwService;\n";
180 out << "using ::android::hardware::getPassthroughServiceManager;\n";
181 out << "using ::android::hardware::Return;\n";
182 out << "using ::android::sp;\n";
183 out << "using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;\n\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000184
Steven Moreland8146c322017-04-06 09:17:44 -0700185 out << "sp<" << interfaceName << "> iface = nullptr;\n";
186
187 out.endl();
188
189 out << "const sp<::android::hidl::manager::V1_0::IServiceManager> sm"
190 << " = defaultServiceManager();\n";
191
192 out.sIf("sm == nullptr", [&] {
193 // hwbinder is not available on this device, so future tries
194 // would also be null. I can only return nullptr.
195 out << "ALOGE(\"getService: defaultServiceManager() is null\");\n"
196 << "return nullptr;\n";
197 }).endl().endl();
198
199 out << "Return<Transport> transportRet = sm->getTransport("
200 << interfaceName << "::descriptor, serviceName);\n\n";
201
202 out.sIf("!transportRet.isOk()", [&] {
203 out << "ALOGE(\"getService: defaultServiceManager()->getTransport returns %s\", "
204 << "transportRet.description().c_str());\n";
205 out << "return nullptr;\n";
206 });
207
208 out.endl();
209
210 out << "Transport transport = transportRet;\n";
211 out << "const bool vintfHwbinder = (transport == Transport::HWBINDER);\n"
212 << "const bool vintfPassthru = (transport == Transport::PASSTHROUGH);\n"
213 << "const bool vintfEmpty = (transport == Transport::EMPTY);\n\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000214
215 // if (getStub) {
216 // getPassthroughServiceManager()->get only once.
217 // } else {
218 // if (vintfHwbinder) {
219 // while (no alive service) {
220 // waitForHwService
221 // defaultServiceManager()->get
222 // }
223 // } else if (vintfEmpty) {
224 // defaultServiceManager()->get only once.
225 // getPassthroughServiceManager()->get only once.
226 // } else if (vintfPassthru) {
227 // getPassthroughServiceManager()->get only once.
228 // }
229 // }
230
Yifan Hongf1ef44f2017-03-23 17:17:57 +0000231 out << "bool tried = false;\n";
232 out.sWhile("!getStub && (vintfHwbinder || (vintfEmpty && !tried))", [&] {
Yifan Hong31f07ff2017-03-21 18:56:35 +0000233
234 out.sIf("tried", [&] {
235 // sleep only after the first trial.
236 out << "ALOGI(\"getService: retrying in 1s...\");\n"
237 << "sleep(1);\n";
238 }).endl();
239
Yifan Hongf1ef44f2017-03-23 17:17:57 +0000240 out << "tried = true;\n";
241
Yifan Hong31f07ff2017-03-21 18:56:35 +0000242
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700243 if (!isTry) {
244 out.sIf("vintfHwbinder", [&] {
Steven Moreland8146c322017-04-06 09:17:44 -0700245 out << "waitForHwService("
246 << interfaceName << "::descriptor, serviceName);\n";
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700247 }).endl();
248 }
Yifan Hong31f07ff2017-03-21 18:56:35 +0000249
Steven Moreland8146c322017-04-06 09:17:44 -0700250 out << "Return<sp<" << gIBaseFqName.cppName() << ">> ret = \n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000251 out.indent(2, [&] {
252 out << "sm->get(" << interfaceName << "::descriptor, serviceName);\n";
253 });
254
255 out.sIf("!ret.isOk()", [&] {
Steven Moreland42394ce2017-03-27 17:03:04 -0700256 // hwservicemanager fails, may be security issue
Yifan Hong31f07ff2017-03-21 18:56:35 +0000257 out << "ALOGE(\"getService: defaultServiceManager()->get returns %s\", "
258 << "ret.description().c_str());\n"
Steven Moreland42394ce2017-03-27 17:03:04 -0700259 << "break;\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000260 }).endl();
261
Steven Moreland8146c322017-04-06 09:17:44 -0700262 out << "sp<" << gIBaseFqName.cppName() << "> base = ret;\n";
Yifan Hong7783bb02017-03-29 03:39:09 -0700263 out.sIf("base == nullptr", [&] {
264 // race condition. hwservicemanager drops the service
265 // from waitForHwService to here
Steven Morelanddff644c2017-03-24 10:59:01 -0700266 out << "ALOGW(\"getService: found null hwbinder interface\");\n"
Yifan Hongdd0b55d2017-04-04 13:27:25 -0700267 << (isTry ? "break" : "continue")
268 << ";\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000269 }).endl();
Steven Moreland8146c322017-04-06 09:17:44 -0700270 out << "Return<sp<" << interfaceName
Yifan Hong7783bb02017-03-29 03:39:09 -0700271 << ">> castRet = " << interfaceName << "::castFrom(base, true /* emitError */);\n";
272 out.sIf("!castRet.isOk()", [&] {
273 out.sIf("castRet.isDeadObject()", [&] {
274 // service is dead (castFrom cannot call interfaceChain)
275 out << "ALOGW(\"getService: found dead hwbinder service\");\n"
Yifan Hongdd0b55d2017-04-04 13:27:25 -0700276 << (isTry ? "break" : "continue")
277 << ";\n";
Yifan Hong7783bb02017-03-29 03:39:09 -0700278 }).sElse([&] {
279 out << "ALOGW(\"getService: cannot call into hwbinder service: %s"
280 << "; No permission? Check for selinux denials.\", "
281 << "castRet.description().c_str());\n"
282 << "break;\n";
283 }).endl();
284 }).endl();
285 out << "iface = castRet;\n";
286 out.sIf("iface == nullptr", [&] {
287 // returned service isn't of correct type; this is a bug
288 // to hwservicemanager or to the service itself (interfaceChain
289 // is not consistent).
290 out << "ALOGW(\"getService: received incompatible service; bug in hwservicemanager?\");\n"
Yifan Hong31f07ff2017-03-21 18:56:35 +0000291 << "break;\n";
292 }).endl();
293
294 out << "return iface;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800295 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800296
Yifan Hong31f07ff2017-03-21 18:56:35 +0000297 out.sIf("getStub || vintfPassthru || vintfEmpty", [&] {
Steven Moreland8146c322017-04-06 09:17:44 -0700298 out << "const sp<::android::hidl::manager::V1_0::IServiceManager> pm"
299 << " = getPassthroughServiceManager();\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000300
301 out.sIf("pm != nullptr", [&] () {
Steven Moreland8146c322017-04-06 09:17:44 -0700302 out << "Return<sp<" << gIBaseFqName.cppName() << ">> ret = \n";
Steven Morelandf10af872017-01-25 16:01:56 +0000303 out.indent(2, [&] {
304 out << "pm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
Steven Moreland2c2dea82017-01-18 17:24:17 -0800305 });
Steven Morelandf10af872017-01-25 16:01:56 +0000306 out.sIf("ret.isOk()", [&] {
Steven Moreland8146c322017-04-06 09:17:44 -0700307 out << "sp<" << gIBaseFqName.cppName()
Steven Morelandf10af872017-01-25 16:01:56 +0000308 << "> baseInterface = ret;\n";
309 out.sIf("baseInterface != nullptr", [&]() {
310 out << "iface = new " << fqName.getInterfacePassthroughName()
311 << "(" << interfaceName << "::castFrom(baseInterface));\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000312 }).endl();
Steven Morelandf10af872017-01-25 16:01:56 +0000313 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800314 }).endl();
315 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800316
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800317 out << "return iface;\n";
318 }).endl().endl();
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700319}
320
321static void implementServiceManagerInteractions(Formatter &out,
322 const FQName &fqName, const std::string &package) {
323
324 const std::string interfaceName = fqName.getInterfaceName();
325
326 implementGetService(out, fqName, true /* isTry */);
327 implementGetService(out, fqName, false /* isTry */);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800328
Yifan Hongeefe4f22017-01-04 15:32:42 -0800329 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800330 << "const std::string &serviceName) ";
331 out.block([&] {
Steven Morelanda9582e62017-04-09 10:54:50 -0700332 out << "::android::hardware::details::onRegistration(\""
333 << fqName.getPackageAndVersion().string() << "\", \""
334 << interfaceName
335 << "\", serviceName);\n\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800336 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
337 out.indent(2, [&] {
338 out << "= ::android::hardware::defaultServiceManager();\n";
339 });
340 out.sIf("sm == nullptr", [&] {
341 out << "return ::android::INVALID_OPERATION;\n";
342 }).endl();
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100343 out << "::android::hardware::Return<bool> ret = "
344 << "sm->add(serviceName.c_str(), this);\n"
345 << "return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800346 }).endl().endl();
347
Yifan Hongeefe4f22017-01-04 15:32:42 -0800348 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800349 out.indent(2, [&] {
350 out << "const std::string &serviceName,\n"
351 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
352 << "&notification) ";
353 });
354 out.block([&] {
355 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
356 out.indent(2, [&] {
357 out << "= ::android::hardware::defaultServiceManager();\n";
358 });
359 out.sIf("sm == nullptr", [&] {
360 out << "return false;\n";
361 }).endl();
362 out << "::android::hardware::Return<bool> success =\n";
363 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800364 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800365 out.indent(2, [&] {
366 out << "serviceName, notification);\n";
367 });
368 });
369 out << "return success.isOk() && success;\n";
370 }).endl().endl();
371}
372
Andreas Huberb82318c2016-08-02 14:45:54 -0700373status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700374
Andreas Huberb82318c2016-08-02 14:45:54 -0700375 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700376 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700377 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700378
379 std::string ifaceName;
380 bool isInterface = true;
381 if (!AST::isInterface(&ifaceName)) {
382 ifaceName = "types";
383 isInterface = false;
384 }
385 path.append(ifaceName);
386 path.append(".h");
387
Andreas Huberd2943e12016-08-05 11:59:31 -0700388 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700389 FILE *file = fopen(path.c_str(), "w");
390
391 if (file == NULL) {
392 return -errno;
393 }
394
395 Formatter out(file);
396
397 const std::string guard = makeHeaderGuard(ifaceName);
398
399 out << "#ifndef " << guard << "\n";
400 out << "#define " << guard << "\n\n";
401
Andreas Huber737080b2016-08-02 15:38:04 -0700402 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700403 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700404 }
405
406 if (!mImportedNames.empty()) {
407 out << "\n";
408 }
409
Steven Moreland0693f312016-11-09 15:06:14 -0800410 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800411 if (isIBase()) {
412 out << "// skipped #include IServiceNotification.h\n\n";
413 } else {
414 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
415 }
Steven Moreland0693f312016-11-09 15:06:14 -0800416 }
417
Yifan Hongc8934042016-11-17 17:10:52 -0800418 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700419 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700420
421 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200422 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700423 }
424
Martijn Coenenaf712c02016-11-16 15:26:27 +0100425 out << "#include <utils/NativeHandle.h>\n";
426 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700427
428 enterLeaveNamespace(out, true /* enter */);
429 out << "\n";
430
431 if (isInterface) {
432 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700433 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700434
435 const Interface *iface = mRootScope->getInterface();
436 const Interface *superType = iface->superType();
437
Steven Moreland40786312016-08-16 10:29:40 -0700438 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800439 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700440 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000441 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700442 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700443 }
444
445 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700446
447 out.indent();
448
Andreas Huber881227d2016-08-02 14:20:21 -0700449 }
450
451 status_t err = emitTypeDeclarations(out);
452
453 if (err != OK) {
454 return err;
455 }
456
457 if (isInterface) {
458 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800459
Yifan Hongc8934042016-11-17 17:10:52 -0800460 out << "virtual bool isRemote() const ";
461 if (!isIBase()) {
462 out << "override ";
463 }
464 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800465
Andreas Huber881227d2016-08-02 14:20:21 -0700466 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700467 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700468
Andreas Huber881227d2016-08-02 14:20:21 -0700469 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800470 const TypedVar *elidedReturn = method->canElideCallback();
471
472 if (elidedReturn == nullptr && returnsValue) {
473 out << "using "
474 << method->name()
Yifan Hong7d234ea2017-03-30 15:40:22 -0700475 << "_cb = std::function<void(";
476 method->emitCppResultSignature(out, true /* specify namespaces */);
477 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800478 }
Andreas Huber881227d2016-08-02 14:20:21 -0700479
Andreas Huber3599d922016-08-09 10:42:57 -0700480 method->dumpAnnotations(out);
481
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700482 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700483 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700484 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700485 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700486 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700487 }
488
489 out << method->name()
Yifan Hong7d234ea2017-03-30 15:40:22 -0700490 << "(";
491 method->emitCppArgSignature(out, true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700492
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700493 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700494 if (!method->args().empty()) {
495 out << ", ";
496 }
497
Steven Moreland67f67b42016-09-29 08:59:02 -0700498 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700499 }
500
Yifan Hong10fe0b52016-10-19 14:20:17 -0700501 out << ")";
502 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800503 if (!isIBase()) {
504 out << " override";
505 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700506 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700507 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700508 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700509 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700510 }
Steven Moreland40786312016-08-16 10:29:40 -0700511
Yifan Hong3d746092016-12-07 14:26:33 -0800512 out << "// cast static functions\n";
513 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700514
Yifan Hong3d746092016-12-07 14:26:33 -0800515 for (const Interface *superType : iface->typeChain()) {
Yifan Hong7783bb02017-03-29 03:39:09 -0700516 out << "static ::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -0800517 << childTypeResult
Yifan Hong7783bb02017-03-29 03:39:09 -0700518 << "> castFrom("
Yifan Hong3d746092016-12-07 14:26:33 -0800519 << superType->getCppArgumentType()
520 << " parent"
Yifan Hong7783bb02017-03-29 03:39:09 -0700521 << ", bool emitError = false);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700522 }
523
Steven Morelandd39133b2016-11-11 12:30:08 -0800524 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700525
Yifan Hongc8934042016-11-17 17:10:52 -0800526 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800527 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800528 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800529 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800530 }
Andreas Huber881227d2016-08-02 14:20:21 -0700531 }
532
533 if (isInterface) {
534 out.unindent();
535
Andreas Hubere3f769a2016-10-10 10:54:44 -0700536 out << "};\n\n";
537 }
538
539 err = mRootScope->emitGlobalTypeDeclarations(out);
540
541 if (err != OK) {
542 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700543 }
544
545 out << "\n";
546 enterLeaveNamespace(out, false /* enter */);
547
548 out << "\n#endif // " << guard << "\n";
549
550 return OK;
551}
552
Steven Moreland40786312016-08-16 10:29:40 -0700553status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
554 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800555 bool isInterface = AST::isInterface(&ifaceName);
556 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800557 std::string klassName{};
558
559 if(isInterface) {
560 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800561 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800562 } else {
563 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700564 }
565
Steven Moreland40786312016-08-16 10:29:40 -0700566 std::string path = outputPath;
567 path.append(mCoordinator->convertPackageRootToPath(mPackage));
568 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
569 path.append(klassName + ".h");
570
Yifan Hong244e82d2016-11-11 11:13:57 -0800571 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700572
573 if (file == NULL) {
574 return -errno;
575 }
576
577 Formatter out(file);
578
579 const std::string guard = makeHeaderGuard(klassName);
580
581 out << "#ifndef " << guard << "\n";
582 out << "#define " << guard << "\n\n";
583
Yifan Hong244e82d2016-11-11 11:13:57 -0800584 if (isInterface) {
585 generateCppPackageInclude(out, mPackage, ifaceName);
586 } else {
587 generateCppPackageInclude(out, mPackage, "types");
588 }
Steven Moreland40786312016-08-16 10:29:40 -0700589
Steven Morelandee88eed2016-10-31 17:49:00 -0700590 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700591
592 for (const auto &item : mImportedNames) {
593 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800594 generateCppPackageInclude(out, item, "hwtypes");
595 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800596 generateCppPackageInclude(out, item, item.getInterfaceStubName());
597 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700598 }
Steven Moreland40786312016-08-16 10:29:40 -0700599 }
600
601 out << "\n";
602
Martijn Coenen93915102016-09-01 01:35:52 +0200603 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700604 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100605 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700606
607 out << "\n";
608
609 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700610
Yifan Hong244e82d2016-11-11 11:13:57 -0800611 status_t err = mRootScope->emitGlobalHwDeclarations(out);
612 if (err != OK) {
613 return err;
614 }
Steven Moreland40786312016-08-16 10:29:40 -0700615
616 enterLeaveNamespace(out, false /* enter */);
617
618 out << "\n#endif // " << guard << "\n";
619
620 return OK;
621}
622
Andreas Huber881227d2016-08-02 14:20:21 -0700623status_t AST::emitTypeDeclarations(Formatter &out) const {
624 return mRootScope->emitTypeDeclarations(out);
625}
626
Yifan Hong7a118f52016-12-07 11:21:15 -0800627static void wrapPassthroughArg(Formatter &out,
628 const TypedVar *arg, bool addPrefixToName,
629 std::function<void(void)> handleError) {
630 if (!arg->type().isInterface()) {
631 return;
632 }
633 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
634 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
635 + arg->name();
636 const Interface &iface = static_cast<const Interface &>(arg->type());
637 out << iface.getCppStackType() << " " << wrappedName << ";\n";
638 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
639 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
640 out << wrappedName
641 << " = "
642 << iface.fqName().cppName()
Yifan Hongeb4fe782017-04-20 18:12:05 -0700643 << "::castFrom(::android::hardware::details::wrapPassthrough<"
644 << iface.fqName().cppName()
645 << ">("
Yifan Hong7a118f52016-12-07 11:21:15 -0800646 << name << "));\n";
647 out.sIf(wrappedName + " == nullptr", [&] {
648 // Fatal error. Happens when the BsFoo class is not found in the binary
649 // or any dynamic libraries.
650 handleError();
651 }).endl();
652 }).sElse([&] {
653 out << wrappedName << " = " << name << ";\n";
654 }).endl().endl();
655}
656
Steven Moreland69e7c702016-09-09 11:16:32 -0700657status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700658 const Method *method) const {
659 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700660
661 out << " {\n";
662 out.indent();
663
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800664 if (method->isHidlReserved()
665 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
666 method->cppImpl(IMPL_PASSTHROUGH, out);
667 out.unindent();
668 out << "}\n\n";
669 return OK;
670 }
671
Steven Moreland69e7c702016-09-09 11:16:32 -0700672 const bool returnsValue = !method->results().empty();
673 const TypedVar *elidedReturn = method->canElideCallback();
674
Steven Moreland67f67b42016-09-29 08:59:02 -0700675 if (returnsValue && elidedReturn == nullptr) {
676 generateCheckNonNull(out, "_hidl_cb");
677 }
678
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700679 generateCppInstrumentationCall(
680 out,
681 InstrumentationEvent::PASSTHROUGH_ENTRY,
682 method);
683
Yifan Hong7a118f52016-12-07 11:21:15 -0800684
685 for (const auto &arg : method->args()) {
686 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
687 out << "return ::android::hardware::Status::fromExceptionCode(\n";
688 out.indent(2, [&] {
689 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800690 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800691 });
692 });
693 }
694
695 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700696 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700697
698 if (method->isOneway()) {
Steven Morelandca279942017-05-02 12:10:13 -0700699 out << "addOnewayTask([mImpl = this->mImpl, "
700 "mEnableInstrumentation = this->mEnableInstrumentation, "
701 "mInstrumentationCallbacks = this->mInstrumentationCallbacks, "
702 "&_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700703 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800704 out << ", "
705 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
706 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700707 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700708 out << "] {\n";
709 out.indent();
Steven Moreland69e7c702016-09-09 11:16:32 -0700710 }
711
712 out << "mImpl->"
713 << method->name()
714 << "(";
715
Yifan Hong7d234ea2017-03-30 15:40:22 -0700716 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800717 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700718 });
Steven Moreland69e7c702016-09-09 11:16:32 -0700719 if (returnsValue && elidedReturn == nullptr) {
720 if (!method->args().empty()) {
721 out << ", ";
722 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800723 out << "[&](";
Yifan Hong7d234ea2017-03-30 15:40:22 -0700724 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800725 out << "const auto &_hidl_out_"
726 << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700727 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800728
729 out << ") {\n";
730 out.indent();
731 status_t status = generateCppInstrumentationCall(
732 out,
733 InstrumentationEvent::PASSTHROUGH_EXIT,
734 method);
735 if (status != OK) {
736 return status;
737 }
738
Yifan Hong7a118f52016-12-07 11:21:15 -0800739 for (const auto &arg : method->results()) {
740 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
741 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
742 out.indent(2, [&] {
743 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800744 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800745 });
746 out << "return;\n";
747 });
748 }
749
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800750 out << "_hidl_cb(";
Yifan Hong7d234ea2017-03-30 15:40:22 -0700751 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800752 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
753 << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700754 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800755 out << ");\n";
756 out.unindent();
757 out << "});\n\n";
758 } else {
759 out << ");\n\n";
760 if (elidedReturn != nullptr) {
761 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800762 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800763 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000764 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800765 }
766 status_t status = generateCppInstrumentationCall(
767 out,
768 InstrumentationEvent::PASSTHROUGH_EXIT,
769 method);
770 if (status != OK) {
771 return status;
772 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700773 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700774
775 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700776 out.unindent();
777 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700778 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700779
780 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700781
782 out.unindent();
783 out << "}\n";
784
785 return OK;
786}
787
Yifan Hong068c5522016-10-31 14:07:25 -0700788status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700789
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700790 const Interface *iface = mRootScope->getInterface();
791
Yifan Hong10fe0b52016-10-19 14:20:17 -0700792 const Interface *prevIterface = nullptr;
793 for (const auto &tuple : iface->allMethodsFromRoot()) {
794 const Method *method = tuple.method();
795 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700796
Yifan Hong10fe0b52016-10-19 14:20:17 -0700797 if(prevIterface != superInterface) {
798 if (prevIterface != nullptr) {
799 out << "\n";
800 }
801 out << "// Methods from "
802 << superInterface->fullName()
803 << " follow.\n";
804 prevIterface = superInterface;
805 }
Yifan Hong068c5522016-10-31 14:07:25 -0700806 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700807
Yifan Hong10fe0b52016-10-19 14:20:17 -0700808 if (err != OK) {
809 return err;
810 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700811 }
812
Yifan Hong10fe0b52016-10-19 14:20:17 -0700813 out << "\n";
814
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700815 return OK;
816}
817
Andreas Huberb82318c2016-08-02 14:45:54 -0700818status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700819 std::string ifaceName;
820 if (!AST::isInterface(&ifaceName)) {
821 // types.hal does not get a stub header.
822 return OK;
823 }
824
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700825 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800826 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700827
Andreas Huberb82318c2016-08-02 14:45:54 -0700828 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700829 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700830 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700831 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700832 path.append(".h");
833
Andreas Huberd2943e12016-08-05 11:59:31 -0700834 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700835 FILE *file = fopen(path.c_str(), "w");
836
837 if (file == NULL) {
838 return -errno;
839 }
840
841 Formatter out(file);
842
Steven Moreland40786312016-08-16 10:29:40 -0700843 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700844
845 out << "#ifndef " << guard << "\n";
846 out << "#define " << guard << "\n\n";
847
Yifan Hongeefe4f22017-01-04 15:32:42 -0800848 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700849 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700850
851 enterLeaveNamespace(out, true /* enter */);
852 out << "\n";
853
854 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800855 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100856 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800857 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000858 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100859 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800860 out << " : public "
861 << gIBaseFqName.getInterfaceStubFqName().cppName()
862 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100863 }
Andreas Huber881227d2016-08-02 14:20:21 -0700864
865 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800866 out << "explicit "
867 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700868 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100869 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800870 out << "explicit "
871 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100872 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800873 << " const std::string& HidlInstrumentor_package,"
874 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700875 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700876 out << "::android::status_t onTransact(\n";
877 out.indent();
878 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700879 out << "uint32_t _hidl_code,\n";
880 out << "const ::android::hardware::Parcel &_hidl_data,\n";
881 out << "::android::hardware::Parcel *_hidl_reply,\n";
882 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700883 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700884 out.unindent();
885 out.unindent();
886
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100887 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
888 out.unindent();
889 out << "private:\n";
890 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800891
892 status_t err = generateMethods(out, [&](const Method *method, const Interface *iface) {
893 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
894 return OK;
895 }
896 const bool returnsValue = !method->results().empty();
897 const TypedVar *elidedReturn = method->canElideCallback();
898
899 if (elidedReturn == nullptr && returnsValue) {
900 out << "using " << method->name() << "_cb = "
901 << iface->fqName().cppName()
902 << "::" << method->name() << "_cb;\n";
903 }
904 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800905 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800906 return OK;
907 });
908 if (err != OK) {
909 return err;
910 }
911
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100912 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700913 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700914 out << "};\n\n";
915
916 enterLeaveNamespace(out, false /* enter */);
917
918 out << "\n#endif // " << guard << "\n";
919
920 return OK;
921}
922
Andreas Huberb82318c2016-08-02 14:45:54 -0700923status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700924 std::string ifaceName;
925 if (!AST::isInterface(&ifaceName)) {
926 // types.hal does not get a proxy header.
927 return OK;
928 }
929
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700930 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800931 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700932
Andreas Huberb82318c2016-08-02 14:45:54 -0700933 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700934 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700935 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800936 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700937 path.append(".h");
938
Andreas Huberd2943e12016-08-05 11:59:31 -0700939 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700940 FILE *file = fopen(path.c_str(), "w");
941
942 if (file == NULL) {
943 return -errno;
944 }
945
946 Formatter out(file);
947
Yifan Hongeefe4f22017-01-04 15:32:42 -0800948 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700949
950 out << "#ifndef " << guard << "\n";
951 out << "#define " << guard << "\n\n";
952
Martijn Coenen115d4282016-12-19 05:14:04 +0100953 out << "#include <hidl/HidlTransportSupport.h>\n\n";
954
Andreas Huber881227d2016-08-02 14:20:21 -0700955 std::vector<std::string> packageComponents;
956 getPackageAndVersionComponents(
957 &packageComponents, false /* cpp_compatible */);
958
Yifan Hongeefe4f22017-01-04 15:32:42 -0800959 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700960 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700961
962 enterLeaveNamespace(out, true /* enter */);
963 out << "\n";
964
965 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800966 << proxyName
967 << " : public ::android::hardware::BpInterface<"
968 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000969 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700970
971 out.indent();
972
Yifan Hongeefe4f22017-01-04 15:32:42 -0800973 out << "explicit "
974 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700975 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700976 << "\n\n";
977
Yifan Hong10fe0b52016-10-19 14:20:17 -0700978 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700979
Yifan Hong068c5522016-10-31 14:07:25 -0700980 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
981 method->generateCppSignature(out);
982 out << " override;\n";
983 return OK;
984 });
Steven Moreland9c387612016-09-07 09:54:26 -0700985
986 if (err != OK) {
987 return err;
988 }
Andreas Huber881227d2016-08-02 14:20:21 -0700989
990 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100991 out << "private:\n";
992 out.indent();
993 out << "std::mutex _hidl_mMutex;\n"
994 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
995 << " _hidl_mDeathRecipients;\n";
996 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700997 out << "};\n\n";
998
999 enterLeaveNamespace(out, false /* enter */);
1000
1001 out << "\n#endif // " << guard << "\n";
1002
1003 return OK;
1004}
1005
Steven Moreland4f7b11c2017-05-09 14:32:53 -07001006status_t AST::generateCppSources(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001007
Andreas Huberb82318c2016-08-02 14:45:54 -07001008 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -07001009 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -07001010 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -07001011
1012 std::string ifaceName;
1013 std::string baseName;
1014
Yifan Hongfe95aa22016-10-19 17:26:45 -07001015 const Interface *iface = nullptr;
1016 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -07001017 if (!AST::isInterface(&ifaceName)) {
1018 baseName = "types";
1019 isInterface = false;
1020 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001021 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -07001022 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001023 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -07001024 }
1025
1026 path.append(baseName);
1027
1028 if (baseName != "types") {
1029 path.append("All");
1030 }
1031
1032 path.append(".cpp");
1033
Andreas Huberd2943e12016-08-05 11:59:31 -07001034 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -07001035 FILE *file = fopen(path.c_str(), "w");
1036
1037 if (file == NULL) {
1038 return -errno;
1039 }
1040
1041 Formatter out(file);
1042
Steven Moreland623c0042017-01-13 14:42:29 -08001043 out << "#define LOG_TAG \""
1044 << mPackage.string() << "::" << baseName
1045 << "\"\n\n";
1046
Steven Moreland05cd4232016-11-21 16:01:12 -08001047 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001048 out << "#include <cutils/trace.h>\n";
1049 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001050 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -07001051 // This is a no-op for IServiceManager itself.
1052 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
1053
Steven Morelandbec74ed2017-01-25 17:42:35 -08001054 // TODO(b/34274385) remove this
1055 out << "#include <hidl/LegacySupport.h>\n";
1056
Yifan Hongeefe4f22017-01-04 15:32:42 -08001057 generateCppPackageInclude(out, mPackage, iface->getProxyName());
1058 generateCppPackageInclude(out, mPackage, iface->getStubName());
1059 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001060
1061 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -07001062 generateCppPackageInclude(out,
1063 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -08001064 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001065 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -08001066
1067 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001068 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -07001069 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -08001070 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -07001071 }
1072
1073 out << "\n";
1074
1075 enterLeaveNamespace(out, true /* enter */);
1076 out << "\n";
1077
1078 status_t err = generateTypeSource(out, ifaceName);
1079
1080 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001081 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001082
1083 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -08001084 out << "const char* "
1085 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -07001086 << "::descriptor(\""
1087 << iface->fqName().string()
1088 << "\");\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +01001089 out << "__attribute__((constructor))";
1090 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001091 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001092 out << "::android::hardware::details::gBnConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001093 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001094 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001095 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001096 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001097 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001098 out << "return new "
1099 << iface->getStubName()
Yifan Hongeb4fe782017-04-20 18:12:05 -07001100 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001101 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001102 << " *>(iIntf));\n";
1103 });
Yifan Hongb04de382017-02-06 15:31:52 -08001104 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001105 });
Yifan Honga159f3b2017-03-16 14:53:51 -07001106 out << "::android::hardware::details::gBsConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001107 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001108 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001109 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001110 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -08001111 << gIBaseFqName.cppName()
1112 << "> {\n";
1113 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001114 out << "return new "
1115 << iface->getPassthroughName()
Yifan Hongeb4fe782017-04-20 18:12:05 -07001116 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001117 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001118 << " *>(iIntf));\n";
1119 });
Yifan Hongb04de382017-02-06 15:31:52 -08001120 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001121 });
Yifan Hong158655a2016-11-08 12:34:07 -08001122 });
Martijn Coenen8adcb652017-02-03 17:37:36 +01001123 out << "};\n\n";
1124 out << "__attribute__((destructor))";
1125 out << "static void static_destructor() {\n";
1126 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001127 out << "::android::hardware::details::gBnConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001128 << iface->localName()
1129 << "::descriptor);\n";
Yifan Honga159f3b2017-03-16 14:53:51 -07001130 out << "::android::hardware::details::gBsConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001131 << iface->localName()
1132 << "::descriptor);\n";
1133 });
1134 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001135
Yifan Hongfe95aa22016-10-19 17:26:45 -07001136 err = generateInterfaceSource(out);
1137 }
1138
1139 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001140 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001141 }
1142
1143 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001144 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001145 }
1146
Steven Moreland40786312016-08-16 10:29:40 -07001147 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001148 err = generatePassthroughSource(out);
1149 }
1150
1151 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001152 const Interface *iface = mRootScope->getInterface();
1153
Yifan Hongc8934042016-11-17 17:10:52 -08001154 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001155 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001156 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001157 std::string package = iface->fqName().package()
1158 + iface->fqName().atVersion();
1159
Yifan Hongeefe4f22017-01-04 15:32:42 -08001160 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001161 }
Steven Moreland40786312016-08-16 10:29:40 -07001162 }
1163
Andreas Huber02ef12f2017-04-06 11:09:07 -07001164 HidlTypeAssertion::EmitAll(out);
1165 out << "\n";
1166
Andreas Huber881227d2016-08-02 14:20:21 -07001167 enterLeaveNamespace(out, false /* enter */);
1168
1169 return err;
1170}
1171
Steven Moreland67f67b42016-09-29 08:59:02 -07001172// static
1173void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001174 out.sIf(nonNull + " == nullptr", [&] {
1175 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1176 out.indent(2, [&] {
1177 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1178 });
1179 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001180}
1181
Andreas Huber881227d2016-08-02 14:20:21 -07001182status_t AST::generateTypeSource(
1183 Formatter &out, const std::string &ifaceName) const {
1184 return mRootScope->emitTypeDefinitions(out, ifaceName);
1185}
1186
Andreas Hubere7ff2282016-08-16 13:50:03 -07001187void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001188 Formatter &out,
1189 const std::vector<TypedVar *> &args,
1190 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001191 if (args.empty()) {
1192 return;
1193 }
1194
1195 for (const auto &arg : args) {
1196 const Type &type = arg->type();
1197
Yifan Hong3b320f82016-11-01 15:15:54 -07001198 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001199 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001200 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001201 << ";\n";
1202 }
1203
1204 out << "\n";
1205}
1206
Andreas Huber881227d2016-08-02 14:20:21 -07001207void AST::emitCppReaderWriter(
1208 Formatter &out,
1209 const std::string &parcelObj,
1210 bool parcelObjIsPointer,
1211 const TypedVar *arg,
1212 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001213 Type::ErrorMode mode,
1214 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001215 const Type &type = arg->type();
1216
Andreas Huber881227d2016-08-02 14:20:21 -07001217 type.emitReaderWriter(
1218 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001219 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001220 parcelObj,
1221 parcelObjIsPointer,
1222 isReader,
1223 mode);
1224}
1225
Yifan Hongbf459bc2016-08-23 16:50:37 -07001226void AST::emitCppResolveReferences(
1227 Formatter &out,
1228 const std::string &parcelObj,
1229 bool parcelObjIsPointer,
1230 const TypedVar *arg,
1231 bool isReader,
1232 Type::ErrorMode mode,
1233 bool addPrefixToName) const {
1234 const Type &type = arg->type();
1235 if(type.needsResolveReferences()) {
1236 type.emitResolveReferences(
1237 out,
1238 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1239 isReader, // nameIsPointer
1240 parcelObj,
1241 parcelObjIsPointer,
1242 isReader,
1243 mode);
1244 }
1245}
1246
Yifan Hong068c5522016-10-31 14:07:25 -07001247status_t AST::generateProxyMethodSource(Formatter &out,
1248 const std::string &klassName,
1249 const Method *method,
1250 const Interface *superInterface) const {
1251
1252 method->generateCppSignature(out,
1253 klassName,
1254 true /* specify namespaces */);
1255
1256 const bool returnsValue = !method->results().empty();
1257 const TypedVar *elidedReturn = method->canElideCallback();
1258
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001259 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001260
1261 out.indent();
1262
Martijn Coenen115d4282016-12-19 05:14:04 +01001263 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1264 method->cppImpl(IMPL_PROXY, out);
1265 out.unindent();
1266 out << "}\n\n";
1267 return OK;
1268 }
1269
Yifan Hong068c5522016-10-31 14:07:25 -07001270 if (returnsValue && elidedReturn == nullptr) {
1271 generateCheckNonNull(out, "_hidl_cb");
1272 }
1273
1274 status_t status = generateCppInstrumentationCall(
1275 out,
1276 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001277 method);
1278 if (status != OK) {
1279 return status;
1280 }
1281
1282 out << "::android::hardware::Parcel _hidl_data;\n";
1283 out << "::android::hardware::Parcel _hidl_reply;\n";
1284 out << "::android::status_t _hidl_err;\n";
1285 out << "::android::hardware::Status _hidl_status;\n\n";
1286
1287 declareCppReaderLocals(
1288 out, method->results(), true /* forResults */);
1289
1290 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001291 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001292 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001293 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1294
Martijn Coenenfff73352017-01-04 16:36:31 +01001295 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001296 // First DFS: write all buffers and resolve pointers for parent
1297 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001298 if (arg->type().isInterface()) {
1299 hasInterfaceArgument = true;
1300 }
Yifan Hong068c5522016-10-31 14:07:25 -07001301 emitCppReaderWriter(
1302 out,
1303 "_hidl_data",
1304 false /* parcelObjIsPointer */,
1305 arg,
1306 false /* reader */,
1307 Type::ErrorMode_Goto,
1308 false /* addPrefixToName */);
1309 }
1310
1311 // Second DFS: resolve references.
1312 for (const auto &arg : method->args()) {
1313 emitCppResolveReferences(
1314 out,
1315 "_hidl_data",
1316 false /* parcelObjIsPointer */,
1317 arg,
1318 false /* reader */,
1319 Type::ErrorMode_Goto,
1320 false /* addPrefixToName */);
1321 }
1322
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001323 if (hasInterfaceArgument) {
1324 // Start binder threadpool to handle incoming transactions
1325 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1326 }
Yifan Hong068c5522016-10-31 14:07:25 -07001327 out << "_hidl_err = remote()->transact("
1328 << method->getSerialId()
1329 << " /* "
1330 << method->name()
1331 << " */, _hidl_data, &_hidl_reply";
1332
1333 if (method->isOneway()) {
1334 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1335 }
1336 out << ");\n";
1337
1338 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1339
1340 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001341 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001342 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1343 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1344
1345
1346 // First DFS: write all buffers and resolve pointers for parent
1347 for (const auto &arg : method->results()) {
1348 emitCppReaderWriter(
1349 out,
1350 "_hidl_reply",
1351 false /* parcelObjIsPointer */,
1352 arg,
1353 true /* reader */,
1354 Type::ErrorMode_Goto,
1355 true /* addPrefixToName */);
1356 }
1357
1358 // Second DFS: resolve references.
1359 for (const auto &arg : method->results()) {
1360 emitCppResolveReferences(
1361 out,
1362 "_hidl_reply",
1363 false /* parcelObjIsPointer */,
1364 arg,
1365 true /* reader */,
1366 Type::ErrorMode_Goto,
1367 true /* addPrefixToName */);
1368 }
1369
1370 if (returnsValue && elidedReturn == nullptr) {
1371 out << "_hidl_cb(";
1372
Yifan Hong7d234ea2017-03-30 15:40:22 -07001373 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001374 if (arg->type().resultNeedsDeref()) {
1375 out << "*";
1376 }
1377 out << "_hidl_out_" << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001378 });
Yifan Hong068c5522016-10-31 14:07:25 -07001379
1380 out << ");\n\n";
1381 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001382 }
1383 status = generateCppInstrumentationCall(
1384 out,
1385 InstrumentationEvent::CLIENT_API_EXIT,
1386 method);
1387 if (status != OK) {
1388 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001389 }
1390
1391 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001392 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1393 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001394 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001395 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1396 } else {
1397 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1398 out << "return ::android::hardware::Return<void>();\n\n";
1399 }
1400
1401 out.unindent();
1402 out << "_hidl_error:\n";
1403 out.indent();
1404 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1405 out << "return ::android::hardware::Return<";
1406 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001407 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001408 } else {
1409 out << "void";
1410 }
1411 out << ">(_hidl_status);\n";
1412
1413 out.unindent();
1414 out << "}\n\n";
1415 return OK;
1416}
1417
Andreas Huber881227d2016-08-02 14:20:21 -07001418status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001419 Formatter &out, const FQName &fqName) const {
1420 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001421
1422 out << klassName
1423 << "::"
1424 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001425 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001426
1427 out.indent();
1428 out.indent();
1429
1430 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001431 << "<"
1432 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001433 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001434 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001435 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001436 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001437 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001438 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001439
Andreas Huber881227d2016-08-02 14:20:21 -07001440 out.unindent();
1441 out.unindent();
1442 out << "}\n\n";
1443
Yifan Hong068c5522016-10-31 14:07:25 -07001444 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1445 return generateProxyMethodSource(out, klassName, method, superInterface);
1446 });
Andreas Huber881227d2016-08-02 14:20:21 -07001447
Yifan Hong068c5522016-10-31 14:07:25 -07001448 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001449}
1450
1451status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001452 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001453 const Interface *iface) const {
1454 const std::string interfaceName = iface->localName();
1455 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001456
Steven Moreland40786312016-08-16 10:29:40 -07001457 out << klassName
1458 << "::"
1459 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001460 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001461
1462 out.indent();
1463 out.indent();
1464
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001465 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001466 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001467 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001468 out << ": "
1469 << gIBaseFqName.getInterfaceStubFqName().cppName()
1470 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001471 }
1472
1473 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001474 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001475 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001476 << "\") { \n";
1477 out.indent();
1478 out << "_hidl_mImpl = _hidl_impl;\n";
Martijn Coenen436dbdf2017-05-03 13:44:29 -07001479 out << "auto prio = ::android::hardware::details::gServicePrioMap.get("
1480 << "_hidl_impl, {SCHED_NORMAL, 0});\n";
1481 out << "mSchedPolicy = prio.sched_policy;\n";
1482 out << "mSchedPriority = prio.prio;\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001483 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001484
1485 out.unindent();
1486 out.unindent();
1487 out << "}\n\n";
1488
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001489 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001490 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001491 // class properly.
1492 out << klassName
1493 << "::"
1494 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001495 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1496 << " const std::string &HidlInstrumentor_package,"
1497 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001498
1499 out.indent();
1500 out.indent();
1501
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001502 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001503 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001504 out.indent();
1505 out << "_hidl_mImpl = _hidl_impl;\n";
1506 out.unindent();
1507
1508 out.unindent();
1509 out.unindent();
1510 out << "}\n\n";
1511 }
1512
Yifan Hongbcffce22017-02-01 15:52:06 -08001513 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1514 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1515 return OK;
1516 }
1517 method->generateCppSignature(out, iface->getStubName());
1518 out << " ";
1519 out.block([&] {
1520 method->cppImpl(IMPL_STUB_IMPL, out);
1521 }).endl();
1522 return OK;
1523 });
Steven Moreland60818632017-02-04 00:33:42 -08001524 if (err != OK) {
1525 return err;
1526 }
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001527
Andreas Huber881227d2016-08-02 14:20:21 -07001528 out << "::android::status_t " << klassName << "::onTransact(\n";
1529
1530 out.indent();
1531 out.indent();
1532
Iliyan Malchev549e2592016-08-10 08:59:12 -07001533 out << "uint32_t _hidl_code,\n"
1534 << "const ::android::hardware::Parcel &_hidl_data,\n"
1535 << "::android::hardware::Parcel *_hidl_reply,\n"
1536 << "uint32_t _hidl_flags,\n"
1537 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001538
1539 out.unindent();
1540
Iliyan Malchev549e2592016-08-10 08:59:12 -07001541 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001542 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001543 out.indent();
1544
Yifan Hong10fe0b52016-10-19 14:20:17 -07001545 for (const auto &tuple : iface->allMethodsFromRoot()) {
1546 const Method *method = tuple.method();
1547 const Interface *superInterface = tuple.interface();
1548 out << "case "
1549 << method->getSerialId()
1550 << " /* "
1551 << method->name()
1552 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001553
Yifan Hong10fe0b52016-10-19 14:20:17 -07001554 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001555
Yifan Hong10fe0b52016-10-19 14:20:17 -07001556 status_t err =
1557 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001558
Yifan Hong10fe0b52016-10-19 14:20:17 -07001559 if (err != OK) {
1560 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001561 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001562
1563 out.unindent();
1564 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001565 }
1566
1567 out << "default:\n{\n";
1568 out.indent();
1569
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001570 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001571
1572 out.indent();
1573 out.indent();
1574
Iliyan Malchev549e2592016-08-10 08:59:12 -07001575 out << "_hidl_code, _hidl_data, _hidl_reply, "
1576 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001577
1578 out.unindent();
1579 out.unindent();
1580
1581 out.unindent();
1582 out << "}\n";
1583
1584 out.unindent();
1585 out << "}\n\n";
1586
Yifan Honga018ed52016-12-13 16:35:08 -08001587 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1588 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1589 out.indent(2, [&] {
1590 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1591 out << "_hidl_reply);\n";
1592 });
1593 });
Andreas Huber881227d2016-08-02 14:20:21 -07001594
Iliyan Malchev549e2592016-08-10 08:59:12 -07001595 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001596
1597 out.unindent();
1598 out << "}\n\n";
1599
1600 return OK;
1601}
1602
1603status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001604 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001605 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1606 method->cppImpl(IMPL_STUB, out);
1607 out << "break;\n";
1608 return OK;
1609 }
1610
Yifan Hongeefe4f22017-01-04 15:32:42 -08001611 out << "if (!_hidl_data.enforceInterface("
1612 << iface->fullName()
1613 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001614
Andreas Huber881227d2016-08-02 14:20:21 -07001615 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001616 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001617 out << "break;\n";
1618 out.unindent();
1619 out << "}\n\n";
1620
Andreas Huber5e44a292016-09-27 14:52:39 -07001621 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001622
Yifan Hongbf459bc2016-08-23 16:50:37 -07001623 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001624 for (const auto &arg : method->args()) {
1625 emitCppReaderWriter(
1626 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001627 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001628 false /* parcelObjIsPointer */,
1629 arg,
1630 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001631 Type::ErrorMode_Break,
1632 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001633 }
1634
Yifan Hongbf459bc2016-08-23 16:50:37 -07001635 // Second DFS: resolve references
1636 for (const auto &arg : method->args()) {
1637 emitCppResolveReferences(
1638 out,
1639 "_hidl_data",
1640 false /* parcelObjIsPointer */,
1641 arg,
1642 true /* reader */,
1643 Type::ErrorMode_Break,
1644 false /* addPrefixToName */);
1645 }
1646
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001647 status_t status = generateCppInstrumentationCall(
1648 out,
1649 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001650 method);
1651 if (status != OK) {
1652 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001653 }
1654
Andreas Huber881227d2016-08-02 14:20:21 -07001655 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001656 const TypedVar *elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -08001657 const std::string callee =
1658 (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL))
1659 ? "this" : "_hidl_mImpl";
Andreas Huber881227d2016-08-02 14:20:21 -07001660
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001661 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001662 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001663 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001664 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001665 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001666 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001667 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001668
Yifan Hong7d234ea2017-03-30 15:40:22 -07001669 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001670 if (arg->type().resultNeedsDeref()) {
1671 out << "*";
1672 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001673 out << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001674 });
Andreas Huber881227d2016-08-02 14:20:21 -07001675
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001676 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001677 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1678 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001679
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001680 elidedReturn->type().emitReaderWriter(
1681 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001682 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001683 "_hidl_reply",
1684 true, /* parcelObjIsPointer */
1685 false, /* isReader */
1686 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001687
Yifan Hongbf459bc2016-08-23 16:50:37 -07001688 emitCppResolveReferences(
1689 out,
1690 "_hidl_reply",
1691 true /* parcelObjIsPointer */,
1692 elidedReturn,
1693 false /* reader */,
1694 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001695 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001696
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001697 status_t status = generateCppInstrumentationCall(
1698 out,
1699 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001700 method);
1701 if (status != OK) {
1702 return status;
1703 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001704
Iliyan Malchev549e2592016-08-10 08:59:12 -07001705 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001706 } else {
1707 if (returnsValue) {
1708 out << "bool _hidl_callbackCalled = false;\n\n";
1709 }
Andreas Huber881227d2016-08-02 14:20:21 -07001710
Yifan Hongcd2ae452017-01-31 14:33:40 -08001711 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001712
Yifan Hong7d234ea2017-03-30 15:40:22 -07001713 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001714 if (arg->type().resultNeedsDeref()) {
1715 out << "*";
1716 }
1717
1718 out << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001719 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001720
1721 if (returnsValue) {
Yifan Hong7d234ea2017-03-30 15:40:22 -07001722 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001723 out << ", ";
1724 }
1725
1726 out << "[&](";
1727
Yifan Hong7d234ea2017-03-30 15:40:22 -07001728 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001729 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001730 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001731
1732 out << ") {\n";
1733 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001734 out << "if (_hidl_callbackCalled) {\n";
1735 out.indent();
1736 out << "LOG_ALWAYS_FATAL(\""
1737 << method->name()
1738 << ": _hidl_cb called a second time, but must be called once.\");\n";
1739 out.unindent();
1740 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001741 out << "_hidl_callbackCalled = true;\n\n";
1742
Yifan Hong859e53f2016-11-14 19:08:24 -08001743 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1744 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001745
Yifan Hongbf459bc2016-08-23 16:50:37 -07001746 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001747 for (const auto &arg : method->results()) {
1748 emitCppReaderWriter(
1749 out,
1750 "_hidl_reply",
1751 true /* parcelObjIsPointer */,
1752 arg,
1753 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001754 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001755 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001756 }
1757
Yifan Hongbf459bc2016-08-23 16:50:37 -07001758 // Second DFS: resolve references
1759 for (const auto &arg : method->results()) {
1760 emitCppResolveReferences(
1761 out,
1762 "_hidl_reply",
1763 true /* parcelObjIsPointer */,
1764 arg,
1765 false /* reader */,
1766 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001767 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001768 }
1769
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001770 status_t status = generateCppInstrumentationCall(
1771 out,
1772 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001773 method);
1774 if (status != OK) {
1775 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001776 }
1777
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001778 out << "_hidl_cb(*_hidl_reply);\n";
1779
1780 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001781 out << "});\n\n";
1782 } else {
1783 out << ");\n\n";
1784 status_t status = generateCppInstrumentationCall(
1785 out,
1786 InstrumentationEvent::SERVER_API_EXIT,
1787 method);
1788 if (status != OK) {
1789 return status;
1790 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001791 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001792
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001793 if (returnsValue) {
1794 out << "if (!_hidl_callbackCalled) {\n";
1795 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001796 out << "LOG_ALWAYS_FATAL(\""
1797 << method->name()
1798 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001799 out.unindent();
1800 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001801 } else {
1802 out << "::android::hardware::writeToParcel("
1803 << "::android::hardware::Status::ok(), "
1804 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001805 }
Andreas Huber881227d2016-08-02 14:20:21 -07001806 }
1807
1808 out << "break;\n";
1809
1810 return OK;
1811}
1812
Steven Moreland69e7c702016-09-09 11:16:32 -07001813status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1814 std::string ifaceName;
1815 if (!AST::isInterface(&ifaceName)) {
1816 // types.hal does not get a stub header.
1817 return OK;
1818 }
1819
1820 const Interface *iface = mRootScope->getInterface();
1821
Yifan Hongeefe4f22017-01-04 15:32:42 -08001822 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001823
1824 bool supportOneway = iface->hasOnewayMethods();
1825
1826 std::string path = outputPath;
1827 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1828 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1829 path.append(klassName);
1830 path.append(".h");
1831
1832 CHECK(Coordinator::MakeParentHierarchy(path));
1833 FILE *file = fopen(path.c_str(), "w");
1834
1835 if (file == NULL) {
1836 return -errno;
1837 }
1838
1839 Formatter out(file);
1840
1841 const std::string guard = makeHeaderGuard(klassName);
1842
1843 out << "#ifndef " << guard << "\n";
1844 out << "#define " << guard << "\n\n";
1845
1846 std::vector<std::string> packageComponents;
1847 getPackageAndVersionComponents(
1848 &packageComponents, false /* cpp_compatible */);
1849
Yifan Hongb0949432016-12-15 15:32:24 -08001850 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001851 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001852
1853 generateCppPackageInclude(out, mPackage, ifaceName);
1854 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001855
Yifan Hong7a118f52016-12-07 11:21:15 -08001856 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001857 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001858 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001859 }
1860
1861 enterLeaveNamespace(out, true /* enter */);
1862 out << "\n";
1863
1864 out << "struct "
1865 << klassName
1866 << " : " << ifaceName
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001867 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001868
1869 out.indent();
1870 out << "explicit "
1871 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001872 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001873 << ifaceName
1874 << "> impl);\n";
1875
Yifan Hong068c5522016-10-31 14:07:25 -07001876 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1877 return generatePassthroughMethod(out, method);
1878 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001879
1880 if (err != OK) {
1881 return err;
1882 }
1883
1884 out.unindent();
1885 out << "private:\n";
1886 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001887 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001888
1889 if (supportOneway) {
Yifan Hongef91d362017-03-20 17:18:13 -07001890 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001891
1892 out << "\n";
1893
1894 out << "::android::hardware::Return<void> addOnewayTask("
1895 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001896 }
1897
1898 out.unindent();
1899
1900 out << "};\n\n";
1901
1902 enterLeaveNamespace(out, false /* enter */);
1903
1904 out << "\n#endif // " << guard << "\n";
1905
1906 return OK;
1907}
1908
Yifan Hongfe95aa22016-10-19 17:26:45 -07001909status_t AST::generateInterfaceSource(Formatter &out) const {
1910 const Interface *iface = mRootScope->getInterface();
1911
Yifan Hong2d7126b2016-10-20 15:12:57 -07001912 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001913 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001914
Steven Morelandd4b068a2017-03-20 06:30:51 -07001915 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1916 bool reserved = method->isHidlReserved();
1917
1918 if (!reserved) {
1919 out << "// no default implementation for: ";
1920 }
1921 method->generateCppSignature(out, iface->localName());
1922 if (reserved) {
1923 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001924 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001925 }).endl();
1926 }
1927
1928 out << "\n";
1929
1930 return OK;
1931 });
1932 if (err != OK) {
1933 return err;
1934 }
1935
Yifan Hong3d746092016-12-07 14:26:33 -08001936 for (const Interface *superType : iface->typeChain()) {
Yifan Hong7783bb02017-03-29 03:39:09 -07001937 out << "// static \n::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -08001938 << childTypeResult
Yifan Hong7783bb02017-03-29 03:39:09 -07001939 << "> "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001940 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001941 << "::castFrom("
1942 << superType->getCppArgumentType()
Yifan Hong7783bb02017-03-29 03:39:09 -07001943 << " parent, bool "
1944 << (iface == superType ? "/* emitError */" : "emitError")
1945 << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001946 out.indent();
1947 if (iface == superType) {
1948 out << "return parent;\n";
1949 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001950 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001951 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001952 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001953 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001954 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001955 << ">(\n";
1956 out.indent();
1957 out.indent();
1958 out << "parent, \""
1959 << iface->fqName().string()
Yifan Hong7783bb02017-03-29 03:39:09 -07001960 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001961 out.unindent();
1962 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001963 }
Yifan Hong3d746092016-12-07 14:26:33 -08001964 out.unindent();
1965 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001966 }
1967
1968 return OK;
1969}
1970
Steven Moreland69e7c702016-09-09 11:16:32 -07001971status_t AST::generatePassthroughSource(Formatter &out) const {
1972 const Interface *iface = mRootScope->getInterface();
1973
Yifan Hongeefe4f22017-01-04 15:32:42 -08001974 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001975
1976 out << klassName
1977 << "::"
1978 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001979 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001980 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001981 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001982 << mPackage.string()
1983 << "\", \""
1984 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001985 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001986 if (iface->hasOnewayMethods()) {
1987 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001988 out.indent([&] {
Yifan Hongf01dad42017-03-20 19:03:11 -07001989 out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001990 });
1991 }
1992 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001993
1994 if (iface->hasOnewayMethods()) {
1995 out << "::android::hardware::Return<void> "
1996 << klassName
1997 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1998 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001999 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07002000 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07002001 out << "return ::android::hardware::Status::fromExceptionCode(\n";
2002 out.indent();
2003 out.indent();
2004 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
2005 out.unindent();
2006 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07002007 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07002008 out << "}\n";
2009
Steven Morelandd366c262016-10-11 15:29:10 -07002010 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07002011
2012 out.unindent();
2013 out << "}\n\n";
2014
2015
2016 }
2017
2018 return OK;
2019}
2020
Martijn Coenen7b295242016-11-04 16:52:56 +01002021status_t AST::generateCppAtraceCall(Formatter &out,
2022 InstrumentationEvent event,
2023 const Method *method) const {
2024 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08002025 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01002026 switch (event) {
2027 case SERVER_API_ENTRY:
2028 {
2029 out << "atrace_begin(ATRACE_TAG_HAL, \""
2030 << baseString + "::server\");\n";
2031 break;
2032 }
2033 case CLIENT_API_ENTRY:
2034 {
2035 out << "atrace_begin(ATRACE_TAG_HAL, \""
2036 << baseString + "::client\");\n";
2037 break;
2038 }
2039 case PASSTHROUGH_ENTRY:
2040 {
2041 out << "atrace_begin(ATRACE_TAG_HAL, \""
2042 << baseString + "::passthrough\");\n";
2043 break;
2044 }
2045 case SERVER_API_EXIT:
2046 case CLIENT_API_EXIT:
2047 case PASSTHROUGH_EXIT:
2048 {
2049 out << "atrace_end(ATRACE_TAG_HAL);\n";
2050 break;
2051 }
2052 default:
2053 {
2054 LOG(ERROR) << "Unsupported instrumentation event: " << event;
2055 return UNKNOWN_ERROR;
2056 }
2057 }
2058
2059 return OK;
2060}
2061
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002062status_t AST::generateCppInstrumentationCall(
2063 Formatter &out,
2064 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07002065 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01002066 status_t err = generateCppAtraceCall(out, event, method);
2067 if (err != OK) {
2068 return err;
2069 }
2070
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002071 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
2072 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002073 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002074 std::string event_str = "";
2075 switch (event) {
2076 case SERVER_API_ENTRY:
2077 {
2078 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
2079 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002080 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002081 << (arg->type().resultNeedsDeref() ? "" : "&")
2082 << arg->name()
2083 << ");\n";
2084 }
2085 break;
2086 }
2087 case SERVER_API_EXIT:
2088 {
2089 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07002090 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002091 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07002092 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002093 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002094 }
2095 break;
2096 }
2097 case CLIENT_API_ENTRY:
2098 {
2099 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2100 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002101 out << "_hidl_args.push_back((void *)&"
2102 << arg->name()
2103 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002104 }
2105 break;
2106 }
2107 case CLIENT_API_EXIT:
2108 {
2109 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2110 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002111 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002112 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002113 << "_hidl_out_"
2114 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002115 << ");\n";
2116 }
2117 break;
2118 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002119 case PASSTHROUGH_ENTRY:
2120 {
2121 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2122 for (const auto &arg : method->args()) {
2123 out << "_hidl_args.push_back((void *)&"
2124 << arg->name()
2125 << ");\n";
2126 }
2127 break;
2128 }
2129 case PASSTHROUGH_EXIT:
2130 {
2131 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002132 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002133 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002134 << arg->name()
2135 << ");\n";
2136 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002137 break;
2138 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002139 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002140 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002141 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002142 return UNKNOWN_ERROR;
2143 }
2144 }
2145
Steven Moreland031ccf12016-10-31 15:54:38 -07002146 const Interface *iface = mRootScope->getInterface();
2147
Steven Moreland1ab31442016-11-03 18:37:51 -07002148 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002149 out.indent();
2150 out << "callback("
2151 << event_str
2152 << ", \""
2153 << mPackage.package()
2154 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002155 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002156 << "\", \""
2157 << iface->localName()
2158 << "\", \""
2159 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002160 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002161 out.unindent();
2162 out << "}\n";
2163 out.unindent();
2164 out << "}\n\n";
2165
2166 return OK;
2167}
2168
Andreas Huber881227d2016-08-02 14:20:21 -07002169} // namespace android