blob: e12d140baddd464aaa06f6664ecdcc8d0a3511f9 [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Huber881227d2016-08-02 14:20:21 -070017#include "AST.h"
18
19#include "Coordinator.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070020#include "EnumType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070021#include "Interface.h"
Andreas Huber02ef12f2017-04-06 11:09:07 -070022#include "HidlTypeAssertion.h"
Andreas Huber881227d2016-08-02 14:20:21 -070023#include "Method.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070024#include "ScalarType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070025#include "Scope.h"
26
Andreas Huberdca261f2016-08-04 13:47:51 -070027#include <algorithm>
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070028#include <hidl-util/Formatter.h>
Steven Moreland5708edf2016-11-04 15:33:31 +000029#include <hidl-util/StringHelper.h>
Andreas Huber881227d2016-08-02 14:20:21 -070030#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070031#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070032#include <vector>
33
34namespace android {
35
Andreas Huberb82318c2016-08-02 14:45:54 -070036status_t AST::generateCpp(const std::string &outputPath) const {
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 Morelandeec5f7a2017-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 Morelandeec5f7a2017-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 Morelandeec5f7a2017-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 Morelandeec5f7a2017-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
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800151 out << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800152 out << "static bool registerForNotifications(\n";
153 out.indent(2, [&] {
154 out << "const std::string &serviceName,\n"
155 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
156 << "&notification);\n";
157 });
158
159}
160
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700161static void implementGetService(Formatter &out,
162 const FQName &fqName,
163 bool isTry) {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800164
165 const std::string interfaceName = fqName.getInterfaceName();
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700166 const std::string functionName = isTry ? "tryGetService" : "getService";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800167
168 out << "// static\n"
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700169 << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
Yifan Hong31f07ff2017-03-21 18:56:35 +0000170 << "const std::string &serviceName, const bool getStub) ";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800171 out.block([&] {
Steven Moreland8146c322017-04-06 09:17:44 -0700172 out << "using ::android::hardware::defaultServiceManager;\n";
173 out << "using ::android::hardware::details::waitForHwService;\n";
174 out << "using ::android::hardware::getPassthroughServiceManager;\n";
175 out << "using ::android::hardware::Return;\n";
176 out << "using ::android::sp;\n";
177 out << "using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;\n\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000178
Steven Moreland8146c322017-04-06 09:17:44 -0700179 out << "sp<" << interfaceName << "> iface = nullptr;\n";
180
181 out.endl();
182
183 out << "const sp<::android::hidl::manager::V1_0::IServiceManager> sm"
184 << " = defaultServiceManager();\n";
185
186 out.sIf("sm == nullptr", [&] {
187 // hwbinder is not available on this device, so future tries
188 // would also be null. I can only return nullptr.
189 out << "ALOGE(\"getService: defaultServiceManager() is null\");\n"
190 << "return nullptr;\n";
191 }).endl().endl();
192
193 out << "Return<Transport> transportRet = sm->getTransport("
194 << interfaceName << "::descriptor, serviceName);\n\n";
195
196 out.sIf("!transportRet.isOk()", [&] {
197 out << "ALOGE(\"getService: defaultServiceManager()->getTransport returns %s\", "
198 << "transportRet.description().c_str());\n";
199 out << "return nullptr;\n";
200 });
201
202 out.endl();
203
204 out << "Transport transport = transportRet;\n";
205 out << "const bool vintfHwbinder = (transport == Transport::HWBINDER);\n"
206 << "const bool vintfPassthru = (transport == Transport::PASSTHROUGH);\n"
207 << "const bool vintfEmpty = (transport == Transport::EMPTY);\n\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000208
209 // if (getStub) {
210 // getPassthroughServiceManager()->get only once.
211 // } else {
212 // if (vintfHwbinder) {
213 // while (no alive service) {
214 // waitForHwService
215 // defaultServiceManager()->get
216 // }
217 // } else if (vintfEmpty) {
218 // defaultServiceManager()->get only once.
219 // getPassthroughServiceManager()->get only once.
220 // } else if (vintfPassthru) {
221 // getPassthroughServiceManager()->get only once.
222 // }
223 // }
224
Yifan Hongf1ef44f2017-03-23 17:17:57 +0000225 out << "bool tried = false;\n";
226 out.sWhile("!getStub && (vintfHwbinder || (vintfEmpty && !tried))", [&] {
Yifan Hong31f07ff2017-03-21 18:56:35 +0000227
228 out.sIf("tried", [&] {
229 // sleep only after the first trial.
230 out << "ALOGI(\"getService: retrying in 1s...\");\n"
231 << "sleep(1);\n";
232 }).endl();
233
Yifan Hongf1ef44f2017-03-23 17:17:57 +0000234 out << "tried = true;\n";
235
Yifan Hong31f07ff2017-03-21 18:56:35 +0000236
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700237 if (!isTry) {
238 out.sIf("vintfHwbinder", [&] {
Steven Moreland8146c322017-04-06 09:17:44 -0700239 out << "waitForHwService("
240 << interfaceName << "::descriptor, serviceName);\n";
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700241 }).endl();
242 }
Yifan Hong31f07ff2017-03-21 18:56:35 +0000243
Steven Moreland8146c322017-04-06 09:17:44 -0700244 out << "Return<sp<" << gIBaseFqName.cppName() << ">> ret = \n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000245 out.indent(2, [&] {
246 out << "sm->get(" << interfaceName << "::descriptor, serviceName);\n";
247 });
248
249 out.sIf("!ret.isOk()", [&] {
Steven Moreland42394ce2017-03-27 17:03:04 -0700250 // hwservicemanager fails, may be security issue
Yifan Hong31f07ff2017-03-21 18:56:35 +0000251 out << "ALOGE(\"getService: defaultServiceManager()->get returns %s\", "
252 << "ret.description().c_str());\n"
Steven Moreland42394ce2017-03-27 17:03:04 -0700253 << "break;\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000254 }).endl();
255
Steven Moreland8146c322017-04-06 09:17:44 -0700256 out << "sp<" << gIBaseFqName.cppName() << "> base = ret;\n";
Yifan Hong7783bb02017-03-29 03:39:09 -0700257 out.sIf("base == nullptr", [&] {
258 // race condition. hwservicemanager drops the service
259 // from waitForHwService to here
Steven Morelanddff644c2017-03-24 10:59:01 -0700260 out << "ALOGW(\"getService: found null hwbinder interface\");\n"
Yifan Hongdd0b55d2017-04-04 13:27:25 -0700261 << (isTry ? "break" : "continue")
262 << ";\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000263 }).endl();
Steven Moreland8146c322017-04-06 09:17:44 -0700264 out << "Return<sp<" << interfaceName
Yifan Hong7783bb02017-03-29 03:39:09 -0700265 << ">> castRet = " << interfaceName << "::castFrom(base, true /* emitError */);\n";
266 out.sIf("!castRet.isOk()", [&] {
267 out.sIf("castRet.isDeadObject()", [&] {
268 // service is dead (castFrom cannot call interfaceChain)
269 out << "ALOGW(\"getService: found dead hwbinder service\");\n"
Yifan Hongdd0b55d2017-04-04 13:27:25 -0700270 << (isTry ? "break" : "continue")
271 << ";\n";
Yifan Hong7783bb02017-03-29 03:39:09 -0700272 }).sElse([&] {
273 out << "ALOGW(\"getService: cannot call into hwbinder service: %s"
274 << "; No permission? Check for selinux denials.\", "
275 << "castRet.description().c_str());\n"
276 << "break;\n";
277 }).endl();
278 }).endl();
279 out << "iface = castRet;\n";
280 out.sIf("iface == nullptr", [&] {
281 // returned service isn't of correct type; this is a bug
282 // to hwservicemanager or to the service itself (interfaceChain
283 // is not consistent).
284 out << "ALOGW(\"getService: received incompatible service; bug in hwservicemanager?\");\n"
Yifan Hong31f07ff2017-03-21 18:56:35 +0000285 << "break;\n";
286 }).endl();
287
288 out << "return iface;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800289 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800290
Yifan Hong31f07ff2017-03-21 18:56:35 +0000291 out.sIf("getStub || vintfPassthru || vintfEmpty", [&] {
Steven Moreland8146c322017-04-06 09:17:44 -0700292 out << "const sp<::android::hidl::manager::V1_0::IServiceManager> pm"
293 << " = getPassthroughServiceManager();\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000294
295 out.sIf("pm != nullptr", [&] () {
Steven Moreland8146c322017-04-06 09:17:44 -0700296 out << "Return<sp<" << gIBaseFqName.cppName() << ">> ret = \n";
Steven Morelandf10af872017-01-25 16:01:56 +0000297 out.indent(2, [&] {
298 out << "pm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
Steven Moreland2c2dea82017-01-18 17:24:17 -0800299 });
Steven Morelandf10af872017-01-25 16:01:56 +0000300 out.sIf("ret.isOk()", [&] {
Steven Moreland8146c322017-04-06 09:17:44 -0700301 out << "sp<" << gIBaseFqName.cppName()
Steven Morelandf10af872017-01-25 16:01:56 +0000302 << "> baseInterface = ret;\n";
303 out.sIf("baseInterface != nullptr", [&]() {
304 out << "iface = new " << fqName.getInterfacePassthroughName()
305 << "(" << interfaceName << "::castFrom(baseInterface));\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000306 }).endl();
Steven Morelandf10af872017-01-25 16:01:56 +0000307 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800308 }).endl();
309 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800310
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800311 out << "return iface;\n";
312 }).endl().endl();
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700313}
314
315static void implementServiceManagerInteractions(Formatter &out,
316 const FQName &fqName, const std::string &package) {
317
318 const std::string interfaceName = fqName.getInterfaceName();
319
320 implementGetService(out, fqName, true /* isTry */);
321 implementGetService(out, fqName, false /* isTry */);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800322
Yifan Hongeefe4f22017-01-04 15:32:42 -0800323 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800324 << "const std::string &serviceName) ";
325 out.block([&] {
Steven Morelanda9582e62017-04-09 10:54:50 -0700326 out << "::android::hardware::details::onRegistration(\""
327 << fqName.getPackageAndVersion().string() << "\", \""
328 << interfaceName
329 << "\", serviceName);\n\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800330 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
331 out.indent(2, [&] {
332 out << "= ::android::hardware::defaultServiceManager();\n";
333 });
334 out.sIf("sm == nullptr", [&] {
335 out << "return ::android::INVALID_OPERATION;\n";
336 }).endl();
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100337 out << "::android::hardware::Return<bool> ret = "
338 << "sm->add(serviceName.c_str(), this);\n"
339 << "return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800340 }).endl().endl();
341
Yifan Hongeefe4f22017-01-04 15:32:42 -0800342 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800343 out.indent(2, [&] {
344 out << "const std::string &serviceName,\n"
345 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
346 << "&notification) ";
347 });
348 out.block([&] {
349 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
350 out.indent(2, [&] {
351 out << "= ::android::hardware::defaultServiceManager();\n";
352 });
353 out.sIf("sm == nullptr", [&] {
354 out << "return false;\n";
355 }).endl();
356 out << "::android::hardware::Return<bool> success =\n";
357 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800358 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800359 out.indent(2, [&] {
360 out << "serviceName, notification);\n";
361 });
362 });
363 out << "return success.isOk() && success;\n";
364 }).endl().endl();
365}
366
Andreas Huberb82318c2016-08-02 14:45:54 -0700367status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700368
Andreas Huberb82318c2016-08-02 14:45:54 -0700369 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700370 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700371 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700372
373 std::string ifaceName;
374 bool isInterface = true;
375 if (!AST::isInterface(&ifaceName)) {
376 ifaceName = "types";
377 isInterface = false;
378 }
379 path.append(ifaceName);
380 path.append(".h");
381
Andreas Huberd2943e12016-08-05 11:59:31 -0700382 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700383 FILE *file = fopen(path.c_str(), "w");
384
385 if (file == NULL) {
386 return -errno;
387 }
388
389 Formatter out(file);
390
391 const std::string guard = makeHeaderGuard(ifaceName);
392
393 out << "#ifndef " << guard << "\n";
394 out << "#define " << guard << "\n\n";
395
Andreas Huber737080b2016-08-02 15:38:04 -0700396 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700397 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700398 }
399
400 if (!mImportedNames.empty()) {
401 out << "\n";
402 }
403
Steven Moreland0693f312016-11-09 15:06:14 -0800404 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800405 if (isIBase()) {
406 out << "// skipped #include IServiceNotification.h\n\n";
407 } else {
408 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
409 }
Steven Moreland0693f312016-11-09 15:06:14 -0800410 }
411
Yifan Hongc8934042016-11-17 17:10:52 -0800412 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700413 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700414
415 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200416 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700417 }
418
Martijn Coenenaf712c02016-11-16 15:26:27 +0100419 out << "#include <utils/NativeHandle.h>\n";
420 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700421
422 enterLeaveNamespace(out, true /* enter */);
423 out << "\n";
424
425 if (isInterface) {
426 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700427 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700428
429 const Interface *iface = mRootScope->getInterface();
430 const Interface *superType = iface->superType();
431
Steven Moreland40786312016-08-16 10:29:40 -0700432 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800433 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700434 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000435 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700436 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700437 }
438
439 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700440
441 out.indent();
442
Andreas Huber881227d2016-08-02 14:20:21 -0700443 }
444
445 status_t err = emitTypeDeclarations(out);
446
447 if (err != OK) {
448 return err;
449 }
450
451 if (isInterface) {
452 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800453
Yifan Hongc8934042016-11-17 17:10:52 -0800454 out << "virtual bool isRemote() const ";
455 if (!isIBase()) {
456 out << "override ";
457 }
458 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800459
Andreas Huber881227d2016-08-02 14:20:21 -0700460 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700461 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700462
Andreas Huber881227d2016-08-02 14:20:21 -0700463 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800464 const TypedVar *elidedReturn = method->canElideCallback();
465
466 if (elidedReturn == nullptr && returnsValue) {
467 out << "using "
468 << method->name()
Yifan Hong7d234ea2017-03-30 15:40:22 -0700469 << "_cb = std::function<void(";
470 method->emitCppResultSignature(out, true /* specify namespaces */);
471 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800472 }
Andreas Huber881227d2016-08-02 14:20:21 -0700473
Andreas Huber3599d922016-08-09 10:42:57 -0700474 method->dumpAnnotations(out);
475
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700476 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700477 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700478 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700479 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700480 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700481 }
482
483 out << method->name()
Yifan Hong7d234ea2017-03-30 15:40:22 -0700484 << "(";
485 method->emitCppArgSignature(out, true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700486
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700487 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700488 if (!method->args().empty()) {
489 out << ", ";
490 }
491
Steven Moreland67f67b42016-09-29 08:59:02 -0700492 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700493 }
494
Yifan Hong10fe0b52016-10-19 14:20:17 -0700495 out << ")";
496 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800497 if (!isIBase()) {
498 out << " override";
499 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700500 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700501 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700502 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700503 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700504 }
Steven Moreland40786312016-08-16 10:29:40 -0700505
Yifan Hong3d746092016-12-07 14:26:33 -0800506 out << "// cast static functions\n";
507 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700508
Yifan Hong3d746092016-12-07 14:26:33 -0800509 for (const Interface *superType : iface->typeChain()) {
Yifan Hong7783bb02017-03-29 03:39:09 -0700510 out << "static ::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -0800511 << childTypeResult
Yifan Hong7783bb02017-03-29 03:39:09 -0700512 << "> castFrom("
Yifan Hong3d746092016-12-07 14:26:33 -0800513 << superType->getCppArgumentType()
514 << " parent"
Yifan Hong7783bb02017-03-29 03:39:09 -0700515 << ", bool emitError = false);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700516 }
517
Steven Morelandd39133b2016-11-11 12:30:08 -0800518 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700519
Yifan Hongc8934042016-11-17 17:10:52 -0800520 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800521 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800522 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800523 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800524 }
Andreas Huber881227d2016-08-02 14:20:21 -0700525 }
526
527 if (isInterface) {
528 out.unindent();
529
Andreas Hubere3f769a2016-10-10 10:54:44 -0700530 out << "};\n\n";
531 }
532
533 err = mRootScope->emitGlobalTypeDeclarations(out);
534
535 if (err != OK) {
536 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700537 }
538
539 out << "\n";
540 enterLeaveNamespace(out, false /* enter */);
541
542 out << "\n#endif // " << guard << "\n";
543
544 return OK;
545}
546
Steven Moreland40786312016-08-16 10:29:40 -0700547status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
548 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800549 bool isInterface = AST::isInterface(&ifaceName);
550 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800551 std::string klassName{};
552
553 if(isInterface) {
554 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800555 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800556 } else {
557 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700558 }
559
Steven Moreland40786312016-08-16 10:29:40 -0700560 std::string path = outputPath;
561 path.append(mCoordinator->convertPackageRootToPath(mPackage));
562 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
563 path.append(klassName + ".h");
564
Yifan Hong244e82d2016-11-11 11:13:57 -0800565 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700566
567 if (file == NULL) {
568 return -errno;
569 }
570
571 Formatter out(file);
572
573 const std::string guard = makeHeaderGuard(klassName);
574
575 out << "#ifndef " << guard << "\n";
576 out << "#define " << guard << "\n\n";
577
Yifan Hong244e82d2016-11-11 11:13:57 -0800578 if (isInterface) {
579 generateCppPackageInclude(out, mPackage, ifaceName);
580 } else {
581 generateCppPackageInclude(out, mPackage, "types");
582 }
Steven Moreland40786312016-08-16 10:29:40 -0700583
Steven Morelandee88eed2016-10-31 17:49:00 -0700584 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700585
586 for (const auto &item : mImportedNames) {
587 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800588 generateCppPackageInclude(out, item, "hwtypes");
589 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800590 generateCppPackageInclude(out, item, item.getInterfaceStubName());
591 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700592 }
Steven Moreland40786312016-08-16 10:29:40 -0700593 }
594
595 out << "\n";
596
Martijn Coenen93915102016-09-01 01:35:52 +0200597 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700598 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100599 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700600
601 out << "\n";
602
603 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700604
Yifan Hong244e82d2016-11-11 11:13:57 -0800605 status_t err = mRootScope->emitGlobalHwDeclarations(out);
606 if (err != OK) {
607 return err;
608 }
Steven Moreland40786312016-08-16 10:29:40 -0700609
610 enterLeaveNamespace(out, false /* enter */);
611
612 out << "\n#endif // " << guard << "\n";
613
614 return OK;
615}
616
Andreas Huber881227d2016-08-02 14:20:21 -0700617status_t AST::emitTypeDeclarations(Formatter &out) const {
618 return mRootScope->emitTypeDeclarations(out);
619}
620
Yifan Hong7a118f52016-12-07 11:21:15 -0800621static void wrapPassthroughArg(Formatter &out,
622 const TypedVar *arg, bool addPrefixToName,
623 std::function<void(void)> handleError) {
624 if (!arg->type().isInterface()) {
625 return;
626 }
627 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
628 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
629 + arg->name();
630 const Interface &iface = static_cast<const Interface &>(arg->type());
631 out << iface.getCppStackType() << " " << wrappedName << ";\n";
632 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
633 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
634 out << wrappedName
635 << " = "
636 << iface.fqName().cppName()
Yifan Hongeb4fe782017-04-20 18:12:05 -0700637 << "::castFrom(::android::hardware::details::wrapPassthrough<"
638 << iface.fqName().cppName()
639 << ">("
Yifan Hong7a118f52016-12-07 11:21:15 -0800640 << name << "));\n";
641 out.sIf(wrappedName + " == nullptr", [&] {
642 // Fatal error. Happens when the BsFoo class is not found in the binary
643 // or any dynamic libraries.
644 handleError();
645 }).endl();
646 }).sElse([&] {
647 out << wrappedName << " = " << name << ";\n";
648 }).endl().endl();
649}
650
Steven Moreland69e7c702016-09-09 11:16:32 -0700651status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700652 const Method *method) const {
653 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700654
655 out << " {\n";
656 out.indent();
657
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800658 if (method->isHidlReserved()
659 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
660 method->cppImpl(IMPL_PASSTHROUGH, out);
661 out.unindent();
662 out << "}\n\n";
663 return OK;
664 }
665
Steven Moreland69e7c702016-09-09 11:16:32 -0700666 const bool returnsValue = !method->results().empty();
667 const TypedVar *elidedReturn = method->canElideCallback();
668
Steven Moreland67f67b42016-09-29 08:59:02 -0700669 if (returnsValue && elidedReturn == nullptr) {
670 generateCheckNonNull(out, "_hidl_cb");
671 }
672
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700673 generateCppInstrumentationCall(
674 out,
675 InstrumentationEvent::PASSTHROUGH_ENTRY,
676 method);
677
Yifan Hong7a118f52016-12-07 11:21:15 -0800678
679 for (const auto &arg : method->args()) {
680 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
681 out << "return ::android::hardware::Status::fromExceptionCode(\n";
682 out.indent(2, [&] {
683 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800684 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800685 });
686 });
687 }
688
689 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700690 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700691
692 if (method->isOneway()) {
Steven Morelandca279942017-05-02 12:10:13 -0700693 out << "addOnewayTask([mImpl = this->mImpl, "
694 "mEnableInstrumentation = this->mEnableInstrumentation, "
695 "mInstrumentationCallbacks = this->mInstrumentationCallbacks, "
696 "&_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700697 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800698 out << ", "
699 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
700 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700701 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700702 out << "] {\n";
703 out.indent();
Steven Moreland69e7c702016-09-09 11:16:32 -0700704 }
705
706 out << "mImpl->"
707 << method->name()
708 << "(";
709
Yifan Hong7d234ea2017-03-30 15:40:22 -0700710 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800711 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700712 });
Steven Moreland69e7c702016-09-09 11:16:32 -0700713 if (returnsValue && elidedReturn == nullptr) {
714 if (!method->args().empty()) {
715 out << ", ";
716 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800717 out << "[&](";
Yifan Hong7d234ea2017-03-30 15:40:22 -0700718 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800719 out << "const auto &_hidl_out_"
720 << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700721 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800722
723 out << ") {\n";
724 out.indent();
725 status_t status = generateCppInstrumentationCall(
726 out,
727 InstrumentationEvent::PASSTHROUGH_EXIT,
728 method);
729 if (status != OK) {
730 return status;
731 }
732
Yifan Hong7a118f52016-12-07 11:21:15 -0800733 for (const auto &arg : method->results()) {
734 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
735 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
736 out.indent(2, [&] {
737 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800738 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800739 });
740 out << "return;\n";
741 });
742 }
743
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800744 out << "_hidl_cb(";
Yifan Hong7d234ea2017-03-30 15:40:22 -0700745 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800746 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
747 << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700748 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800749 out << ");\n";
750 out.unindent();
751 out << "});\n\n";
752 } else {
753 out << ");\n\n";
754 if (elidedReturn != nullptr) {
755 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800756 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800757 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000758 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800759 }
760 status_t status = generateCppInstrumentationCall(
761 out,
762 InstrumentationEvent::PASSTHROUGH_EXIT,
763 method);
764 if (status != OK) {
765 return status;
766 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700767 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700768
769 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700770 out.unindent();
771 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700772 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700773
774 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700775
776 out.unindent();
777 out << "}\n";
778
779 return OK;
780}
781
Yifan Hong068c5522016-10-31 14:07:25 -0700782status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700783
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700784 const Interface *iface = mRootScope->getInterface();
785
Yifan Hong10fe0b52016-10-19 14:20:17 -0700786 const Interface *prevIterface = nullptr;
787 for (const auto &tuple : iface->allMethodsFromRoot()) {
788 const Method *method = tuple.method();
789 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700790
Yifan Hong10fe0b52016-10-19 14:20:17 -0700791 if(prevIterface != superInterface) {
792 if (prevIterface != nullptr) {
793 out << "\n";
794 }
795 out << "// Methods from "
796 << superInterface->fullName()
797 << " follow.\n";
798 prevIterface = superInterface;
799 }
Yifan Hong068c5522016-10-31 14:07:25 -0700800 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700801
Yifan Hong10fe0b52016-10-19 14:20:17 -0700802 if (err != OK) {
803 return err;
804 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700805 }
806
Yifan Hong10fe0b52016-10-19 14:20:17 -0700807 out << "\n";
808
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700809 return OK;
810}
811
Andreas Huberb82318c2016-08-02 14:45:54 -0700812status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700813 std::string ifaceName;
814 if (!AST::isInterface(&ifaceName)) {
815 // types.hal does not get a stub header.
816 return OK;
817 }
818
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700819 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800820 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700821
Andreas Huberb82318c2016-08-02 14:45:54 -0700822 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700823 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700824 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700825 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700826 path.append(".h");
827
Andreas Huberd2943e12016-08-05 11:59:31 -0700828 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700829 FILE *file = fopen(path.c_str(), "w");
830
831 if (file == NULL) {
832 return -errno;
833 }
834
835 Formatter out(file);
836
Steven Moreland40786312016-08-16 10:29:40 -0700837 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700838
839 out << "#ifndef " << guard << "\n";
840 out << "#define " << guard << "\n\n";
841
Yifan Hongeefe4f22017-01-04 15:32:42 -0800842 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700843 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700844
845 enterLeaveNamespace(out, true /* enter */);
846 out << "\n";
847
848 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800849 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100850 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800851 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000852 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100853 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800854 out << " : public "
855 << gIBaseFqName.getInterfaceStubFqName().cppName()
856 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100857 }
Andreas Huber881227d2016-08-02 14:20:21 -0700858
859 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800860 out << "explicit "
861 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700862 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100863 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800864 out << "explicit "
865 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100866 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800867 << " const std::string& HidlInstrumentor_package,"
868 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700869 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700870 out << "::android::status_t onTransact(\n";
871 out.indent();
872 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700873 out << "uint32_t _hidl_code,\n";
874 out << "const ::android::hardware::Parcel &_hidl_data,\n";
875 out << "::android::hardware::Parcel *_hidl_reply,\n";
876 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700877 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700878 out.unindent();
879 out.unindent();
880
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100881 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
882 out.unindent();
883 out << "private:\n";
884 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800885
886 status_t err = generateMethods(out, [&](const Method *method, const Interface *iface) {
887 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
888 return OK;
889 }
890 const bool returnsValue = !method->results().empty();
891 const TypedVar *elidedReturn = method->canElideCallback();
892
893 if (elidedReturn == nullptr && returnsValue) {
894 out << "using " << method->name() << "_cb = "
895 << iface->fqName().cppName()
896 << "::" << method->name() << "_cb;\n";
897 }
898 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800899 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800900 return OK;
901 });
902 if (err != OK) {
903 return err;
904 }
905
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100906 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700907 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700908 out << "};\n\n";
909
910 enterLeaveNamespace(out, false /* enter */);
911
912 out << "\n#endif // " << guard << "\n";
913
914 return OK;
915}
916
Andreas Huberb82318c2016-08-02 14:45:54 -0700917status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700918 std::string ifaceName;
919 if (!AST::isInterface(&ifaceName)) {
920 // types.hal does not get a proxy header.
921 return OK;
922 }
923
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700924 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800925 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700926
Andreas Huberb82318c2016-08-02 14:45:54 -0700927 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700928 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700929 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800930 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700931 path.append(".h");
932
Andreas Huberd2943e12016-08-05 11:59:31 -0700933 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700934 FILE *file = fopen(path.c_str(), "w");
935
936 if (file == NULL) {
937 return -errno;
938 }
939
940 Formatter out(file);
941
Yifan Hongeefe4f22017-01-04 15:32:42 -0800942 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700943
944 out << "#ifndef " << guard << "\n";
945 out << "#define " << guard << "\n\n";
946
Martijn Coenen115d4282016-12-19 05:14:04 +0100947 out << "#include <hidl/HidlTransportSupport.h>\n\n";
948
Andreas Huber881227d2016-08-02 14:20:21 -0700949 std::vector<std::string> packageComponents;
950 getPackageAndVersionComponents(
951 &packageComponents, false /* cpp_compatible */);
952
Yifan Hongeefe4f22017-01-04 15:32:42 -0800953 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700954 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700955
956 enterLeaveNamespace(out, true /* enter */);
957 out << "\n";
958
959 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800960 << proxyName
961 << " : public ::android::hardware::BpInterface<"
962 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000963 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700964
965 out.indent();
966
Yifan Hongeefe4f22017-01-04 15:32:42 -0800967 out << "explicit "
968 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700969 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700970 << "\n\n";
971
Yifan Hong10fe0b52016-10-19 14:20:17 -0700972 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700973
Yifan Hong068c5522016-10-31 14:07:25 -0700974 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
975 method->generateCppSignature(out);
976 out << " override;\n";
977 return OK;
978 });
Steven Moreland9c387612016-09-07 09:54:26 -0700979
980 if (err != OK) {
981 return err;
982 }
Andreas Huber881227d2016-08-02 14:20:21 -0700983
984 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100985 out << "private:\n";
986 out.indent();
987 out << "std::mutex _hidl_mMutex;\n"
988 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
989 << " _hidl_mDeathRecipients;\n";
990 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700991 out << "};\n\n";
992
993 enterLeaveNamespace(out, false /* enter */);
994
995 out << "\n#endif // " << guard << "\n";
996
997 return OK;
998}
999
Andreas Huberb82318c2016-08-02 14:45:54 -07001000status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001001
Andreas Huberb82318c2016-08-02 14:45:54 -07001002 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -07001003 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -07001004 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -07001005
1006 std::string ifaceName;
1007 std::string baseName;
1008
Yifan Hongfe95aa22016-10-19 17:26:45 -07001009 const Interface *iface = nullptr;
1010 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -07001011 if (!AST::isInterface(&ifaceName)) {
1012 baseName = "types";
1013 isInterface = false;
1014 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001015 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -07001016 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001017 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -07001018 }
1019
1020 path.append(baseName);
1021
1022 if (baseName != "types") {
1023 path.append("All");
1024 }
1025
1026 path.append(".cpp");
1027
Andreas Huberd2943e12016-08-05 11:59:31 -07001028 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -07001029 FILE *file = fopen(path.c_str(), "w");
1030
1031 if (file == NULL) {
1032 return -errno;
1033 }
1034
1035 Formatter out(file);
1036
Steven Moreland623c0042017-01-13 14:42:29 -08001037 out << "#define LOG_TAG \""
1038 << mPackage.string() << "::" << baseName
1039 << "\"\n\n";
1040
Steven Moreland05cd4232016-11-21 16:01:12 -08001041 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001042 out << "#include <cutils/trace.h>\n";
1043 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001044 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -07001045 // This is a no-op for IServiceManager itself.
1046 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
1047
Steven Morelandbec74ed2017-01-25 17:42:35 -08001048 // TODO(b/34274385) remove this
1049 out << "#include <hidl/LegacySupport.h>\n";
1050
Yifan Hongeefe4f22017-01-04 15:32:42 -08001051 generateCppPackageInclude(out, mPackage, iface->getProxyName());
1052 generateCppPackageInclude(out, mPackage, iface->getStubName());
1053 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001054
1055 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -07001056 generateCppPackageInclude(out,
1057 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -08001058 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001059 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -08001060
1061 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001062 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -07001063 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -08001064 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -07001065 }
1066
1067 out << "\n";
1068
1069 enterLeaveNamespace(out, true /* enter */);
1070 out << "\n";
1071
1072 status_t err = generateTypeSource(out, ifaceName);
1073
1074 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001075 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001076
1077 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -08001078 out << "const char* "
1079 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -07001080 << "::descriptor(\""
1081 << iface->fqName().string()
1082 << "\");\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +01001083 out << "__attribute__((constructor))";
1084 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001085 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001086 out << "::android::hardware::details::gBnConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001087 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001088 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001089 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001090 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001091 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001092 out << "return new "
1093 << iface->getStubName()
Yifan Hongeb4fe782017-04-20 18:12:05 -07001094 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001095 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001096 << " *>(iIntf));\n";
1097 });
Yifan Hongb04de382017-02-06 15:31:52 -08001098 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001099 });
Yifan Honga159f3b2017-03-16 14:53:51 -07001100 out << "::android::hardware::details::gBsConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001101 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001102 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001103 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001104 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -08001105 << gIBaseFqName.cppName()
1106 << "> {\n";
1107 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001108 out << "return new "
1109 << iface->getPassthroughName()
Yifan Hongeb4fe782017-04-20 18:12:05 -07001110 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001111 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001112 << " *>(iIntf));\n";
1113 });
Yifan Hongb04de382017-02-06 15:31:52 -08001114 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001115 });
Yifan Hong158655a2016-11-08 12:34:07 -08001116 });
Martijn Coenen8adcb652017-02-03 17:37:36 +01001117 out << "};\n\n";
1118 out << "__attribute__((destructor))";
1119 out << "static void static_destructor() {\n";
1120 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001121 out << "::android::hardware::details::gBnConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001122 << iface->localName()
1123 << "::descriptor);\n";
Yifan Honga159f3b2017-03-16 14:53:51 -07001124 out << "::android::hardware::details::gBsConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001125 << iface->localName()
1126 << "::descriptor);\n";
1127 });
1128 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001129
Yifan Hongfe95aa22016-10-19 17:26:45 -07001130 err = generateInterfaceSource(out);
1131 }
1132
1133 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001134 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001135 }
1136
1137 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001138 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001139 }
1140
Steven Moreland40786312016-08-16 10:29:40 -07001141 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001142 err = generatePassthroughSource(out);
1143 }
1144
1145 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001146 const Interface *iface = mRootScope->getInterface();
1147
Yifan Hongc8934042016-11-17 17:10:52 -08001148 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001149 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001150 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001151 std::string package = iface->fqName().package()
1152 + iface->fqName().atVersion();
1153
Yifan Hongeefe4f22017-01-04 15:32:42 -08001154 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001155 }
Steven Moreland40786312016-08-16 10:29:40 -07001156 }
1157
Andreas Huber02ef12f2017-04-06 11:09:07 -07001158 HidlTypeAssertion::EmitAll(out);
1159 out << "\n";
1160
Andreas Huber881227d2016-08-02 14:20:21 -07001161 enterLeaveNamespace(out, false /* enter */);
1162
1163 return err;
1164}
1165
Steven Moreland67f67b42016-09-29 08:59:02 -07001166// static
1167void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001168 out.sIf(nonNull + " == nullptr", [&] {
1169 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1170 out.indent(2, [&] {
1171 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1172 });
1173 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001174}
1175
Andreas Huber881227d2016-08-02 14:20:21 -07001176status_t AST::generateTypeSource(
1177 Formatter &out, const std::string &ifaceName) const {
1178 return mRootScope->emitTypeDefinitions(out, ifaceName);
1179}
1180
Andreas Hubere7ff2282016-08-16 13:50:03 -07001181void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001182 Formatter &out,
1183 const std::vector<TypedVar *> &args,
1184 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001185 if (args.empty()) {
1186 return;
1187 }
1188
1189 for (const auto &arg : args) {
1190 const Type &type = arg->type();
1191
Yifan Hong3b320f82016-11-01 15:15:54 -07001192 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001193 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001194 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001195 << ";\n";
1196 }
1197
1198 out << "\n";
1199}
1200
Andreas Huber881227d2016-08-02 14:20:21 -07001201void AST::emitCppReaderWriter(
1202 Formatter &out,
1203 const std::string &parcelObj,
1204 bool parcelObjIsPointer,
1205 const TypedVar *arg,
1206 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001207 Type::ErrorMode mode,
1208 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001209 const Type &type = arg->type();
1210
Andreas Huber881227d2016-08-02 14:20:21 -07001211 type.emitReaderWriter(
1212 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001213 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001214 parcelObj,
1215 parcelObjIsPointer,
1216 isReader,
1217 mode);
1218}
1219
Yifan Hongbf459bc2016-08-23 16:50:37 -07001220void AST::emitCppResolveReferences(
1221 Formatter &out,
1222 const std::string &parcelObj,
1223 bool parcelObjIsPointer,
1224 const TypedVar *arg,
1225 bool isReader,
1226 Type::ErrorMode mode,
1227 bool addPrefixToName) const {
1228 const Type &type = arg->type();
1229 if(type.needsResolveReferences()) {
1230 type.emitResolveReferences(
1231 out,
1232 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1233 isReader, // nameIsPointer
1234 parcelObj,
1235 parcelObjIsPointer,
1236 isReader,
1237 mode);
1238 }
1239}
1240
Yifan Hong068c5522016-10-31 14:07:25 -07001241status_t AST::generateProxyMethodSource(Formatter &out,
1242 const std::string &klassName,
1243 const Method *method,
1244 const Interface *superInterface) const {
1245
1246 method->generateCppSignature(out,
1247 klassName,
1248 true /* specify namespaces */);
1249
1250 const bool returnsValue = !method->results().empty();
1251 const TypedVar *elidedReturn = method->canElideCallback();
1252
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001253 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001254
1255 out.indent();
1256
Martijn Coenen115d4282016-12-19 05:14:04 +01001257 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1258 method->cppImpl(IMPL_PROXY, out);
1259 out.unindent();
1260 out << "}\n\n";
1261 return OK;
1262 }
1263
Yifan Hong068c5522016-10-31 14:07:25 -07001264 if (returnsValue && elidedReturn == nullptr) {
1265 generateCheckNonNull(out, "_hidl_cb");
1266 }
1267
1268 status_t status = generateCppInstrumentationCall(
1269 out,
1270 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001271 method);
1272 if (status != OK) {
1273 return status;
1274 }
1275
1276 out << "::android::hardware::Parcel _hidl_data;\n";
1277 out << "::android::hardware::Parcel _hidl_reply;\n";
1278 out << "::android::status_t _hidl_err;\n";
1279 out << "::android::hardware::Status _hidl_status;\n\n";
1280
1281 declareCppReaderLocals(
1282 out, method->results(), true /* forResults */);
1283
1284 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001285 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001286 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001287 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1288
Martijn Coenenfff73352017-01-04 16:36:31 +01001289 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001290 // First DFS: write all buffers and resolve pointers for parent
1291 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001292 if (arg->type().isInterface()) {
1293 hasInterfaceArgument = true;
1294 }
Yifan Hong068c5522016-10-31 14:07:25 -07001295 emitCppReaderWriter(
1296 out,
1297 "_hidl_data",
1298 false /* parcelObjIsPointer */,
1299 arg,
1300 false /* reader */,
1301 Type::ErrorMode_Goto,
1302 false /* addPrefixToName */);
1303 }
1304
1305 // Second DFS: resolve references.
1306 for (const auto &arg : method->args()) {
1307 emitCppResolveReferences(
1308 out,
1309 "_hidl_data",
1310 false /* parcelObjIsPointer */,
1311 arg,
1312 false /* reader */,
1313 Type::ErrorMode_Goto,
1314 false /* addPrefixToName */);
1315 }
1316
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001317 if (hasInterfaceArgument) {
1318 // Start binder threadpool to handle incoming transactions
1319 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1320 }
Yifan Hong068c5522016-10-31 14:07:25 -07001321 out << "_hidl_err = remote()->transact("
1322 << method->getSerialId()
1323 << " /* "
1324 << method->name()
1325 << " */, _hidl_data, &_hidl_reply";
1326
1327 if (method->isOneway()) {
1328 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1329 }
1330 out << ");\n";
1331
1332 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1333
1334 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001335 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001336 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1337 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1338
1339
1340 // First DFS: write all buffers and resolve pointers for parent
1341 for (const auto &arg : method->results()) {
1342 emitCppReaderWriter(
1343 out,
1344 "_hidl_reply",
1345 false /* parcelObjIsPointer */,
1346 arg,
1347 true /* reader */,
1348 Type::ErrorMode_Goto,
1349 true /* addPrefixToName */);
1350 }
1351
1352 // Second DFS: resolve references.
1353 for (const auto &arg : method->results()) {
1354 emitCppResolveReferences(
1355 out,
1356 "_hidl_reply",
1357 false /* parcelObjIsPointer */,
1358 arg,
1359 true /* reader */,
1360 Type::ErrorMode_Goto,
1361 true /* addPrefixToName */);
1362 }
1363
1364 if (returnsValue && elidedReturn == nullptr) {
1365 out << "_hidl_cb(";
1366
Yifan Hong7d234ea2017-03-30 15:40:22 -07001367 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001368 if (arg->type().resultNeedsDeref()) {
1369 out << "*";
1370 }
1371 out << "_hidl_out_" << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001372 });
Yifan Hong068c5522016-10-31 14:07:25 -07001373
1374 out << ");\n\n";
1375 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001376 }
1377 status = generateCppInstrumentationCall(
1378 out,
1379 InstrumentationEvent::CLIENT_API_EXIT,
1380 method);
1381 if (status != OK) {
1382 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001383 }
1384
1385 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001386 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1387 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001388 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001389 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1390 } else {
1391 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1392 out << "return ::android::hardware::Return<void>();\n\n";
1393 }
1394
1395 out.unindent();
1396 out << "_hidl_error:\n";
1397 out.indent();
1398 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1399 out << "return ::android::hardware::Return<";
1400 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001401 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001402 } else {
1403 out << "void";
1404 }
1405 out << ">(_hidl_status);\n";
1406
1407 out.unindent();
1408 out << "}\n\n";
1409 return OK;
1410}
1411
Andreas Huber881227d2016-08-02 14:20:21 -07001412status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001413 Formatter &out, const FQName &fqName) const {
1414 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001415
1416 out << klassName
1417 << "::"
1418 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001419 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001420
1421 out.indent();
1422 out.indent();
1423
1424 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001425 << "<"
1426 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001427 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001428 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001429 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001430 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001431 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001432 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001433
Andreas Huber881227d2016-08-02 14:20:21 -07001434 out.unindent();
1435 out.unindent();
1436 out << "}\n\n";
1437
Yifan Hong068c5522016-10-31 14:07:25 -07001438 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1439 return generateProxyMethodSource(out, klassName, method, superInterface);
1440 });
Andreas Huber881227d2016-08-02 14:20:21 -07001441
Yifan Hong068c5522016-10-31 14:07:25 -07001442 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001443}
1444
1445status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001446 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001447 const Interface *iface) const {
1448 const std::string interfaceName = iface->localName();
1449 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001450
Steven Moreland40786312016-08-16 10:29:40 -07001451 out << klassName
1452 << "::"
1453 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001454 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001455
1456 out.indent();
1457 out.indent();
1458
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001459 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001460 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001461 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001462 out << ": "
1463 << gIBaseFqName.getInterfaceStubFqName().cppName()
1464 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001465 }
1466
1467 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001468 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001469 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001470 << "\") { \n";
1471 out.indent();
1472 out << "_hidl_mImpl = _hidl_impl;\n";
1473 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001474
1475 out.unindent();
1476 out.unindent();
1477 out << "}\n\n";
1478
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001479 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001480 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001481 // class properly.
1482 out << klassName
1483 << "::"
1484 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001485 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1486 << " const std::string &HidlInstrumentor_package,"
1487 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001488
1489 out.indent();
1490 out.indent();
1491
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001492 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001493 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001494 out.indent();
1495 out << "_hidl_mImpl = _hidl_impl;\n";
1496 out.unindent();
1497
1498 out.unindent();
1499 out.unindent();
1500 out << "}\n\n";
1501 }
1502
Yifan Hongbcffce22017-02-01 15:52:06 -08001503 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1504 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1505 return OK;
1506 }
1507 method->generateCppSignature(out, iface->getStubName());
1508 out << " ";
1509 out.block([&] {
1510 method->cppImpl(IMPL_STUB_IMPL, out);
1511 }).endl();
1512 return OK;
1513 });
Steven Moreland60818632017-02-04 00:33:42 -08001514 if (err != OK) {
1515 return err;
1516 }
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001517
Andreas Huber881227d2016-08-02 14:20:21 -07001518 out << "::android::status_t " << klassName << "::onTransact(\n";
1519
1520 out.indent();
1521 out.indent();
1522
Iliyan Malchev549e2592016-08-10 08:59:12 -07001523 out << "uint32_t _hidl_code,\n"
1524 << "const ::android::hardware::Parcel &_hidl_data,\n"
1525 << "::android::hardware::Parcel *_hidl_reply,\n"
1526 << "uint32_t _hidl_flags,\n"
1527 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001528
1529 out.unindent();
1530
Iliyan Malchev549e2592016-08-10 08:59:12 -07001531 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001532 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001533 out.indent();
1534
Yifan Hong10fe0b52016-10-19 14:20:17 -07001535 for (const auto &tuple : iface->allMethodsFromRoot()) {
1536 const Method *method = tuple.method();
1537 const Interface *superInterface = tuple.interface();
1538 out << "case "
1539 << method->getSerialId()
1540 << " /* "
1541 << method->name()
1542 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001543
Yifan Hong10fe0b52016-10-19 14:20:17 -07001544 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001545
Yifan Hong10fe0b52016-10-19 14:20:17 -07001546 status_t err =
1547 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001548
Yifan Hong10fe0b52016-10-19 14:20:17 -07001549 if (err != OK) {
1550 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001551 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001552
1553 out.unindent();
1554 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001555 }
1556
1557 out << "default:\n{\n";
1558 out.indent();
1559
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001560 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001561
1562 out.indent();
1563 out.indent();
1564
Iliyan Malchev549e2592016-08-10 08:59:12 -07001565 out << "_hidl_code, _hidl_data, _hidl_reply, "
1566 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001567
1568 out.unindent();
1569 out.unindent();
1570
1571 out.unindent();
1572 out << "}\n";
1573
1574 out.unindent();
1575 out << "}\n\n";
1576
Yifan Honga018ed52016-12-13 16:35:08 -08001577 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1578 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1579 out.indent(2, [&] {
1580 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1581 out << "_hidl_reply);\n";
1582 });
1583 });
Andreas Huber881227d2016-08-02 14:20:21 -07001584
Iliyan Malchev549e2592016-08-10 08:59:12 -07001585 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001586
1587 out.unindent();
1588 out << "}\n\n";
1589
1590 return OK;
1591}
1592
1593status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001594 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001595 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1596 method->cppImpl(IMPL_STUB, out);
1597 out << "break;\n";
1598 return OK;
1599 }
1600
Yifan Hongeefe4f22017-01-04 15:32:42 -08001601 out << "if (!_hidl_data.enforceInterface("
1602 << iface->fullName()
1603 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001604
Andreas Huber881227d2016-08-02 14:20:21 -07001605 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001606 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001607 out << "break;\n";
1608 out.unindent();
1609 out << "}\n\n";
1610
Andreas Huber5e44a292016-09-27 14:52:39 -07001611 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001612
Yifan Hongbf459bc2016-08-23 16:50:37 -07001613 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001614 for (const auto &arg : method->args()) {
1615 emitCppReaderWriter(
1616 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001617 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001618 false /* parcelObjIsPointer */,
1619 arg,
1620 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001621 Type::ErrorMode_Break,
1622 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001623 }
1624
Yifan Hongbf459bc2016-08-23 16:50:37 -07001625 // Second DFS: resolve references
1626 for (const auto &arg : method->args()) {
1627 emitCppResolveReferences(
1628 out,
1629 "_hidl_data",
1630 false /* parcelObjIsPointer */,
1631 arg,
1632 true /* reader */,
1633 Type::ErrorMode_Break,
1634 false /* addPrefixToName */);
1635 }
1636
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001637 status_t status = generateCppInstrumentationCall(
1638 out,
1639 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001640 method);
1641 if (status != OK) {
1642 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001643 }
1644
Andreas Huber881227d2016-08-02 14:20:21 -07001645 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001646 const TypedVar *elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -08001647 const std::string callee =
1648 (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL))
1649 ? "this" : "_hidl_mImpl";
Andreas Huber881227d2016-08-02 14:20:21 -07001650
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001651 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001652 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001653 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001654 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001655 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001656 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001657 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001658
Yifan Hong7d234ea2017-03-30 15:40:22 -07001659 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001660 if (arg->type().resultNeedsDeref()) {
1661 out << "*";
1662 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001663 out << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001664 });
Andreas Huber881227d2016-08-02 14:20:21 -07001665
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001666 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001667 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1668 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001669
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001670 elidedReturn->type().emitReaderWriter(
1671 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001672 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001673 "_hidl_reply",
1674 true, /* parcelObjIsPointer */
1675 false, /* isReader */
1676 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001677
Yifan Hongbf459bc2016-08-23 16:50:37 -07001678 emitCppResolveReferences(
1679 out,
1680 "_hidl_reply",
1681 true /* parcelObjIsPointer */,
1682 elidedReturn,
1683 false /* reader */,
1684 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001685 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001686
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001687 status_t status = generateCppInstrumentationCall(
1688 out,
1689 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001690 method);
1691 if (status != OK) {
1692 return status;
1693 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001694
Iliyan Malchev549e2592016-08-10 08:59:12 -07001695 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001696 } else {
1697 if (returnsValue) {
1698 out << "bool _hidl_callbackCalled = false;\n\n";
1699 }
Andreas Huber881227d2016-08-02 14:20:21 -07001700
Yifan Hongcd2ae452017-01-31 14:33:40 -08001701 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001702
Yifan Hong7d234ea2017-03-30 15:40:22 -07001703 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001704 if (arg->type().resultNeedsDeref()) {
1705 out << "*";
1706 }
1707
1708 out << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001709 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001710
1711 if (returnsValue) {
Yifan Hong7d234ea2017-03-30 15:40:22 -07001712 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001713 out << ", ";
1714 }
1715
1716 out << "[&](";
1717
Yifan Hong7d234ea2017-03-30 15:40:22 -07001718 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001719 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001720 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001721
1722 out << ") {\n";
1723 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001724 out << "if (_hidl_callbackCalled) {\n";
1725 out.indent();
1726 out << "LOG_ALWAYS_FATAL(\""
1727 << method->name()
1728 << ": _hidl_cb called a second time, but must be called once.\");\n";
1729 out.unindent();
1730 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001731 out << "_hidl_callbackCalled = true;\n\n";
1732
Yifan Hong859e53f2016-11-14 19:08:24 -08001733 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1734 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001735
Yifan Hongbf459bc2016-08-23 16:50:37 -07001736 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001737 for (const auto &arg : method->results()) {
1738 emitCppReaderWriter(
1739 out,
1740 "_hidl_reply",
1741 true /* parcelObjIsPointer */,
1742 arg,
1743 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001744 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001745 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001746 }
1747
Yifan Hongbf459bc2016-08-23 16:50:37 -07001748 // Second DFS: resolve references
1749 for (const auto &arg : method->results()) {
1750 emitCppResolveReferences(
1751 out,
1752 "_hidl_reply",
1753 true /* parcelObjIsPointer */,
1754 arg,
1755 false /* reader */,
1756 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001757 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001758 }
1759
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001760 status_t status = generateCppInstrumentationCall(
1761 out,
1762 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001763 method);
1764 if (status != OK) {
1765 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001766 }
1767
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001768 out << "_hidl_cb(*_hidl_reply);\n";
1769
1770 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001771 out << "});\n\n";
1772 } else {
1773 out << ");\n\n";
1774 status_t status = generateCppInstrumentationCall(
1775 out,
1776 InstrumentationEvent::SERVER_API_EXIT,
1777 method);
1778 if (status != OK) {
1779 return status;
1780 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001781 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001782
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001783 if (returnsValue) {
1784 out << "if (!_hidl_callbackCalled) {\n";
1785 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001786 out << "LOG_ALWAYS_FATAL(\""
1787 << method->name()
1788 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001789 out.unindent();
1790 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001791 } else {
1792 out << "::android::hardware::writeToParcel("
1793 << "::android::hardware::Status::ok(), "
1794 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001795 }
Andreas Huber881227d2016-08-02 14:20:21 -07001796 }
1797
1798 out << "break;\n";
1799
1800 return OK;
1801}
1802
Steven Moreland69e7c702016-09-09 11:16:32 -07001803status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1804 std::string ifaceName;
1805 if (!AST::isInterface(&ifaceName)) {
1806 // types.hal does not get a stub header.
1807 return OK;
1808 }
1809
1810 const Interface *iface = mRootScope->getInterface();
1811
Yifan Hongeefe4f22017-01-04 15:32:42 -08001812 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001813
1814 bool supportOneway = iface->hasOnewayMethods();
1815
1816 std::string path = outputPath;
1817 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1818 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1819 path.append(klassName);
1820 path.append(".h");
1821
1822 CHECK(Coordinator::MakeParentHierarchy(path));
1823 FILE *file = fopen(path.c_str(), "w");
1824
1825 if (file == NULL) {
1826 return -errno;
1827 }
1828
1829 Formatter out(file);
1830
1831 const std::string guard = makeHeaderGuard(klassName);
1832
1833 out << "#ifndef " << guard << "\n";
1834 out << "#define " << guard << "\n\n";
1835
1836 std::vector<std::string> packageComponents;
1837 getPackageAndVersionComponents(
1838 &packageComponents, false /* cpp_compatible */);
1839
Yifan Hongb0949432016-12-15 15:32:24 -08001840 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001841 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001842
1843 generateCppPackageInclude(out, mPackage, ifaceName);
1844 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001845
Yifan Hong7a118f52016-12-07 11:21:15 -08001846 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001847 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001848 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001849 }
1850
1851 enterLeaveNamespace(out, true /* enter */);
1852 out << "\n";
1853
1854 out << "struct "
1855 << klassName
1856 << " : " << ifaceName
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001857 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001858
1859 out.indent();
1860 out << "explicit "
1861 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001862 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001863 << ifaceName
1864 << "> impl);\n";
1865
Yifan Hong068c5522016-10-31 14:07:25 -07001866 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1867 return generatePassthroughMethod(out, method);
1868 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001869
1870 if (err != OK) {
1871 return err;
1872 }
1873
1874 out.unindent();
1875 out << "private:\n";
1876 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001877 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001878
1879 if (supportOneway) {
Yifan Hongef91d362017-03-20 17:18:13 -07001880 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001881
1882 out << "\n";
1883
1884 out << "::android::hardware::Return<void> addOnewayTask("
1885 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001886 }
1887
1888 out.unindent();
1889
1890 out << "};\n\n";
1891
1892 enterLeaveNamespace(out, false /* enter */);
1893
1894 out << "\n#endif // " << guard << "\n";
1895
1896 return OK;
1897}
1898
Yifan Hongfe95aa22016-10-19 17:26:45 -07001899status_t AST::generateInterfaceSource(Formatter &out) const {
1900 const Interface *iface = mRootScope->getInterface();
1901
Yifan Hong2d7126b2016-10-20 15:12:57 -07001902 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001903 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001904
Steven Morelandd4b068a2017-03-20 06:30:51 -07001905 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1906 bool reserved = method->isHidlReserved();
1907
1908 if (!reserved) {
1909 out << "// no default implementation for: ";
1910 }
1911 method->generateCppSignature(out, iface->localName());
1912 if (reserved) {
1913 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001914 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001915 }).endl();
1916 }
1917
1918 out << "\n";
1919
1920 return OK;
1921 });
1922 if (err != OK) {
1923 return err;
1924 }
1925
Yifan Hong3d746092016-12-07 14:26:33 -08001926 for (const Interface *superType : iface->typeChain()) {
Yifan Hong7783bb02017-03-29 03:39:09 -07001927 out << "// static \n::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -08001928 << childTypeResult
Yifan Hong7783bb02017-03-29 03:39:09 -07001929 << "> "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001930 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001931 << "::castFrom("
1932 << superType->getCppArgumentType()
Yifan Hong7783bb02017-03-29 03:39:09 -07001933 << " parent, bool "
1934 << (iface == superType ? "/* emitError */" : "emitError")
1935 << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001936 out.indent();
1937 if (iface == superType) {
1938 out << "return parent;\n";
1939 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001940 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001941 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001942 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001943 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001944 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001945 << ">(\n";
1946 out.indent();
1947 out.indent();
1948 out << "parent, \""
1949 << iface->fqName().string()
Yifan Hong7783bb02017-03-29 03:39:09 -07001950 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001951 out.unindent();
1952 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001953 }
Yifan Hong3d746092016-12-07 14:26:33 -08001954 out.unindent();
1955 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001956 }
1957
1958 return OK;
1959}
1960
Steven Moreland69e7c702016-09-09 11:16:32 -07001961status_t AST::generatePassthroughSource(Formatter &out) const {
1962 const Interface *iface = mRootScope->getInterface();
1963
Yifan Hongeefe4f22017-01-04 15:32:42 -08001964 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001965
1966 out << klassName
1967 << "::"
1968 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001969 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001970 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001971 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001972 << mPackage.string()
1973 << "\", \""
1974 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001975 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001976 if (iface->hasOnewayMethods()) {
1977 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001978 out.indent([&] {
Yifan Hongf01dad42017-03-20 19:03:11 -07001979 out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001980 });
1981 }
1982 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001983
1984 if (iface->hasOnewayMethods()) {
1985 out << "::android::hardware::Return<void> "
1986 << klassName
1987 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1988 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001989 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001990 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001991 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1992 out.indent();
1993 out.indent();
1994 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1995 out.unindent();
1996 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001997 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001998 out << "}\n";
1999
Steven Morelandd366c262016-10-11 15:29:10 -07002000 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07002001
2002 out.unindent();
2003 out << "}\n\n";
2004
2005
2006 }
2007
2008 return OK;
2009}
2010
Martijn Coenen7b295242016-11-04 16:52:56 +01002011status_t AST::generateCppAtraceCall(Formatter &out,
2012 InstrumentationEvent event,
2013 const Method *method) const {
2014 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08002015 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01002016 switch (event) {
2017 case SERVER_API_ENTRY:
2018 {
2019 out << "atrace_begin(ATRACE_TAG_HAL, \""
2020 << baseString + "::server\");\n";
2021 break;
2022 }
2023 case CLIENT_API_ENTRY:
2024 {
2025 out << "atrace_begin(ATRACE_TAG_HAL, \""
2026 << baseString + "::client\");\n";
2027 break;
2028 }
2029 case PASSTHROUGH_ENTRY:
2030 {
2031 out << "atrace_begin(ATRACE_TAG_HAL, \""
2032 << baseString + "::passthrough\");\n";
2033 break;
2034 }
2035 case SERVER_API_EXIT:
2036 case CLIENT_API_EXIT:
2037 case PASSTHROUGH_EXIT:
2038 {
2039 out << "atrace_end(ATRACE_TAG_HAL);\n";
2040 break;
2041 }
2042 default:
2043 {
2044 LOG(ERROR) << "Unsupported instrumentation event: " << event;
2045 return UNKNOWN_ERROR;
2046 }
2047 }
2048
2049 return OK;
2050}
2051
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002052status_t AST::generateCppInstrumentationCall(
2053 Formatter &out,
2054 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07002055 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01002056 status_t err = generateCppAtraceCall(out, event, method);
2057 if (err != OK) {
2058 return err;
2059 }
2060
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002061 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
2062 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002063 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002064 std::string event_str = "";
2065 switch (event) {
2066 case SERVER_API_ENTRY:
2067 {
2068 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
2069 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002070 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002071 << (arg->type().resultNeedsDeref() ? "" : "&")
2072 << arg->name()
2073 << ");\n";
2074 }
2075 break;
2076 }
2077 case SERVER_API_EXIT:
2078 {
2079 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07002080 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002081 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07002082 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002083 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002084 }
2085 break;
2086 }
2087 case CLIENT_API_ENTRY:
2088 {
2089 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2090 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002091 out << "_hidl_args.push_back((void *)&"
2092 << arg->name()
2093 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002094 }
2095 break;
2096 }
2097 case CLIENT_API_EXIT:
2098 {
2099 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2100 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002101 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002102 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002103 << "_hidl_out_"
2104 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002105 << ");\n";
2106 }
2107 break;
2108 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002109 case PASSTHROUGH_ENTRY:
2110 {
2111 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2112 for (const auto &arg : method->args()) {
2113 out << "_hidl_args.push_back((void *)&"
2114 << arg->name()
2115 << ");\n";
2116 }
2117 break;
2118 }
2119 case PASSTHROUGH_EXIT:
2120 {
2121 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002122 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002123 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002124 << arg->name()
2125 << ");\n";
2126 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002127 break;
2128 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002129 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002130 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002131 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002132 return UNKNOWN_ERROR;
2133 }
2134 }
2135
Steven Moreland031ccf12016-10-31 15:54:38 -07002136 const Interface *iface = mRootScope->getInterface();
2137
Steven Moreland1ab31442016-11-03 18:37:51 -07002138 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002139 out.indent();
2140 out << "callback("
2141 << event_str
2142 << ", \""
2143 << mPackage.package()
2144 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002145 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002146 << "\", \""
2147 << iface->localName()
2148 << "\", \""
2149 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002150 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002151 out.unindent();
2152 out << "}\n";
2153 out.unindent();
2154 out << "}\n\n";
2155
2156 return OK;
2157}
2158
Andreas Huber881227d2016-08-02 14:20:21 -07002159} // namespace android