blob: b675ac0862bfb3ebd00696e95df32b58452cd278 [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 Huber6755e9d2017-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 {
37 status_t err = generateInterfaceHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070038
39 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070040 err = generateStubHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070041 }
42
43 if (err == OK) {
Steven Moreland40786312016-08-16 10:29:40 -070044 err = generateHwBinderHeader(outputPath);
45 }
46
47 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070048 err = generateProxyHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070049 }
50
51 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070052 err = generateAllSource(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070053 }
54
Steven Moreland69e7c702016-09-09 11:16:32 -070055 if (err == OK) {
Yifan Hong7a118f52016-12-07 11:21:15 -080056 err = generatePassthroughHeader(outputPath);
Steven Moreland69e7c702016-09-09 11:16:32 -070057 }
58
Andreas Huber881227d2016-08-02 14:20:21 -070059 return err;
60}
61
Andreas Huber737080b2016-08-02 15:38:04 -070062void AST::getPackageComponents(
63 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070064 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070065}
66
67void AST::getPackageAndVersionComponents(
68 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070069 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070070}
71
Steven Moreland5708edf2016-11-04 15:33:31 +000072std::string AST::makeHeaderGuard(const std::string &baseName,
73 bool indicateGenerated) const {
74 std::string guard;
Andreas Huber881227d2016-08-02 14:20:21 -070075
Steven Moreland5708edf2016-11-04 15:33:31 +000076 if (indicateGenerated) {
77 guard += "HIDL_GENERATED_";
78 }
79
80 guard += StringHelper::Uppercase(mPackage.tokenName());
Andreas Huber881227d2016-08-02 14:20:21 -070081 guard += "_";
Steven Moreland5708edf2016-11-04 15:33:31 +000082 guard += StringHelper::Uppercase(baseName);
83 guard += "_H";
Andreas Huber881227d2016-08-02 14:20:21 -070084
85 return guard;
86}
87
Steven Morelandee88eed2016-10-31 17:49:00 -070088// static
89void AST::generateCppPackageInclude(
90 Formatter &out,
91 const FQName &package,
92 const std::string &klass) {
93
94 out << "#include <";
95
96 std::vector<std::string> components;
97 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
98
99 for (const auto &component : components) {
100 out << component << "/";
101 }
102
103 out << klass
104 << ".h>\n";
105}
106
Andreas Huber881227d2016-08-02 14:20:21 -0700107void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
108 std::vector<std::string> packageComponents;
109 getPackageAndVersionComponents(
110 &packageComponents, true /* cpp_compatible */);
111
112 if (enter) {
113 for (const auto &component : packageComponents) {
114 out << "namespace " << component << " {\n";
115 }
Andreas Huber0e00de42016-08-03 09:56:02 -0700116
Andreas Huber2831d512016-08-15 09:33:47 -0700117 out.setNamespace(mPackage.cppNamespace() + "::");
Andreas Huber881227d2016-08-02 14:20:21 -0700118 } else {
Andreas Huber0e00de42016-08-03 09:56:02 -0700119 out.setNamespace(std::string());
120
Andreas Huber881227d2016-08-02 14:20:21 -0700121 for (auto it = packageComponents.rbegin();
122 it != packageComponents.rend();
123 ++it) {
124 out << "} // namespace " << *it << "\n";
125 }
126 }
127}
128
Steven Moreland038903b2017-03-30 12:11:24 -0700129static void declareGetService(Formatter &out, const std::string &interfaceName, bool isTry) {
130 const std::string functionName = isTry ? "tryGetService" : "getService";
131
132 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800133 << "const std::string &serviceName=\"default\", bool getStub=false);\n";
Steven Moreland038903b2017-03-30 12:11:24 -0700134 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800135 << "const char serviceName[], bool getStub=false)"
136 << " { std::string str(serviceName ? serviceName : \"\");"
Steven Moreland038903b2017-03-30 12:11:24 -0700137 << " return " << functionName << "(str, getStub); }\n";
138 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800139 << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
140 // without c_str the std::string constructor is ambiguous
141 << " { std::string str(serviceName.c_str());"
Steven Moreland038903b2017-03-30 12:11:24 -0700142 << " return " << functionName << "(str, getStub); }\n";
143 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
144 << "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
145}
146
147static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
148 declareGetService(out, interfaceName, true /* isTry */);
149 declareGetService(out, interfaceName, false /* isTry */);
150
Steven Moreland90831502017-03-27 12:08:40 -0700151 out << "__attribute__ ((warn_unused_result))"
152 << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800153 out << "static bool registerForNotifications(\n";
154 out.indent(2, [&] {
155 out << "const std::string &serviceName,\n"
156 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
157 << "&notification);\n";
158 });
159
160}
161
Steven Moreland038903b2017-03-30 12:11:24 -0700162static void implementGetService(Formatter &out,
163 const FQName &fqName,
164 bool isTry) {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800165
166 const std::string interfaceName = fqName.getInterfaceName();
Steven Moreland038903b2017-03-30 12:11:24 -0700167 const std::string functionName = isTry ? "tryGetService" : "getService";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800168
169 out << "// static\n"
Steven Moreland038903b2017-03-30 12:11:24 -0700170 << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
Yifan Hong31f07ff2017-03-21 18:56:35 +0000171 << "const std::string &serviceName, const bool getStub) ";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800172 out.block([&] {
Steven Morelandbcf51802017-04-06 09:17:44 -0700173 out << "using ::android::hardware::defaultServiceManager;\n";
174 out << "using ::android::hardware::details::waitForHwService;\n";
175 out << "using ::android::hardware::getPassthroughServiceManager;\n";
176 out << "using ::android::hardware::Return;\n";
177 out << "using ::android::sp;\n";
178 out << "using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;\n\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000179
Steven Morelandbcf51802017-04-06 09:17:44 -0700180 out << "sp<" << interfaceName << "> iface = nullptr;\n";
181
182 out.endl();
183
184 out << "const sp<::android::hidl::manager::V1_0::IServiceManager> sm"
185 << " = defaultServiceManager();\n";
186
187 out.sIf("sm == nullptr", [&] {
188 // hwbinder is not available on this device, so future tries
189 // would also be null. I can only return nullptr.
190 out << "ALOGE(\"getService: defaultServiceManager() is null\");\n"
191 << "return nullptr;\n";
192 }).endl().endl();
193
194 out << "Return<Transport> transportRet = sm->getTransport("
195 << interfaceName << "::descriptor, serviceName);\n\n";
196
197 out.sIf("!transportRet.isOk()", [&] {
198 out << "ALOGE(\"getService: defaultServiceManager()->getTransport returns %s\", "
199 << "transportRet.description().c_str());\n";
200 out << "return nullptr;\n";
201 });
202
203 out.endl();
204
205 out << "Transport transport = transportRet;\n";
206 out << "const bool vintfHwbinder = (transport == Transport::HWBINDER);\n"
207 << "const bool vintfPassthru = (transport == Transport::PASSTHROUGH);\n"
208 << "const bool vintfEmpty = (transport == Transport::EMPTY);\n\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000209
210 // if (getStub) {
211 // getPassthroughServiceManager()->get only once.
212 // } else {
213 // if (vintfHwbinder) {
214 // while (no alive service) {
215 // waitForHwService
216 // defaultServiceManager()->get
217 // }
218 // } else if (vintfEmpty) {
219 // defaultServiceManager()->get only once.
220 // getPassthroughServiceManager()->get only once.
221 // } else if (vintfPassthru) {
222 // getPassthroughServiceManager()->get only once.
223 // }
224 // }
225
Yifan Hong223fd472017-03-23 17:17:57 +0000226 out << "bool tried = false;\n";
227 out.sWhile("!getStub && (vintfHwbinder || (vintfEmpty && !tried))", [&] {
Yifan Hong31f07ff2017-03-21 18:56:35 +0000228
229 out.sIf("tried", [&] {
230 // sleep only after the first trial.
231 out << "ALOGI(\"getService: retrying in 1s...\");\n"
232 << "sleep(1);\n";
233 }).endl();
234
Yifan Hong223fd472017-03-23 17:17:57 +0000235 out << "tried = true;\n";
236
Yifan Hong31f07ff2017-03-21 18:56:35 +0000237
Steven Moreland038903b2017-03-30 12:11:24 -0700238 if (!isTry) {
239 out.sIf("vintfHwbinder", [&] {
Steven Morelandbcf51802017-04-06 09:17:44 -0700240 out << "waitForHwService("
241 << interfaceName << "::descriptor, serviceName);\n";
Steven Moreland038903b2017-03-30 12:11:24 -0700242 }).endl();
243 }
Yifan Hong31f07ff2017-03-21 18:56:35 +0000244
Steven Morelandbcf51802017-04-06 09:17:44 -0700245 out << "Return<sp<" << gIBaseFqName.cppName() << ">> ret = \n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000246 out.indent(2, [&] {
247 out << "sm->get(" << interfaceName << "::descriptor, serviceName);\n";
248 });
249
250 out.sIf("!ret.isOk()", [&] {
Steven Moreland42394ce2017-03-27 17:03:04 -0700251 // hwservicemanager fails, may be security issue
Yifan Hong31f07ff2017-03-21 18:56:35 +0000252 out << "ALOGE(\"getService: defaultServiceManager()->get returns %s\", "
253 << "ret.description().c_str());\n"
Steven Moreland42394ce2017-03-27 17:03:04 -0700254 << "break;\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000255 }).endl();
256
Steven Morelandbcf51802017-04-06 09:17:44 -0700257 out << "sp<" << gIBaseFqName.cppName() << "> base = ret;\n";
Yifan Hong200209c2017-03-29 03:39:09 -0700258 out.sIf("base == nullptr", [&] {
259 // race condition. hwservicemanager drops the service
260 // from waitForHwService to here
Steven Morelanddff644c2017-03-24 10:59:01 -0700261 out << "ALOGW(\"getService: found null hwbinder interface\");\n"
Yifan Hong9c74a5b2017-04-04 13:27:25 -0700262 << (isTry ? "break" : "continue")
263 << ";\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000264 }).endl();
Steven Morelandbcf51802017-04-06 09:17:44 -0700265 out << "Return<sp<" << interfaceName
Yifan Hong200209c2017-03-29 03:39:09 -0700266 << ">> castRet = " << interfaceName << "::castFrom(base, true /* emitError */);\n";
267 out.sIf("!castRet.isOk()", [&] {
268 out.sIf("castRet.isDeadObject()", [&] {
269 // service is dead (castFrom cannot call interfaceChain)
270 out << "ALOGW(\"getService: found dead hwbinder service\");\n"
Yifan Hong9c74a5b2017-04-04 13:27:25 -0700271 << (isTry ? "break" : "continue")
272 << ";\n";
Yifan Hong200209c2017-03-29 03:39:09 -0700273 }).sElse([&] {
274 out << "ALOGW(\"getService: cannot call into hwbinder service: %s"
275 << "; No permission? Check for selinux denials.\", "
276 << "castRet.description().c_str());\n"
277 << "break;\n";
278 }).endl();
279 }).endl();
280 out << "iface = castRet;\n";
281 out.sIf("iface == nullptr", [&] {
282 // returned service isn't of correct type; this is a bug
283 // to hwservicemanager or to the service itself (interfaceChain
284 // is not consistent).
285 out << "ALOGW(\"getService: received incompatible service; bug in hwservicemanager?\");\n"
286 << "break;\n";
287 }).endl();
Yifan Hong31f07ff2017-03-21 18:56:35 +0000288
289 out << "return iface;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800290 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800291
Yifan Hong31f07ff2017-03-21 18:56:35 +0000292 out.sIf("getStub || vintfPassthru || vintfEmpty", [&] {
Steven Morelandbcf51802017-04-06 09:17:44 -0700293 out << "const sp<::android::hidl::manager::V1_0::IServiceManager> pm"
294 << " = getPassthroughServiceManager();\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000295
296 out.sIf("pm != nullptr", [&] () {
Steven Morelandbcf51802017-04-06 09:17:44 -0700297 out << "Return<sp<" << gIBaseFqName.cppName() << ">> ret = \n";
Steven Morelandf10af872017-01-25 16:01:56 +0000298 out.indent(2, [&] {
299 out << "pm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
Steven Moreland2c2dea82017-01-18 17:24:17 -0800300 });
Steven Morelandf10af872017-01-25 16:01:56 +0000301 out.sIf("ret.isOk()", [&] {
Steven Morelandbcf51802017-04-06 09:17:44 -0700302 out << "sp<" << gIBaseFqName.cppName()
Steven Morelandf10af872017-01-25 16:01:56 +0000303 << "> baseInterface = ret;\n";
304 out.sIf("baseInterface != nullptr", [&]() {
305 out << "iface = new " << fqName.getInterfacePassthroughName()
306 << "(" << interfaceName << "::castFrom(baseInterface));\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000307 }).endl();
Steven Morelandf10af872017-01-25 16:01:56 +0000308 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800309 }).endl();
310 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800311
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800312 out << "return iface;\n";
313 }).endl().endl();
Steven Moreland038903b2017-03-30 12:11:24 -0700314}
315
316static void implementServiceManagerInteractions(Formatter &out,
317 const FQName &fqName, const std::string &package) {
318
319 const std::string interfaceName = fqName.getInterfaceName();
320
321 implementGetService(out, fqName, true /* isTry */);
322 implementGetService(out, fqName, false /* isTry */);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800323
Yifan Hongeefe4f22017-01-04 15:32:42 -0800324 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800325 << "const std::string &serviceName) ";
326 out.block([&] {
Steven Moreland58b478b2017-04-09 10:54:50 -0700327 out << "::android::hardware::details::onRegistration(\""
328 << fqName.getPackageAndVersion().string() << "\", \""
329 << interfaceName
330 << "\", serviceName);\n\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800331 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
332 out.indent(2, [&] {
333 out << "= ::android::hardware::defaultServiceManager();\n";
334 });
335 out.sIf("sm == nullptr", [&] {
336 out << "return ::android::INVALID_OPERATION;\n";
337 }).endl();
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100338 out << "::android::hardware::Return<bool> ret = "
339 << "sm->add(serviceName.c_str(), this);\n"
340 << "return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800341 }).endl().endl();
342
Yifan Hongeefe4f22017-01-04 15:32:42 -0800343 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800344 out.indent(2, [&] {
345 out << "const std::string &serviceName,\n"
346 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
347 << "&notification) ";
348 });
349 out.block([&] {
350 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
351 out.indent(2, [&] {
352 out << "= ::android::hardware::defaultServiceManager();\n";
353 });
354 out.sIf("sm == nullptr", [&] {
355 out << "return false;\n";
356 }).endl();
357 out << "::android::hardware::Return<bool> success =\n";
358 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800359 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800360 out.indent(2, [&] {
361 out << "serviceName, notification);\n";
362 });
363 });
364 out << "return success.isOk() && success;\n";
365 }).endl().endl();
366}
367
Andreas Huberb82318c2016-08-02 14:45:54 -0700368status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700369
Andreas Huberb82318c2016-08-02 14:45:54 -0700370 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700371 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700372 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700373
374 std::string ifaceName;
375 bool isInterface = true;
376 if (!AST::isInterface(&ifaceName)) {
377 ifaceName = "types";
378 isInterface = false;
379 }
380 path.append(ifaceName);
381 path.append(".h");
382
Andreas Huberd2943e12016-08-05 11:59:31 -0700383 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700384 FILE *file = fopen(path.c_str(), "w");
385
386 if (file == NULL) {
387 return -errno;
388 }
389
390 Formatter out(file);
391
392 const std::string guard = makeHeaderGuard(ifaceName);
393
394 out << "#ifndef " << guard << "\n";
395 out << "#define " << guard << "\n\n";
396
Andreas Huber737080b2016-08-02 15:38:04 -0700397 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700398 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700399 }
400
401 if (!mImportedNames.empty()) {
402 out << "\n";
403 }
404
Steven Moreland0693f312016-11-09 15:06:14 -0800405 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800406 if (isIBase()) {
407 out << "// skipped #include IServiceNotification.h\n\n";
408 } else {
409 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
410 }
Steven Moreland0693f312016-11-09 15:06:14 -0800411 }
412
Yifan Hongc8934042016-11-17 17:10:52 -0800413 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700414 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700415
416 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200417 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700418 }
419
Martijn Coenenaf712c02016-11-16 15:26:27 +0100420 out << "#include <utils/NativeHandle.h>\n";
421 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700422
423 enterLeaveNamespace(out, true /* enter */);
424 out << "\n";
425
426 if (isInterface) {
427 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700428 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700429
430 const Interface *iface = mRootScope->getInterface();
431 const Interface *superType = iface->superType();
432
Steven Moreland40786312016-08-16 10:29:40 -0700433 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800434 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700435 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000436 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700437 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700438 }
439
440 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700441
442 out.indent();
443
Andreas Huber881227d2016-08-02 14:20:21 -0700444 }
445
446 status_t err = emitTypeDeclarations(out);
447
448 if (err != OK) {
449 return err;
450 }
451
452 if (isInterface) {
453 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800454
Yifan Hongc8934042016-11-17 17:10:52 -0800455 out << "virtual bool isRemote() const ";
456 if (!isIBase()) {
457 out << "override ";
458 }
459 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800460
Andreas Huber881227d2016-08-02 14:20:21 -0700461 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700462 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700463
Andreas Huber881227d2016-08-02 14:20:21 -0700464 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800465 const TypedVar *elidedReturn = method->canElideCallback();
466
467 if (elidedReturn == nullptr && returnsValue) {
468 out << "using "
469 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700470 << "_cb = std::function<void(";
471 method->emitCppResultSignature(out, true /* specify namespaces */);
472 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800473 }
Andreas Huber881227d2016-08-02 14:20:21 -0700474
Andreas Huber3599d922016-08-09 10:42:57 -0700475 method->dumpAnnotations(out);
476
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700477 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700478 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700479 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700480 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700481 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700482 }
483
484 out << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700485 << "(";
486 method->emitCppArgSignature(out, true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700487
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700488 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700489 if (!method->args().empty()) {
490 out << ", ";
491 }
492
Steven Moreland67f67b42016-09-29 08:59:02 -0700493 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700494 }
495
Yifan Hong10fe0b52016-10-19 14:20:17 -0700496 out << ")";
497 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800498 if (!isIBase()) {
499 out << " override";
500 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700501 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700502 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700503 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700504 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700505 }
Steven Moreland40786312016-08-16 10:29:40 -0700506
Yifan Hong3d746092016-12-07 14:26:33 -0800507 out << "// cast static functions\n";
508 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700509
Yifan Hong3d746092016-12-07 14:26:33 -0800510 for (const Interface *superType : iface->typeChain()) {
Yifan Hong200209c2017-03-29 03:39:09 -0700511 out << "static ::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -0800512 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -0700513 << "> castFrom("
Yifan Hong3d746092016-12-07 14:26:33 -0800514 << superType->getCppArgumentType()
515 << " parent"
Yifan Hong200209c2017-03-29 03:39:09 -0700516 << ", bool emitError = false);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700517 }
518
Steven Morelandd39133b2016-11-11 12:30:08 -0800519 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700520
Yifan Hongc8934042016-11-17 17:10:52 -0800521 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800522 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800523 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800524 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800525 }
Andreas Huber881227d2016-08-02 14:20:21 -0700526 }
527
528 if (isInterface) {
529 out.unindent();
530
Andreas Hubere3f769a2016-10-10 10:54:44 -0700531 out << "};\n\n";
532 }
533
534 err = mRootScope->emitGlobalTypeDeclarations(out);
535
536 if (err != OK) {
537 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700538 }
539
540 out << "\n";
541 enterLeaveNamespace(out, false /* enter */);
542
543 out << "\n#endif // " << guard << "\n";
544
545 return OK;
546}
547
Steven Moreland40786312016-08-16 10:29:40 -0700548status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
549 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800550 bool isInterface = AST::isInterface(&ifaceName);
551 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800552 std::string klassName{};
553
554 if(isInterface) {
555 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800556 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800557 } else {
558 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700559 }
560
Steven Moreland40786312016-08-16 10:29:40 -0700561 std::string path = outputPath;
562 path.append(mCoordinator->convertPackageRootToPath(mPackage));
563 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
564 path.append(klassName + ".h");
565
Yifan Hong244e82d2016-11-11 11:13:57 -0800566 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700567
568 if (file == NULL) {
569 return -errno;
570 }
571
572 Formatter out(file);
573
574 const std::string guard = makeHeaderGuard(klassName);
575
576 out << "#ifndef " << guard << "\n";
577 out << "#define " << guard << "\n\n";
578
Yifan Hong244e82d2016-11-11 11:13:57 -0800579 if (isInterface) {
580 generateCppPackageInclude(out, mPackage, ifaceName);
581 } else {
582 generateCppPackageInclude(out, mPackage, "types");
583 }
Steven Moreland40786312016-08-16 10:29:40 -0700584
Steven Morelandee88eed2016-10-31 17:49:00 -0700585 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700586
587 for (const auto &item : mImportedNames) {
588 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800589 generateCppPackageInclude(out, item, "hwtypes");
590 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800591 generateCppPackageInclude(out, item, item.getInterfaceStubName());
592 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700593 }
Steven Moreland40786312016-08-16 10:29:40 -0700594 }
595
596 out << "\n";
597
Martijn Coenen93915102016-09-01 01:35:52 +0200598 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700599 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100600 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700601
602 out << "\n";
603
604 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700605
Yifan Hong244e82d2016-11-11 11:13:57 -0800606 status_t err = mRootScope->emitGlobalHwDeclarations(out);
607 if (err != OK) {
608 return err;
609 }
Steven Moreland40786312016-08-16 10:29:40 -0700610
611 enterLeaveNamespace(out, false /* enter */);
612
613 out << "\n#endif // " << guard << "\n";
614
615 return OK;
616}
617
Andreas Huber881227d2016-08-02 14:20:21 -0700618status_t AST::emitTypeDeclarations(Formatter &out) const {
619 return mRootScope->emitTypeDeclarations(out);
620}
621
Yifan Hong7a118f52016-12-07 11:21:15 -0800622static void wrapPassthroughArg(Formatter &out,
623 const TypedVar *arg, bool addPrefixToName,
624 std::function<void(void)> handleError) {
625 if (!arg->type().isInterface()) {
626 return;
627 }
628 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
629 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
630 + arg->name();
631 const Interface &iface = static_cast<const Interface &>(arg->type());
632 out << iface.getCppStackType() << " " << wrappedName << ";\n";
633 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
634 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
635 out << wrappedName
636 << " = "
637 << iface.fqName().cppName()
Yifan Hong341112d2017-04-20 18:12:05 -0700638 << "::castFrom(::android::hardware::details::wrapPassthrough<"
639 << iface.fqName().cppName()
640 << ">("
Yifan Hong7a118f52016-12-07 11:21:15 -0800641 << name << "));\n";
642 out.sIf(wrappedName + " == nullptr", [&] {
643 // Fatal error. Happens when the BsFoo class is not found in the binary
644 // or any dynamic libraries.
645 handleError();
646 }).endl();
647 }).sElse([&] {
648 out << wrappedName << " = " << name << ";\n";
649 }).endl().endl();
650}
651
Steven Moreland69e7c702016-09-09 11:16:32 -0700652status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700653 const Method *method) const {
654 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700655
656 out << " {\n";
657 out.indent();
658
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800659 if (method->isHidlReserved()
660 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
661 method->cppImpl(IMPL_PASSTHROUGH, out);
662 out.unindent();
663 out << "}\n\n";
664 return OK;
665 }
666
Steven Moreland69e7c702016-09-09 11:16:32 -0700667 const bool returnsValue = !method->results().empty();
668 const TypedVar *elidedReturn = method->canElideCallback();
669
Steven Moreland67f67b42016-09-29 08:59:02 -0700670 if (returnsValue && elidedReturn == nullptr) {
671 generateCheckNonNull(out, "_hidl_cb");
672 }
673
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700674 generateCppInstrumentationCall(
675 out,
676 InstrumentationEvent::PASSTHROUGH_ENTRY,
677 method);
678
Yifan Hong7a118f52016-12-07 11:21:15 -0800679
680 for (const auto &arg : method->args()) {
681 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
682 out << "return ::android::hardware::Status::fromExceptionCode(\n";
683 out.indent(2, [&] {
684 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800685 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800686 });
687 });
688 }
689
690 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700691 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700692
693 if (method->isOneway()) {
Steven Morelanda4c565f2017-05-02 12:10:13 -0700694 out << "addOnewayTask([mImpl = this->mImpl, "
695 "mEnableInstrumentation = this->mEnableInstrumentation, "
696 "mInstrumentationCallbacks = this->mInstrumentationCallbacks, "
697 "&_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700698 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800699 out << ", "
700 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
701 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700702 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700703 out << "] {\n";
704 out.indent();
Steven Moreland69e7c702016-09-09 11:16:32 -0700705 }
706
707 out << "mImpl->"
708 << method->name()
709 << "(";
710
Yifan Hong932464e2017-03-30 15:40:22 -0700711 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800712 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700713 });
Steven Moreland69e7c702016-09-09 11:16:32 -0700714 if (returnsValue && elidedReturn == nullptr) {
715 if (!method->args().empty()) {
716 out << ", ";
717 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800718 out << "[&](";
Yifan Hong932464e2017-03-30 15:40:22 -0700719 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800720 out << "const auto &_hidl_out_"
721 << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700722 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800723
724 out << ") {\n";
725 out.indent();
726 status_t status = generateCppInstrumentationCall(
727 out,
728 InstrumentationEvent::PASSTHROUGH_EXIT,
729 method);
730 if (status != OK) {
731 return status;
732 }
733
Yifan Hong7a118f52016-12-07 11:21:15 -0800734 for (const auto &arg : method->results()) {
735 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
736 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
737 out.indent(2, [&] {
738 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800739 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800740 });
741 out << "return;\n";
742 });
743 }
744
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800745 out << "_hidl_cb(";
Yifan Hong932464e2017-03-30 15:40:22 -0700746 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800747 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
748 << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700749 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800750 out << ");\n";
751 out.unindent();
752 out << "});\n\n";
753 } else {
754 out << ");\n\n";
755 if (elidedReturn != nullptr) {
756 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800757 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800758 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000759 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800760 }
761 status_t status = generateCppInstrumentationCall(
762 out,
763 InstrumentationEvent::PASSTHROUGH_EXIT,
764 method);
765 if (status != OK) {
766 return status;
767 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700768 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700769
770 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700771 out.unindent();
772 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700773 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700774
775 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700776
777 out.unindent();
778 out << "}\n";
779
780 return OK;
781}
782
Yifan Hong068c5522016-10-31 14:07:25 -0700783status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700784
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700785 const Interface *iface = mRootScope->getInterface();
786
Yifan Hong10fe0b52016-10-19 14:20:17 -0700787 const Interface *prevIterface = nullptr;
788 for (const auto &tuple : iface->allMethodsFromRoot()) {
789 const Method *method = tuple.method();
790 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700791
Yifan Hong10fe0b52016-10-19 14:20:17 -0700792 if(prevIterface != superInterface) {
793 if (prevIterface != nullptr) {
794 out << "\n";
795 }
796 out << "// Methods from "
797 << superInterface->fullName()
798 << " follow.\n";
799 prevIterface = superInterface;
800 }
Yifan Hong068c5522016-10-31 14:07:25 -0700801 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700802
Yifan Hong10fe0b52016-10-19 14:20:17 -0700803 if (err != OK) {
804 return err;
805 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700806 }
807
Yifan Hong10fe0b52016-10-19 14:20:17 -0700808 out << "\n";
809
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700810 return OK;
811}
812
Andreas Huberb82318c2016-08-02 14:45:54 -0700813status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700814 std::string ifaceName;
815 if (!AST::isInterface(&ifaceName)) {
816 // types.hal does not get a stub header.
817 return OK;
818 }
819
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700820 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800821 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700822
Andreas Huberb82318c2016-08-02 14:45:54 -0700823 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700824 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700825 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700826 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700827 path.append(".h");
828
Andreas Huberd2943e12016-08-05 11:59:31 -0700829 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700830 FILE *file = fopen(path.c_str(), "w");
831
832 if (file == NULL) {
833 return -errno;
834 }
835
836 Formatter out(file);
837
Steven Moreland40786312016-08-16 10:29:40 -0700838 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700839
840 out << "#ifndef " << guard << "\n";
841 out << "#define " << guard << "\n\n";
842
Yifan Hongeefe4f22017-01-04 15:32:42 -0800843 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700844 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700845
846 enterLeaveNamespace(out, true /* enter */);
847 out << "\n";
848
849 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800850 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100851 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800852 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000853 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100854 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800855 out << " : public "
856 << gIBaseFqName.getInterfaceStubFqName().cppName()
857 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100858 }
Andreas Huber881227d2016-08-02 14:20:21 -0700859
860 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800861 out << "explicit "
862 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700863 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100864 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800865 out << "explicit "
866 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100867 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800868 << " const std::string& HidlInstrumentor_package,"
869 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700870 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700871 out << "::android::status_t onTransact(\n";
872 out.indent();
873 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700874 out << "uint32_t _hidl_code,\n";
875 out << "const ::android::hardware::Parcel &_hidl_data,\n";
876 out << "::android::hardware::Parcel *_hidl_reply,\n";
877 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700878 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700879 out.unindent();
880 out.unindent();
881
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100882 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
883 out.unindent();
884 out << "private:\n";
885 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800886
887 status_t err = generateMethods(out, [&](const Method *method, const Interface *iface) {
888 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
889 return OK;
890 }
891 const bool returnsValue = !method->results().empty();
892 const TypedVar *elidedReturn = method->canElideCallback();
893
894 if (elidedReturn == nullptr && returnsValue) {
895 out << "using " << method->name() << "_cb = "
896 << iface->fqName().cppName()
897 << "::" << method->name() << "_cb;\n";
898 }
899 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800900 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800901 return OK;
902 });
903 if (err != OK) {
904 return err;
905 }
906
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100907 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700908 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700909 out << "};\n\n";
910
911 enterLeaveNamespace(out, false /* enter */);
912
913 out << "\n#endif // " << guard << "\n";
914
915 return OK;
916}
917
Andreas Huberb82318c2016-08-02 14:45:54 -0700918status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700919 std::string ifaceName;
920 if (!AST::isInterface(&ifaceName)) {
921 // types.hal does not get a proxy header.
922 return OK;
923 }
924
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700925 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800926 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700927
Andreas Huberb82318c2016-08-02 14:45:54 -0700928 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700929 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700930 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800931 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700932 path.append(".h");
933
Andreas Huberd2943e12016-08-05 11:59:31 -0700934 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700935 FILE *file = fopen(path.c_str(), "w");
936
937 if (file == NULL) {
938 return -errno;
939 }
940
941 Formatter out(file);
942
Yifan Hongeefe4f22017-01-04 15:32:42 -0800943 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700944
945 out << "#ifndef " << guard << "\n";
946 out << "#define " << guard << "\n\n";
947
Martijn Coenen115d4282016-12-19 05:14:04 +0100948 out << "#include <hidl/HidlTransportSupport.h>\n\n";
949
Andreas Huber881227d2016-08-02 14:20:21 -0700950 std::vector<std::string> packageComponents;
951 getPackageAndVersionComponents(
952 &packageComponents, false /* cpp_compatible */);
953
Yifan Hongeefe4f22017-01-04 15:32:42 -0800954 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700955 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700956
957 enterLeaveNamespace(out, true /* enter */);
958 out << "\n";
959
960 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800961 << proxyName
962 << " : public ::android::hardware::BpInterface<"
963 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000964 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700965
966 out.indent();
967
Yifan Hongeefe4f22017-01-04 15:32:42 -0800968 out << "explicit "
969 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700970 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700971 << "\n\n";
972
Yifan Hong10fe0b52016-10-19 14:20:17 -0700973 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700974
Yifan Hong068c5522016-10-31 14:07:25 -0700975 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
976 method->generateCppSignature(out);
977 out << " override;\n";
978 return OK;
979 });
Steven Moreland9c387612016-09-07 09:54:26 -0700980
981 if (err != OK) {
982 return err;
983 }
Andreas Huber881227d2016-08-02 14:20:21 -0700984
985 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100986 out << "private:\n";
987 out.indent();
988 out << "std::mutex _hidl_mMutex;\n"
989 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
990 << " _hidl_mDeathRecipients;\n";
991 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700992 out << "};\n\n";
993
994 enterLeaveNamespace(out, false /* enter */);
995
996 out << "\n#endif // " << guard << "\n";
997
998 return OK;
999}
1000
Andreas Huberb82318c2016-08-02 14:45:54 -07001001status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001002
Andreas Huberb82318c2016-08-02 14:45:54 -07001003 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -07001004 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -07001005 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -07001006
1007 std::string ifaceName;
1008 std::string baseName;
1009
Yifan Hongfe95aa22016-10-19 17:26:45 -07001010 const Interface *iface = nullptr;
1011 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -07001012 if (!AST::isInterface(&ifaceName)) {
1013 baseName = "types";
1014 isInterface = false;
1015 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001016 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -07001017 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001018 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -07001019 }
1020
1021 path.append(baseName);
1022
1023 if (baseName != "types") {
1024 path.append("All");
1025 }
1026
1027 path.append(".cpp");
1028
Andreas Huberd2943e12016-08-05 11:59:31 -07001029 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -07001030 FILE *file = fopen(path.c_str(), "w");
1031
1032 if (file == NULL) {
1033 return -errno;
1034 }
1035
1036 Formatter out(file);
1037
Steven Moreland623c0042017-01-13 14:42:29 -08001038 out << "#define LOG_TAG \""
1039 << mPackage.string() << "::" << baseName
1040 << "\"\n\n";
1041
Steven Moreland05cd4232016-11-21 16:01:12 -08001042 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001043 out << "#include <cutils/trace.h>\n";
1044 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001045 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -07001046 // This is a no-op for IServiceManager itself.
1047 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
1048
Steven Morelandbec74ed2017-01-25 17:42:35 -08001049 // TODO(b/34274385) remove this
1050 out << "#include <hidl/LegacySupport.h>\n";
1051
Yifan Hongeefe4f22017-01-04 15:32:42 -08001052 generateCppPackageInclude(out, mPackage, iface->getProxyName());
1053 generateCppPackageInclude(out, mPackage, iface->getStubName());
1054 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001055
1056 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -07001057 generateCppPackageInclude(out,
1058 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -08001059 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001060 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -08001061
1062 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001063 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -07001064 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -08001065 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -07001066 }
1067
1068 out << "\n";
1069
1070 enterLeaveNamespace(out, true /* enter */);
1071 out << "\n";
1072
1073 status_t err = generateTypeSource(out, ifaceName);
1074
1075 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001076 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001077
1078 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -08001079 out << "const char* "
1080 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -07001081 << "::descriptor(\""
1082 << iface->fqName().string()
1083 << "\");\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +01001084 out << "__attribute__((constructor))";
1085 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001086 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001087 out << "::android::hardware::details::gBnConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001088 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001089 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001090 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001091 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001092 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001093 out << "return new "
1094 << iface->getStubName()
Yifan Hong341112d2017-04-20 18:12:05 -07001095 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001096 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001097 << " *>(iIntf));\n";
1098 });
Yifan Hongb04de382017-02-06 15:31:52 -08001099 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001100 });
Yifan Honga159f3b2017-03-16 14:53:51 -07001101 out << "::android::hardware::details::gBsConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001102 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001103 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001104 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001105 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -08001106 << gIBaseFqName.cppName()
1107 << "> {\n";
1108 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001109 out << "return new "
1110 << iface->getPassthroughName()
Yifan Hong341112d2017-04-20 18:12:05 -07001111 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001112 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001113 << " *>(iIntf));\n";
1114 });
Yifan Hongb04de382017-02-06 15:31:52 -08001115 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001116 });
Yifan Hong158655a2016-11-08 12:34:07 -08001117 });
Martijn Coenen8adcb652017-02-03 17:37:36 +01001118 out << "};\n\n";
1119 out << "__attribute__((destructor))";
1120 out << "static void static_destructor() {\n";
1121 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001122 out << "::android::hardware::details::gBnConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001123 << iface->localName()
1124 << "::descriptor);\n";
Yifan Honga159f3b2017-03-16 14:53:51 -07001125 out << "::android::hardware::details::gBsConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001126 << iface->localName()
1127 << "::descriptor);\n";
1128 });
1129 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001130
Yifan Hongfe95aa22016-10-19 17:26:45 -07001131 err = generateInterfaceSource(out);
1132 }
1133
1134 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001135 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001136 }
1137
1138 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001139 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001140 }
1141
Steven Moreland40786312016-08-16 10:29:40 -07001142 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001143 err = generatePassthroughSource(out);
1144 }
1145
1146 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001147 const Interface *iface = mRootScope->getInterface();
1148
Yifan Hongc8934042016-11-17 17:10:52 -08001149 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001150 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001151 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001152 std::string package = iface->fqName().package()
1153 + iface->fqName().atVersion();
1154
Yifan Hongeefe4f22017-01-04 15:32:42 -08001155 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001156 }
Steven Moreland40786312016-08-16 10:29:40 -07001157 }
1158
Andreas Huber6755e9d2017-04-06 11:09:07 -07001159 HidlTypeAssertion::EmitAll(out);
1160 out << "\n";
1161
Andreas Huber881227d2016-08-02 14:20:21 -07001162 enterLeaveNamespace(out, false /* enter */);
1163
1164 return err;
1165}
1166
Steven Moreland67f67b42016-09-29 08:59:02 -07001167// static
1168void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001169 out.sIf(nonNull + " == nullptr", [&] {
1170 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1171 out.indent(2, [&] {
1172 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1173 });
1174 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001175}
1176
Andreas Huber881227d2016-08-02 14:20:21 -07001177status_t AST::generateTypeSource(
1178 Formatter &out, const std::string &ifaceName) const {
1179 return mRootScope->emitTypeDefinitions(out, ifaceName);
1180}
1181
Andreas Hubere7ff2282016-08-16 13:50:03 -07001182void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001183 Formatter &out,
1184 const std::vector<TypedVar *> &args,
1185 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001186 if (args.empty()) {
1187 return;
1188 }
1189
1190 for (const auto &arg : args) {
1191 const Type &type = arg->type();
1192
Yifan Hong3b320f82016-11-01 15:15:54 -07001193 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001194 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001195 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001196 << ";\n";
1197 }
1198
1199 out << "\n";
1200}
1201
Andreas Huber881227d2016-08-02 14:20:21 -07001202void AST::emitCppReaderWriter(
1203 Formatter &out,
1204 const std::string &parcelObj,
1205 bool parcelObjIsPointer,
1206 const TypedVar *arg,
1207 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001208 Type::ErrorMode mode,
1209 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001210 const Type &type = arg->type();
1211
Andreas Huber881227d2016-08-02 14:20:21 -07001212 type.emitReaderWriter(
1213 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001214 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001215 parcelObj,
1216 parcelObjIsPointer,
1217 isReader,
1218 mode);
1219}
1220
Yifan Hongbf459bc2016-08-23 16:50:37 -07001221void AST::emitCppResolveReferences(
1222 Formatter &out,
1223 const std::string &parcelObj,
1224 bool parcelObjIsPointer,
1225 const TypedVar *arg,
1226 bool isReader,
1227 Type::ErrorMode mode,
1228 bool addPrefixToName) const {
1229 const Type &type = arg->type();
1230 if(type.needsResolveReferences()) {
1231 type.emitResolveReferences(
1232 out,
1233 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1234 isReader, // nameIsPointer
1235 parcelObj,
1236 parcelObjIsPointer,
1237 isReader,
1238 mode);
1239 }
1240}
1241
Yifan Hong068c5522016-10-31 14:07:25 -07001242status_t AST::generateProxyMethodSource(Formatter &out,
1243 const std::string &klassName,
1244 const Method *method,
1245 const Interface *superInterface) const {
1246
1247 method->generateCppSignature(out,
1248 klassName,
1249 true /* specify namespaces */);
1250
1251 const bool returnsValue = !method->results().empty();
1252 const TypedVar *elidedReturn = method->canElideCallback();
1253
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001254 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001255
1256 out.indent();
1257
Martijn Coenen115d4282016-12-19 05:14:04 +01001258 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1259 method->cppImpl(IMPL_PROXY, out);
1260 out.unindent();
1261 out << "}\n\n";
1262 return OK;
1263 }
1264
Yifan Hong068c5522016-10-31 14:07:25 -07001265 if (returnsValue && elidedReturn == nullptr) {
1266 generateCheckNonNull(out, "_hidl_cb");
1267 }
1268
1269 status_t status = generateCppInstrumentationCall(
1270 out,
1271 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001272 method);
1273 if (status != OK) {
1274 return status;
1275 }
1276
1277 out << "::android::hardware::Parcel _hidl_data;\n";
1278 out << "::android::hardware::Parcel _hidl_reply;\n";
1279 out << "::android::status_t _hidl_err;\n";
1280 out << "::android::hardware::Status _hidl_status;\n\n";
1281
1282 declareCppReaderLocals(
1283 out, method->results(), true /* forResults */);
1284
1285 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001286 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001287 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001288 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1289
Martijn Coenenfff73352017-01-04 16:36:31 +01001290 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001291 // First DFS: write all buffers and resolve pointers for parent
1292 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001293 if (arg->type().isInterface()) {
1294 hasInterfaceArgument = true;
1295 }
Yifan Hong068c5522016-10-31 14:07:25 -07001296 emitCppReaderWriter(
1297 out,
1298 "_hidl_data",
1299 false /* parcelObjIsPointer */,
1300 arg,
1301 false /* reader */,
1302 Type::ErrorMode_Goto,
1303 false /* addPrefixToName */);
1304 }
1305
1306 // Second DFS: resolve references.
1307 for (const auto &arg : method->args()) {
1308 emitCppResolveReferences(
1309 out,
1310 "_hidl_data",
1311 false /* parcelObjIsPointer */,
1312 arg,
1313 false /* reader */,
1314 Type::ErrorMode_Goto,
1315 false /* addPrefixToName */);
1316 }
1317
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001318 if (hasInterfaceArgument) {
1319 // Start binder threadpool to handle incoming transactions
1320 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1321 }
Yifan Hong068c5522016-10-31 14:07:25 -07001322 out << "_hidl_err = remote()->transact("
1323 << method->getSerialId()
1324 << " /* "
1325 << method->name()
1326 << " */, _hidl_data, &_hidl_reply";
1327
1328 if (method->isOneway()) {
1329 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1330 }
1331 out << ");\n";
1332
1333 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1334
1335 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001336 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001337 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1338 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1339
1340
1341 // First DFS: write all buffers and resolve pointers for parent
1342 for (const auto &arg : method->results()) {
1343 emitCppReaderWriter(
1344 out,
1345 "_hidl_reply",
1346 false /* parcelObjIsPointer */,
1347 arg,
1348 true /* reader */,
1349 Type::ErrorMode_Goto,
1350 true /* addPrefixToName */);
1351 }
1352
1353 // Second DFS: resolve references.
1354 for (const auto &arg : method->results()) {
1355 emitCppResolveReferences(
1356 out,
1357 "_hidl_reply",
1358 false /* parcelObjIsPointer */,
1359 arg,
1360 true /* reader */,
1361 Type::ErrorMode_Goto,
1362 true /* addPrefixToName */);
1363 }
1364
1365 if (returnsValue && elidedReturn == nullptr) {
1366 out << "_hidl_cb(";
1367
Yifan Hong932464e2017-03-30 15:40:22 -07001368 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001369 if (arg->type().resultNeedsDeref()) {
1370 out << "*";
1371 }
1372 out << "_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001373 });
Yifan Hong068c5522016-10-31 14:07:25 -07001374
1375 out << ");\n\n";
1376 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001377 }
1378 status = generateCppInstrumentationCall(
1379 out,
1380 InstrumentationEvent::CLIENT_API_EXIT,
1381 method);
1382 if (status != OK) {
1383 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001384 }
1385
1386 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001387 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1388 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001389 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001390 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1391 } else {
1392 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1393 out << "return ::android::hardware::Return<void>();\n\n";
1394 }
1395
1396 out.unindent();
1397 out << "_hidl_error:\n";
1398 out.indent();
1399 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1400 out << "return ::android::hardware::Return<";
1401 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001402 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001403 } else {
1404 out << "void";
1405 }
1406 out << ">(_hidl_status);\n";
1407
1408 out.unindent();
1409 out << "}\n\n";
1410 return OK;
1411}
1412
Andreas Huber881227d2016-08-02 14:20:21 -07001413status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001414 Formatter &out, const FQName &fqName) const {
1415 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001416
1417 out << klassName
1418 << "::"
1419 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001420 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001421
1422 out.indent();
1423 out.indent();
1424
1425 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001426 << "<"
1427 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001428 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001429 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001430 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001431 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001432 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001433 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001434
Andreas Huber881227d2016-08-02 14:20:21 -07001435 out.unindent();
1436 out.unindent();
1437 out << "}\n\n";
1438
Yifan Hong068c5522016-10-31 14:07:25 -07001439 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1440 return generateProxyMethodSource(out, klassName, method, superInterface);
1441 });
Andreas Huber881227d2016-08-02 14:20:21 -07001442
Yifan Hong068c5522016-10-31 14:07:25 -07001443 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001444}
1445
1446status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001447 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001448 const Interface *iface) const {
1449 const std::string interfaceName = iface->localName();
1450 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001451
Steven Moreland40786312016-08-16 10:29:40 -07001452 out << klassName
1453 << "::"
1454 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001455 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001456
1457 out.indent();
1458 out.indent();
1459
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001460 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001461 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001462 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001463 out << ": "
1464 << gIBaseFqName.getInterfaceStubFqName().cppName()
1465 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001466 }
1467
1468 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001469 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001470 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001471 << "\") { \n";
1472 out.indent();
1473 out << "_hidl_mImpl = _hidl_impl;\n";
1474 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001475
1476 out.unindent();
1477 out.unindent();
1478 out << "}\n\n";
1479
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001480 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001481 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001482 // class properly.
1483 out << klassName
1484 << "::"
1485 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001486 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1487 << " const std::string &HidlInstrumentor_package,"
1488 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001489
1490 out.indent();
1491 out.indent();
1492
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001493 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001494 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001495 out.indent();
1496 out << "_hidl_mImpl = _hidl_impl;\n";
1497 out.unindent();
1498
1499 out.unindent();
1500 out.unindent();
1501 out << "}\n\n";
1502 }
1503
Yifan Hongbcffce22017-02-01 15:52:06 -08001504 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1505 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1506 return OK;
1507 }
1508 method->generateCppSignature(out, iface->getStubName());
1509 out << " ";
1510 out.block([&] {
1511 method->cppImpl(IMPL_STUB_IMPL, out);
1512 }).endl();
1513 return OK;
1514 });
Steven Moreland60818632017-02-04 00:33:42 -08001515 if (err != OK) {
1516 return err;
1517 }
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001518
Andreas Huber881227d2016-08-02 14:20:21 -07001519 out << "::android::status_t " << klassName << "::onTransact(\n";
1520
1521 out.indent();
1522 out.indent();
1523
Iliyan Malchev549e2592016-08-10 08:59:12 -07001524 out << "uint32_t _hidl_code,\n"
1525 << "const ::android::hardware::Parcel &_hidl_data,\n"
1526 << "::android::hardware::Parcel *_hidl_reply,\n"
1527 << "uint32_t _hidl_flags,\n"
1528 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001529
1530 out.unindent();
1531
Iliyan Malchev549e2592016-08-10 08:59:12 -07001532 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001533 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001534 out.indent();
1535
Yifan Hong10fe0b52016-10-19 14:20:17 -07001536 for (const auto &tuple : iface->allMethodsFromRoot()) {
1537 const Method *method = tuple.method();
1538 const Interface *superInterface = tuple.interface();
1539 out << "case "
1540 << method->getSerialId()
1541 << " /* "
1542 << method->name()
1543 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001544
Yifan Hong10fe0b52016-10-19 14:20:17 -07001545 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001546
Yifan Hong10fe0b52016-10-19 14:20:17 -07001547 status_t err =
1548 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001549
Yifan Hong10fe0b52016-10-19 14:20:17 -07001550 if (err != OK) {
1551 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001552 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001553
1554 out.unindent();
1555 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001556 }
1557
1558 out << "default:\n{\n";
1559 out.indent();
1560
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001561 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001562
1563 out.indent();
1564 out.indent();
1565
Iliyan Malchev549e2592016-08-10 08:59:12 -07001566 out << "_hidl_code, _hidl_data, _hidl_reply, "
1567 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001568
1569 out.unindent();
1570 out.unindent();
1571
1572 out.unindent();
1573 out << "}\n";
1574
1575 out.unindent();
1576 out << "}\n\n";
1577
Yifan Honga018ed52016-12-13 16:35:08 -08001578 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1579 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1580 out.indent(2, [&] {
1581 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1582 out << "_hidl_reply);\n";
1583 });
1584 });
Andreas Huber881227d2016-08-02 14:20:21 -07001585
Iliyan Malchev549e2592016-08-10 08:59:12 -07001586 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001587
1588 out.unindent();
1589 out << "}\n\n";
1590
1591 return OK;
1592}
1593
1594status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001595 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001596 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1597 method->cppImpl(IMPL_STUB, out);
1598 out << "break;\n";
1599 return OK;
1600 }
1601
Yifan Hongeefe4f22017-01-04 15:32:42 -08001602 out << "if (!_hidl_data.enforceInterface("
1603 << iface->fullName()
1604 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001605
Andreas Huber881227d2016-08-02 14:20:21 -07001606 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001607 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001608 out << "break;\n";
1609 out.unindent();
1610 out << "}\n\n";
1611
Andreas Huber5e44a292016-09-27 14:52:39 -07001612 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001613
Yifan Hongbf459bc2016-08-23 16:50:37 -07001614 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001615 for (const auto &arg : method->args()) {
1616 emitCppReaderWriter(
1617 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001618 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001619 false /* parcelObjIsPointer */,
1620 arg,
1621 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001622 Type::ErrorMode_Break,
1623 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001624 }
1625
Yifan Hongbf459bc2016-08-23 16:50:37 -07001626 // Second DFS: resolve references
1627 for (const auto &arg : method->args()) {
1628 emitCppResolveReferences(
1629 out,
1630 "_hidl_data",
1631 false /* parcelObjIsPointer */,
1632 arg,
1633 true /* reader */,
1634 Type::ErrorMode_Break,
1635 false /* addPrefixToName */);
1636 }
1637
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001638 status_t status = generateCppInstrumentationCall(
1639 out,
1640 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001641 method);
1642 if (status != OK) {
1643 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001644 }
1645
Andreas Huber881227d2016-08-02 14:20:21 -07001646 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001647 const TypedVar *elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -08001648 const std::string callee =
1649 (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL))
1650 ? "this" : "_hidl_mImpl";
Andreas Huber881227d2016-08-02 14:20:21 -07001651
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001652 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001653 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001654 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001655 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001656 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001657 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001658 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001659
Yifan Hong932464e2017-03-30 15:40:22 -07001660 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001661 if (arg->type().resultNeedsDeref()) {
1662 out << "*";
1663 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001664 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001665 });
Andreas Huber881227d2016-08-02 14:20:21 -07001666
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001667 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001668 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1669 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001670
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001671 elidedReturn->type().emitReaderWriter(
1672 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001673 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001674 "_hidl_reply",
1675 true, /* parcelObjIsPointer */
1676 false, /* isReader */
1677 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001678
Yifan Hongbf459bc2016-08-23 16:50:37 -07001679 emitCppResolveReferences(
1680 out,
1681 "_hidl_reply",
1682 true /* parcelObjIsPointer */,
1683 elidedReturn,
1684 false /* reader */,
1685 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001686 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001687
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001688 status_t status = generateCppInstrumentationCall(
1689 out,
1690 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001691 method);
1692 if (status != OK) {
1693 return status;
1694 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001695
Iliyan Malchev549e2592016-08-10 08:59:12 -07001696 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001697 } else {
1698 if (returnsValue) {
1699 out << "bool _hidl_callbackCalled = false;\n\n";
1700 }
Andreas Huber881227d2016-08-02 14:20:21 -07001701
Yifan Hongcd2ae452017-01-31 14:33:40 -08001702 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001703
Yifan Hong932464e2017-03-30 15:40:22 -07001704 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001705 if (arg->type().resultNeedsDeref()) {
1706 out << "*";
1707 }
1708
1709 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001710 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001711
1712 if (returnsValue) {
Yifan Hong932464e2017-03-30 15:40:22 -07001713 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001714 out << ", ";
1715 }
1716
1717 out << "[&](";
1718
Yifan Hong932464e2017-03-30 15:40:22 -07001719 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001720 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001721 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001722
1723 out << ") {\n";
1724 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001725 out << "if (_hidl_callbackCalled) {\n";
1726 out.indent();
1727 out << "LOG_ALWAYS_FATAL(\""
1728 << method->name()
1729 << ": _hidl_cb called a second time, but must be called once.\");\n";
1730 out.unindent();
1731 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001732 out << "_hidl_callbackCalled = true;\n\n";
1733
Yifan Hong859e53f2016-11-14 19:08:24 -08001734 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1735 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001736
Yifan Hongbf459bc2016-08-23 16:50:37 -07001737 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001738 for (const auto &arg : method->results()) {
1739 emitCppReaderWriter(
1740 out,
1741 "_hidl_reply",
1742 true /* parcelObjIsPointer */,
1743 arg,
1744 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001745 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001746 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001747 }
1748
Yifan Hongbf459bc2016-08-23 16:50:37 -07001749 // Second DFS: resolve references
1750 for (const auto &arg : method->results()) {
1751 emitCppResolveReferences(
1752 out,
1753 "_hidl_reply",
1754 true /* parcelObjIsPointer */,
1755 arg,
1756 false /* reader */,
1757 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001758 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001759 }
1760
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001761 status_t status = generateCppInstrumentationCall(
1762 out,
1763 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001764 method);
1765 if (status != OK) {
1766 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001767 }
1768
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001769 out << "_hidl_cb(*_hidl_reply);\n";
1770
1771 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001772 out << "});\n\n";
1773 } else {
1774 out << ");\n\n";
1775 status_t status = generateCppInstrumentationCall(
1776 out,
1777 InstrumentationEvent::SERVER_API_EXIT,
1778 method);
1779 if (status != OK) {
1780 return status;
1781 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001782 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001783
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001784 if (returnsValue) {
1785 out << "if (!_hidl_callbackCalled) {\n";
1786 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001787 out << "LOG_ALWAYS_FATAL(\""
1788 << method->name()
1789 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001790 out.unindent();
1791 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001792 } else {
1793 out << "::android::hardware::writeToParcel("
1794 << "::android::hardware::Status::ok(), "
1795 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001796 }
Andreas Huber881227d2016-08-02 14:20:21 -07001797 }
1798
1799 out << "break;\n";
1800
1801 return OK;
1802}
1803
Steven Moreland69e7c702016-09-09 11:16:32 -07001804status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1805 std::string ifaceName;
1806 if (!AST::isInterface(&ifaceName)) {
1807 // types.hal does not get a stub header.
1808 return OK;
1809 }
1810
1811 const Interface *iface = mRootScope->getInterface();
1812
Yifan Hongeefe4f22017-01-04 15:32:42 -08001813 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001814
1815 bool supportOneway = iface->hasOnewayMethods();
1816
1817 std::string path = outputPath;
1818 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1819 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1820 path.append(klassName);
1821 path.append(".h");
1822
1823 CHECK(Coordinator::MakeParentHierarchy(path));
1824 FILE *file = fopen(path.c_str(), "w");
1825
1826 if (file == NULL) {
1827 return -errno;
1828 }
1829
1830 Formatter out(file);
1831
1832 const std::string guard = makeHeaderGuard(klassName);
1833
1834 out << "#ifndef " << guard << "\n";
1835 out << "#define " << guard << "\n\n";
1836
1837 std::vector<std::string> packageComponents;
1838 getPackageAndVersionComponents(
1839 &packageComponents, false /* cpp_compatible */);
1840
Steven Moreland61d3f4b2017-04-28 17:30:38 -07001841 out << "#include <android-base/macros.h>\n";
Yifan Hongb0949432016-12-15 15:32:24 -08001842 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001843 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001844
1845 generateCppPackageInclude(out, mPackage, ifaceName);
1846 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001847
Yifan Hong7a118f52016-12-07 11:21:15 -08001848 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001849 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001850 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001851 }
1852
1853 enterLeaveNamespace(out, true /* enter */);
1854 out << "\n";
1855
1856 out << "struct "
1857 << klassName
1858 << " : " << ifaceName
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001859 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001860
1861 out.indent();
1862 out << "explicit "
1863 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001864 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001865 << ifaceName
1866 << "> impl);\n";
1867
Yifan Hong068c5522016-10-31 14:07:25 -07001868 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1869 return generatePassthroughMethod(out, method);
1870 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001871
1872 if (err != OK) {
1873 return err;
1874 }
1875
1876 out.unindent();
1877 out << "private:\n";
1878 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001879 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001880
1881 if (supportOneway) {
Yifan Hongef91d362017-03-20 17:18:13 -07001882 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001883
1884 out << "\n";
1885
1886 out << "::android::hardware::Return<void> addOnewayTask("
1887 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001888 }
1889
1890 out.unindent();
1891
1892 out << "};\n\n";
1893
1894 enterLeaveNamespace(out, false /* enter */);
1895
1896 out << "\n#endif // " << guard << "\n";
1897
1898 return OK;
1899}
1900
Yifan Hongfe95aa22016-10-19 17:26:45 -07001901status_t AST::generateInterfaceSource(Formatter &out) const {
1902 const Interface *iface = mRootScope->getInterface();
1903
Yifan Hong2d7126b2016-10-20 15:12:57 -07001904 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001905 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001906
Steven Morelandd4b068a2017-03-20 06:30:51 -07001907 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1908 bool reserved = method->isHidlReserved();
1909
1910 if (!reserved) {
1911 out << "// no default implementation for: ";
1912 }
1913 method->generateCppSignature(out, iface->localName());
1914 if (reserved) {
1915 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001916 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001917 }).endl();
1918 }
1919
1920 out << "\n";
1921
1922 return OK;
1923 });
1924 if (err != OK) {
1925 return err;
1926 }
1927
Yifan Hong3d746092016-12-07 14:26:33 -08001928 for (const Interface *superType : iface->typeChain()) {
Yifan Hong200209c2017-03-29 03:39:09 -07001929 out << "// static \n::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -08001930 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -07001931 << "> "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001932 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001933 << "::castFrom("
1934 << superType->getCppArgumentType()
Yifan Hong200209c2017-03-29 03:39:09 -07001935 << " parent, bool "
1936 << (iface == superType ? "/* emitError */" : "emitError")
1937 << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001938 out.indent();
1939 if (iface == superType) {
1940 out << "return parent;\n";
1941 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001942 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001943 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001944 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001945 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001946 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001947 << ">(\n";
1948 out.indent();
1949 out.indent();
1950 out << "parent, \""
1951 << iface->fqName().string()
Yifan Hong200209c2017-03-29 03:39:09 -07001952 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001953 out.unindent();
1954 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001955 }
Yifan Hong3d746092016-12-07 14:26:33 -08001956 out.unindent();
1957 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001958 }
1959
1960 return OK;
1961}
1962
Steven Moreland69e7c702016-09-09 11:16:32 -07001963status_t AST::generatePassthroughSource(Formatter &out) const {
1964 const Interface *iface = mRootScope->getInterface();
1965
Yifan Hongeefe4f22017-01-04 15:32:42 -08001966 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001967
1968 out << klassName
1969 << "::"
1970 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001971 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001972 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001973 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001974 << mPackage.string()
1975 << "\", \""
1976 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001977 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001978 if (iface->hasOnewayMethods()) {
1979 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001980 out.indent([&] {
Yifan Hongf01dad42017-03-20 19:03:11 -07001981 out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001982 });
1983 }
1984 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001985
1986 if (iface->hasOnewayMethods()) {
1987 out << "::android::hardware::Return<void> "
1988 << klassName
1989 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1990 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001991 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001992 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001993 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1994 out.indent();
1995 out.indent();
1996 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1997 out.unindent();
1998 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001999 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07002000 out << "}\n";
2001
Steven Morelandd366c262016-10-11 15:29:10 -07002002 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07002003
2004 out.unindent();
2005 out << "}\n\n";
2006
2007
2008 }
2009
2010 return OK;
2011}
2012
Martijn Coenen7b295242016-11-04 16:52:56 +01002013status_t AST::generateCppAtraceCall(Formatter &out,
2014 InstrumentationEvent event,
2015 const Method *method) const {
2016 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08002017 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01002018 switch (event) {
2019 case SERVER_API_ENTRY:
2020 {
2021 out << "atrace_begin(ATRACE_TAG_HAL, \""
2022 << baseString + "::server\");\n";
2023 break;
2024 }
2025 case CLIENT_API_ENTRY:
2026 {
2027 out << "atrace_begin(ATRACE_TAG_HAL, \""
2028 << baseString + "::client\");\n";
2029 break;
2030 }
2031 case PASSTHROUGH_ENTRY:
2032 {
2033 out << "atrace_begin(ATRACE_TAG_HAL, \""
2034 << baseString + "::passthrough\");\n";
2035 break;
2036 }
2037 case SERVER_API_EXIT:
2038 case CLIENT_API_EXIT:
2039 case PASSTHROUGH_EXIT:
2040 {
2041 out << "atrace_end(ATRACE_TAG_HAL);\n";
2042 break;
2043 }
2044 default:
2045 {
2046 LOG(ERROR) << "Unsupported instrumentation event: " << event;
2047 return UNKNOWN_ERROR;
2048 }
2049 }
2050
2051 return OK;
2052}
2053
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002054status_t AST::generateCppInstrumentationCall(
2055 Formatter &out,
2056 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07002057 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01002058 status_t err = generateCppAtraceCall(out, event, method);
2059 if (err != OK) {
2060 return err;
2061 }
2062
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002063 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
2064 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002065 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002066 std::string event_str = "";
2067 switch (event) {
2068 case SERVER_API_ENTRY:
2069 {
2070 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
2071 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002072 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002073 << (arg->type().resultNeedsDeref() ? "" : "&")
2074 << arg->name()
2075 << ");\n";
2076 }
2077 break;
2078 }
2079 case SERVER_API_EXIT:
2080 {
2081 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07002082 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002083 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07002084 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002085 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002086 }
2087 break;
2088 }
2089 case CLIENT_API_ENTRY:
2090 {
2091 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2092 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002093 out << "_hidl_args.push_back((void *)&"
2094 << arg->name()
2095 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002096 }
2097 break;
2098 }
2099 case CLIENT_API_EXIT:
2100 {
2101 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2102 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002103 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002104 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002105 << "_hidl_out_"
2106 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002107 << ");\n";
2108 }
2109 break;
2110 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002111 case PASSTHROUGH_ENTRY:
2112 {
2113 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2114 for (const auto &arg : method->args()) {
2115 out << "_hidl_args.push_back((void *)&"
2116 << arg->name()
2117 << ");\n";
2118 }
2119 break;
2120 }
2121 case PASSTHROUGH_EXIT:
2122 {
2123 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002124 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002125 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002126 << arg->name()
2127 << ");\n";
2128 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002129 break;
2130 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002131 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002132 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002133 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002134 return UNKNOWN_ERROR;
2135 }
2136 }
2137
Steven Moreland031ccf12016-10-31 15:54:38 -07002138 const Interface *iface = mRootScope->getInterface();
2139
Steven Moreland1ab31442016-11-03 18:37:51 -07002140 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002141 out.indent();
2142 out << "callback("
2143 << event_str
2144 << ", \""
2145 << mPackage.package()
2146 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002147 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002148 << "\", \""
2149 << iface->localName()
2150 << "\", \""
2151 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002152 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002153 out.unindent();
2154 out << "}\n";
2155 out.unindent();
2156 out << "}\n\n";
2157
2158 return OK;
2159}
2160
Andreas Huber881227d2016-08-02 14:20:21 -07002161} // namespace android