blob: 36d205ddac6ee22dd53a468aaeb32b65445509d3 [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 Morelandf10af872017-01-25 16:01:56 +0000172 out << "::android::sp<" << interfaceName << "> iface = nullptr;\n";
Yifan Hongd3b58ed2017-01-30 14:13:10 -0800173 out << "::android::vintf::Transport transport = ::android::hardware::getTransport("
Yifan Hong152866b2017-02-28 15:34:27 -0800174 << interfaceName << "::descriptor, serviceName);\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000175
Steven Moreland34955d62017-03-30 16:30:35 -0700176 out << "const bool vintfHwbinder = (transport == ::android::vintf::Transport::HWBINDER);\n"
177 << "const bool vintfPassthru = (transport == ::android::vintf::Transport::PASSTHROUGH);\n"
Yifan Hong31f07ff2017-03-21 18:56:35 +0000178 << "const bool vintfEmpty = (transport == ::android::vintf::Transport::EMPTY);\n\n";
179
180 // if (getStub) {
181 // getPassthroughServiceManager()->get only once.
182 // } else {
183 // if (vintfHwbinder) {
184 // while (no alive service) {
185 // waitForHwService
186 // defaultServiceManager()->get
187 // }
188 // } else if (vintfEmpty) {
189 // defaultServiceManager()->get only once.
190 // getPassthroughServiceManager()->get only once.
191 // } else if (vintfPassthru) {
192 // getPassthroughServiceManager()->get only once.
193 // }
194 // }
195
Yifan Hongf1ef44f2017-03-23 17:17:57 +0000196 out << "bool tried = false;\n";
197 out.sWhile("!getStub && (vintfHwbinder || (vintfEmpty && !tried))", [&] {
Yifan Hong31f07ff2017-03-21 18:56:35 +0000198
199 out.sIf("tried", [&] {
200 // sleep only after the first trial.
201 out << "ALOGI(\"getService: retrying in 1s...\");\n"
202 << "sleep(1);\n";
203 }).endl();
204
Yifan Hongf1ef44f2017-03-23 17:17:57 +0000205 out << "tried = true;\n";
206
Steven Morelandf10af872017-01-25 16:01:56 +0000207 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800208 out.indent(2, [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000209 out << "= ::android::hardware::defaultServiceManager();\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800210 });
Yifan Hong31f07ff2017-03-21 18:56:35 +0000211 out.sIf("sm == nullptr", [&] {
212 // hwbinder is not available on this device, so future tries
213 // would also be null. I can only "break" here and
214 // (vintfEmpty) try passthrough or (vintfHwbinder) return nullptr.
215 out << "ALOGE(\"getService: defaultServiceManager() is null\");\n"
216 << "break;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800217 }).endl();
Yifan Hong31f07ff2017-03-21 18:56:35 +0000218
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700219 if (!isTry) {
220 out.sIf("vintfHwbinder", [&] {
221 out << "::android::hardware::details::waitForHwService("
222 << interfaceName << "::descriptor" << ", serviceName);\n";
223 }).endl();
224 }
Yifan Hong31f07ff2017-03-21 18:56:35 +0000225
226 out << "::android::hardware::Return<::android::sp<"
227 << gIBaseFqName.cppName() << ">> ret = \n";
228 out.indent(2, [&] {
229 out << "sm->get(" << interfaceName << "::descriptor, serviceName);\n";
230 });
231
232 out.sIf("!ret.isOk()", [&] {
Steven Moreland42394ce2017-03-27 17:03:04 -0700233 // hwservicemanager fails, may be security issue
Yifan Hong31f07ff2017-03-21 18:56:35 +0000234 out << "ALOGE(\"getService: defaultServiceManager()->get returns %s\", "
235 << "ret.description().c_str());\n"
Steven Moreland42394ce2017-03-27 17:03:04 -0700236 << "break;\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000237 }).endl();
238
Yifan Hong7783bb02017-03-29 03:39:09 -0700239 out << "::android::sp<" << gIBaseFqName.cppName() << "> base = ret;\n";
240 out.sIf("base == nullptr", [&] {
241 // race condition. hwservicemanager drops the service
242 // from waitForHwService to here
Steven Morelanddff644c2017-03-24 10:59:01 -0700243 out << "ALOGW(\"getService: found null hwbinder interface\");\n"
Yifan Hongdd0b55d2017-04-04 13:27:25 -0700244 << (isTry ? "break" : "continue")
245 << ";\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000246 }).endl();
Yifan Hong7783bb02017-03-29 03:39:09 -0700247 out << "::android::hardware::Return<::android::sp<" << interfaceName
248 << ">> castRet = " << interfaceName << "::castFrom(base, true /* emitError */);\n";
249 out.sIf("!castRet.isOk()", [&] {
250 out.sIf("castRet.isDeadObject()", [&] {
251 // service is dead (castFrom cannot call interfaceChain)
252 out << "ALOGW(\"getService: found dead hwbinder service\");\n"
Yifan Hongdd0b55d2017-04-04 13:27:25 -0700253 << (isTry ? "break" : "continue")
254 << ";\n";
Yifan Hong7783bb02017-03-29 03:39:09 -0700255 }).sElse([&] {
256 out << "ALOGW(\"getService: cannot call into hwbinder service: %s"
257 << "; No permission? Check for selinux denials.\", "
258 << "castRet.description().c_str());\n"
259 << "break;\n";
260 }).endl();
261 }).endl();
262 out << "iface = castRet;\n";
263 out.sIf("iface == nullptr", [&] {
264 // returned service isn't of correct type; this is a bug
265 // to hwservicemanager or to the service itself (interfaceChain
266 // is not consistent).
267 out << "ALOGW(\"getService: received incompatible service; bug in hwservicemanager?\");\n"
Yifan Hong31f07ff2017-03-21 18:56:35 +0000268 << "break;\n";
269 }).endl();
270
271 out << "return iface;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800272 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800273
Yifan Hong31f07ff2017-03-21 18:56:35 +0000274 out.sIf("getStub || vintfPassthru || vintfEmpty", [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000275 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> pm\n";
Steven Morelande3fa5da2017-01-25 07:07:53 +0000276 out.indent(2, [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000277 out << "= ::android::hardware::getPassthroughServiceManager();\n";
Steven Morelande3fa5da2017-01-25 07:07:53 +0000278 });
Steven Morelandf10af872017-01-25 16:01:56 +0000279
280 out.sIf("pm != nullptr", [&] () {
281 out << "::android::hardware::Return<::android::sp<" << gIBaseFqName.cppName() << ">> ret = \n";
282 out.indent(2, [&] {
283 out << "pm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
Steven Moreland2c2dea82017-01-18 17:24:17 -0800284 });
Steven Morelandf10af872017-01-25 16:01:56 +0000285 out.sIf("ret.isOk()", [&] {
286 out << "::android::sp<" << gIBaseFqName.cppName()
287 << "> baseInterface = ret;\n";
288 out.sIf("baseInterface != nullptr", [&]() {
289 out << "iface = new " << fqName.getInterfacePassthroughName()
290 << "(" << interfaceName << "::castFrom(baseInterface));\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000291 }).endl();
Steven Morelandf10af872017-01-25 16:01:56 +0000292 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800293 }).endl();
294 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800295
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800296 out << "return iface;\n";
297 }).endl().endl();
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700298}
299
300static void implementServiceManagerInteractions(Formatter &out,
301 const FQName &fqName, const std::string &package) {
302
303 const std::string interfaceName = fqName.getInterfaceName();
304
305 implementGetService(out, fqName, true /* isTry */);
306 implementGetService(out, fqName, false /* isTry */);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800307
Yifan Hongeefe4f22017-01-04 15:32:42 -0800308 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800309 << "const std::string &serviceName) ";
310 out.block([&] {
311 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
312 out.indent(2, [&] {
313 out << "= ::android::hardware::defaultServiceManager();\n";
314 });
315 out.sIf("sm == nullptr", [&] {
316 out << "return ::android::INVALID_OPERATION;\n";
317 }).endl();
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100318 out << "::android::hardware::Return<bool> ret = "
319 << "sm->add(serviceName.c_str(), this);\n"
320 << "return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800321 }).endl().endl();
322
Yifan Hongeefe4f22017-01-04 15:32:42 -0800323 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800324 out.indent(2, [&] {
325 out << "const std::string &serviceName,\n"
326 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
327 << "&notification) ";
328 });
329 out.block([&] {
330 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 false;\n";
336 }).endl();
337 out << "::android::hardware::Return<bool> success =\n";
338 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800339 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800340 out.indent(2, [&] {
341 out << "serviceName, notification);\n";
342 });
343 });
344 out << "return success.isOk() && success;\n";
345 }).endl().endl();
346}
347
Andreas Huberb82318c2016-08-02 14:45:54 -0700348status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700349
Andreas Huberb82318c2016-08-02 14:45:54 -0700350 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700351 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700352 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700353
354 std::string ifaceName;
355 bool isInterface = true;
356 if (!AST::isInterface(&ifaceName)) {
357 ifaceName = "types";
358 isInterface = false;
359 }
360 path.append(ifaceName);
361 path.append(".h");
362
Andreas Huberd2943e12016-08-05 11:59:31 -0700363 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700364 FILE *file = fopen(path.c_str(), "w");
365
366 if (file == NULL) {
367 return -errno;
368 }
369
370 Formatter out(file);
371
372 const std::string guard = makeHeaderGuard(ifaceName);
373
374 out << "#ifndef " << guard << "\n";
375 out << "#define " << guard << "\n\n";
376
Andreas Huber737080b2016-08-02 15:38:04 -0700377 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700378 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700379 }
380
381 if (!mImportedNames.empty()) {
382 out << "\n";
383 }
384
Steven Moreland0693f312016-11-09 15:06:14 -0800385 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800386 if (isIBase()) {
387 out << "// skipped #include IServiceNotification.h\n\n";
388 } else {
389 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
390 }
Steven Moreland0693f312016-11-09 15:06:14 -0800391 }
392
Yifan Hongc8934042016-11-17 17:10:52 -0800393 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700394 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700395
396 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200397 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700398 }
399
Martijn Coenenaf712c02016-11-16 15:26:27 +0100400 out << "#include <utils/NativeHandle.h>\n";
401 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700402
403 enterLeaveNamespace(out, true /* enter */);
404 out << "\n";
405
406 if (isInterface) {
407 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700408 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700409
410 const Interface *iface = mRootScope->getInterface();
411 const Interface *superType = iface->superType();
412
Steven Moreland40786312016-08-16 10:29:40 -0700413 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800414 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700415 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000416 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700417 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700418 }
419
420 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700421
422 out.indent();
423
Andreas Huber881227d2016-08-02 14:20:21 -0700424 }
425
426 status_t err = emitTypeDeclarations(out);
427
428 if (err != OK) {
429 return err;
430 }
431
432 if (isInterface) {
433 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800434
Yifan Hongc8934042016-11-17 17:10:52 -0800435 out << "virtual bool isRemote() const ";
436 if (!isIBase()) {
437 out << "override ";
438 }
439 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800440
Andreas Huber881227d2016-08-02 14:20:21 -0700441 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700442 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700443
Andreas Huber881227d2016-08-02 14:20:21 -0700444 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800445 const TypedVar *elidedReturn = method->canElideCallback();
446
447 if (elidedReturn == nullptr && returnsValue) {
448 out << "using "
449 << method->name()
Yifan Hong7d234ea2017-03-30 15:40:22 -0700450 << "_cb = std::function<void(";
451 method->emitCppResultSignature(out, true /* specify namespaces */);
452 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800453 }
Andreas Huber881227d2016-08-02 14:20:21 -0700454
Andreas Huber3599d922016-08-09 10:42:57 -0700455 method->dumpAnnotations(out);
456
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700457 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700458 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700459 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700460 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700461 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700462 }
463
464 out << method->name()
Yifan Hong7d234ea2017-03-30 15:40:22 -0700465 << "(";
466 method->emitCppArgSignature(out, true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700467
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700468 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700469 if (!method->args().empty()) {
470 out << ", ";
471 }
472
Steven Moreland67f67b42016-09-29 08:59:02 -0700473 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700474 }
475
Yifan Hong10fe0b52016-10-19 14:20:17 -0700476 out << ")";
477 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800478 if (!isIBase()) {
479 out << " override";
480 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700481 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700482 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700483 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700484 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700485 }
Steven Moreland40786312016-08-16 10:29:40 -0700486
Yifan Hong3d746092016-12-07 14:26:33 -0800487 out << "// cast static functions\n";
488 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700489
Yifan Hong3d746092016-12-07 14:26:33 -0800490 for (const Interface *superType : iface->typeChain()) {
Yifan Hong7783bb02017-03-29 03:39:09 -0700491 out << "static ::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -0800492 << childTypeResult
Yifan Hong7783bb02017-03-29 03:39:09 -0700493 << "> castFrom("
Yifan Hong3d746092016-12-07 14:26:33 -0800494 << superType->getCppArgumentType()
495 << " parent"
Yifan Hong7783bb02017-03-29 03:39:09 -0700496 << ", bool emitError = false);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700497 }
498
Steven Morelandd39133b2016-11-11 12:30:08 -0800499 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700500
Yifan Hongc8934042016-11-17 17:10:52 -0800501 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800502 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800503 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800504 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800505 }
Andreas Huber881227d2016-08-02 14:20:21 -0700506 }
507
508 if (isInterface) {
509 out.unindent();
510
Andreas Hubere3f769a2016-10-10 10:54:44 -0700511 out << "};\n\n";
512 }
513
514 err = mRootScope->emitGlobalTypeDeclarations(out);
515
516 if (err != OK) {
517 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700518 }
519
520 out << "\n";
521 enterLeaveNamespace(out, false /* enter */);
522
523 out << "\n#endif // " << guard << "\n";
524
525 return OK;
526}
527
Steven Moreland40786312016-08-16 10:29:40 -0700528status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
529 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800530 bool isInterface = AST::isInterface(&ifaceName);
531 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800532 std::string klassName{};
533
534 if(isInterface) {
535 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800536 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800537 } else {
538 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700539 }
540
Steven Moreland40786312016-08-16 10:29:40 -0700541 std::string path = outputPath;
542 path.append(mCoordinator->convertPackageRootToPath(mPackage));
543 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
544 path.append(klassName + ".h");
545
Yifan Hong244e82d2016-11-11 11:13:57 -0800546 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700547
548 if (file == NULL) {
549 return -errno;
550 }
551
552 Formatter out(file);
553
554 const std::string guard = makeHeaderGuard(klassName);
555
556 out << "#ifndef " << guard << "\n";
557 out << "#define " << guard << "\n\n";
558
Yifan Hong244e82d2016-11-11 11:13:57 -0800559 if (isInterface) {
560 generateCppPackageInclude(out, mPackage, ifaceName);
561 } else {
562 generateCppPackageInclude(out, mPackage, "types");
563 }
Steven Moreland40786312016-08-16 10:29:40 -0700564
Steven Morelandee88eed2016-10-31 17:49:00 -0700565 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700566
567 for (const auto &item : mImportedNames) {
568 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800569 generateCppPackageInclude(out, item, "hwtypes");
570 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800571 generateCppPackageInclude(out, item, item.getInterfaceStubName());
572 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700573 }
Steven Moreland40786312016-08-16 10:29:40 -0700574 }
575
576 out << "\n";
577
Martijn Coenen93915102016-09-01 01:35:52 +0200578 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700579 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100580 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700581
582 out << "\n";
583
584 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700585
Yifan Hong244e82d2016-11-11 11:13:57 -0800586 status_t err = mRootScope->emitGlobalHwDeclarations(out);
587 if (err != OK) {
588 return err;
589 }
Steven Moreland40786312016-08-16 10:29:40 -0700590
591 enterLeaveNamespace(out, false /* enter */);
592
593 out << "\n#endif // " << guard << "\n";
594
595 return OK;
596}
597
Andreas Huber881227d2016-08-02 14:20:21 -0700598status_t AST::emitTypeDeclarations(Formatter &out) const {
599 return mRootScope->emitTypeDeclarations(out);
600}
601
Yifan Hong7a118f52016-12-07 11:21:15 -0800602static void wrapPassthroughArg(Formatter &out,
603 const TypedVar *arg, bool addPrefixToName,
604 std::function<void(void)> handleError) {
605 if (!arg->type().isInterface()) {
606 return;
607 }
608 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
609 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
610 + arg->name();
611 const Interface &iface = static_cast<const Interface &>(arg->type());
612 out << iface.getCppStackType() << " " << wrappedName << ";\n";
613 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
614 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
615 out << wrappedName
616 << " = "
617 << iface.fqName().cppName()
Yifan Hong052425a2017-03-13 17:06:13 -0700618 << "::castFrom(::android::hardware::details::wrapPassthrough("
Yifan Hong7a118f52016-12-07 11:21:15 -0800619 << name << "));\n";
620 out.sIf(wrappedName + " == nullptr", [&] {
621 // Fatal error. Happens when the BsFoo class is not found in the binary
622 // or any dynamic libraries.
623 handleError();
624 }).endl();
625 }).sElse([&] {
626 out << wrappedName << " = " << name << ";\n";
627 }).endl().endl();
628}
629
Steven Moreland69e7c702016-09-09 11:16:32 -0700630status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700631 const Method *method) const {
632 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700633
634 out << " {\n";
635 out.indent();
636
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800637 if (method->isHidlReserved()
638 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
639 method->cppImpl(IMPL_PASSTHROUGH, out);
640 out.unindent();
641 out << "}\n\n";
642 return OK;
643 }
644
Steven Moreland69e7c702016-09-09 11:16:32 -0700645 const bool returnsValue = !method->results().empty();
646 const TypedVar *elidedReturn = method->canElideCallback();
647
Steven Moreland67f67b42016-09-29 08:59:02 -0700648 if (returnsValue && elidedReturn == nullptr) {
649 generateCheckNonNull(out, "_hidl_cb");
650 }
651
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700652 generateCppInstrumentationCall(
653 out,
654 InstrumentationEvent::PASSTHROUGH_ENTRY,
655 method);
656
Yifan Hong7a118f52016-12-07 11:21:15 -0800657
658 for (const auto &arg : method->args()) {
659 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
660 out << "return ::android::hardware::Status::fromExceptionCode(\n";
661 out.indent(2, [&] {
662 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800663 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800664 });
665 });
666 }
667
668 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700669 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700670
671 if (method->isOneway()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800672 out << "addOnewayTask([this, &_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700673 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800674 out << ", "
675 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
676 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700677 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700678 out << "] {\n";
679 out.indent();
680 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700681 }
682
683 out << "mImpl->"
684 << method->name()
685 << "(";
686
Yifan Hong7d234ea2017-03-30 15:40:22 -0700687 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800688 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700689 });
Steven Moreland69e7c702016-09-09 11:16:32 -0700690 if (returnsValue && elidedReturn == nullptr) {
691 if (!method->args().empty()) {
692 out << ", ";
693 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800694 out << "[&](";
Yifan Hong7d234ea2017-03-30 15:40:22 -0700695 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800696 out << "const auto &_hidl_out_"
697 << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700698 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800699
700 out << ") {\n";
701 out.indent();
702 status_t status = generateCppInstrumentationCall(
703 out,
704 InstrumentationEvent::PASSTHROUGH_EXIT,
705 method);
706 if (status != OK) {
707 return status;
708 }
709
Yifan Hong7a118f52016-12-07 11:21:15 -0800710 for (const auto &arg : method->results()) {
711 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
712 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
713 out.indent(2, [&] {
714 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800715 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800716 });
717 out << "return;\n";
718 });
719 }
720
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800721 out << "_hidl_cb(";
Yifan Hong7d234ea2017-03-30 15:40:22 -0700722 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800723 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
724 << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700725 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800726 out << ");\n";
727 out.unindent();
728 out << "});\n\n";
729 } else {
730 out << ");\n\n";
731 if (elidedReturn != nullptr) {
732 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800733 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800734 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000735 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800736 }
737 status_t status = generateCppInstrumentationCall(
738 out,
739 InstrumentationEvent::PASSTHROUGH_EXIT,
740 method);
741 if (status != OK) {
742 return status;
743 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700744 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700745
746 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700747 out.unindent();
748 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700749 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700750
751 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700752
753 out.unindent();
754 out << "}\n";
755
756 return OK;
757}
758
Yifan Hong068c5522016-10-31 14:07:25 -0700759status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700760
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700761 const Interface *iface = mRootScope->getInterface();
762
Yifan Hong10fe0b52016-10-19 14:20:17 -0700763 const Interface *prevIterface = nullptr;
764 for (const auto &tuple : iface->allMethodsFromRoot()) {
765 const Method *method = tuple.method();
766 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700767
Yifan Hong10fe0b52016-10-19 14:20:17 -0700768 if(prevIterface != superInterface) {
769 if (prevIterface != nullptr) {
770 out << "\n";
771 }
772 out << "// Methods from "
773 << superInterface->fullName()
774 << " follow.\n";
775 prevIterface = superInterface;
776 }
Yifan Hong068c5522016-10-31 14:07:25 -0700777 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700778
Yifan Hong10fe0b52016-10-19 14:20:17 -0700779 if (err != OK) {
780 return err;
781 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700782 }
783
Yifan Hong10fe0b52016-10-19 14:20:17 -0700784 out << "\n";
785
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700786 return OK;
787}
788
Andreas Huberb82318c2016-08-02 14:45:54 -0700789status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700790 std::string ifaceName;
791 if (!AST::isInterface(&ifaceName)) {
792 // types.hal does not get a stub header.
793 return OK;
794 }
795
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700796 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800797 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700798
Andreas Huberb82318c2016-08-02 14:45:54 -0700799 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700800 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700801 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700802 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700803 path.append(".h");
804
Andreas Huberd2943e12016-08-05 11:59:31 -0700805 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700806 FILE *file = fopen(path.c_str(), "w");
807
808 if (file == NULL) {
809 return -errno;
810 }
811
812 Formatter out(file);
813
Steven Moreland40786312016-08-16 10:29:40 -0700814 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700815
816 out << "#ifndef " << guard << "\n";
817 out << "#define " << guard << "\n\n";
818
Yifan Hongeefe4f22017-01-04 15:32:42 -0800819 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700820 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700821
822 enterLeaveNamespace(out, true /* enter */);
823 out << "\n";
824
825 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800826 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100827 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800828 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000829 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100830 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800831 out << " : public "
832 << gIBaseFqName.getInterfaceStubFqName().cppName()
833 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100834 }
Andreas Huber881227d2016-08-02 14:20:21 -0700835
836 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800837 out << "explicit "
838 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700839 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100840 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800841 out << "explicit "
842 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100843 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800844 << " const std::string& HidlInstrumentor_package,"
845 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700846 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700847 out << "::android::status_t onTransact(\n";
848 out.indent();
849 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700850 out << "uint32_t _hidl_code,\n";
851 out << "const ::android::hardware::Parcel &_hidl_data,\n";
852 out << "::android::hardware::Parcel *_hidl_reply,\n";
853 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700854 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700855 out.unindent();
856 out.unindent();
857
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100858 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
859 out.unindent();
860 out << "private:\n";
861 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800862
863 status_t err = generateMethods(out, [&](const Method *method, const Interface *iface) {
864 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
865 return OK;
866 }
867 const bool returnsValue = !method->results().empty();
868 const TypedVar *elidedReturn = method->canElideCallback();
869
870 if (elidedReturn == nullptr && returnsValue) {
871 out << "using " << method->name() << "_cb = "
872 << iface->fqName().cppName()
873 << "::" << method->name() << "_cb;\n";
874 }
875 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800876 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800877 return OK;
878 });
879 if (err != OK) {
880 return err;
881 }
882
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100883 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700884 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700885 out << "};\n\n";
886
887 enterLeaveNamespace(out, false /* enter */);
888
889 out << "\n#endif // " << guard << "\n";
890
891 return OK;
892}
893
Andreas Huberb82318c2016-08-02 14:45:54 -0700894status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700895 std::string ifaceName;
896 if (!AST::isInterface(&ifaceName)) {
897 // types.hal does not get a proxy header.
898 return OK;
899 }
900
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700901 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800902 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700903
Andreas Huberb82318c2016-08-02 14:45:54 -0700904 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700905 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700906 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800907 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700908 path.append(".h");
909
Andreas Huberd2943e12016-08-05 11:59:31 -0700910 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700911 FILE *file = fopen(path.c_str(), "w");
912
913 if (file == NULL) {
914 return -errno;
915 }
916
917 Formatter out(file);
918
Yifan Hongeefe4f22017-01-04 15:32:42 -0800919 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700920
921 out << "#ifndef " << guard << "\n";
922 out << "#define " << guard << "\n\n";
923
Martijn Coenen115d4282016-12-19 05:14:04 +0100924 out << "#include <hidl/HidlTransportSupport.h>\n\n";
925
Andreas Huber881227d2016-08-02 14:20:21 -0700926 std::vector<std::string> packageComponents;
927 getPackageAndVersionComponents(
928 &packageComponents, false /* cpp_compatible */);
929
Yifan Hongeefe4f22017-01-04 15:32:42 -0800930 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700931 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700932
933 enterLeaveNamespace(out, true /* enter */);
934 out << "\n";
935
936 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800937 << proxyName
938 << " : public ::android::hardware::BpInterface<"
939 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000940 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700941
942 out.indent();
943
Yifan Hongeefe4f22017-01-04 15:32:42 -0800944 out << "explicit "
945 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700946 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700947 << "\n\n";
948
Yifan Hong10fe0b52016-10-19 14:20:17 -0700949 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700950
Yifan Hong068c5522016-10-31 14:07:25 -0700951 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
952 method->generateCppSignature(out);
953 out << " override;\n";
954 return OK;
955 });
Steven Moreland9c387612016-09-07 09:54:26 -0700956
957 if (err != OK) {
958 return err;
959 }
Andreas Huber881227d2016-08-02 14:20:21 -0700960
961 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100962 out << "private:\n";
963 out.indent();
964 out << "std::mutex _hidl_mMutex;\n"
965 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
966 << " _hidl_mDeathRecipients;\n";
967 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700968 out << "};\n\n";
969
970 enterLeaveNamespace(out, false /* enter */);
971
972 out << "\n#endif // " << guard << "\n";
973
974 return OK;
975}
976
Andreas Huberb82318c2016-08-02 14:45:54 -0700977status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700978
Andreas Huberb82318c2016-08-02 14:45:54 -0700979 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700980 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700981 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700982
983 std::string ifaceName;
984 std::string baseName;
985
Yifan Hongfe95aa22016-10-19 17:26:45 -0700986 const Interface *iface = nullptr;
987 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700988 if (!AST::isInterface(&ifaceName)) {
989 baseName = "types";
990 isInterface = false;
991 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700992 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700993 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700994 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700995 }
996
997 path.append(baseName);
998
999 if (baseName != "types") {
1000 path.append("All");
1001 }
1002
1003 path.append(".cpp");
1004
Andreas Huberd2943e12016-08-05 11:59:31 -07001005 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -07001006 FILE *file = fopen(path.c_str(), "w");
1007
1008 if (file == NULL) {
1009 return -errno;
1010 }
1011
1012 Formatter out(file);
1013
Steven Moreland623c0042017-01-13 14:42:29 -08001014 out << "#define LOG_TAG \""
1015 << mPackage.string() << "::" << baseName
1016 << "\"\n\n";
1017
Steven Moreland05cd4232016-11-21 16:01:12 -08001018 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001019 out << "#include <cutils/trace.h>\n";
1020 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001021 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -07001022 // This is a no-op for IServiceManager itself.
1023 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
1024
Steven Morelandbec74ed2017-01-25 17:42:35 -08001025 // TODO(b/34274385) remove this
1026 out << "#include <hidl/LegacySupport.h>\n";
1027
Yifan Hongeefe4f22017-01-04 15:32:42 -08001028 generateCppPackageInclude(out, mPackage, iface->getProxyName());
1029 generateCppPackageInclude(out, mPackage, iface->getStubName());
1030 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001031
1032 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -07001033 generateCppPackageInclude(out,
1034 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -08001035 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001036 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -08001037
1038 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001039 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -07001040 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -08001041 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -07001042 }
1043
1044 out << "\n";
1045
1046 enterLeaveNamespace(out, true /* enter */);
1047 out << "\n";
1048
1049 status_t err = generateTypeSource(out, ifaceName);
1050
1051 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001052 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001053
1054 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -08001055 out << "const char* "
1056 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -07001057 << "::descriptor(\""
1058 << iface->fqName().string()
1059 << "\");\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +01001060 out << "__attribute__((constructor))";
1061 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001062 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001063 out << "::android::hardware::details::gBnConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001064 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001065 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001066 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001067 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001068 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001069 out << "return new "
1070 << iface->getStubName()
1071 << "(reinterpret_cast<"
1072 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001073 << " *>(iIntf));\n";
1074 });
Yifan Hongb04de382017-02-06 15:31:52 -08001075 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001076 });
Yifan Honga159f3b2017-03-16 14:53:51 -07001077 out << "::android::hardware::details::gBsConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001078 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001079 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001080 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001081 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -08001082 << gIBaseFqName.cppName()
1083 << "> {\n";
1084 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001085 out << "return new "
1086 << iface->getPassthroughName()
1087 << "(reinterpret_cast<"
1088 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001089 << " *>(iIntf));\n";
1090 });
Yifan Hongb04de382017-02-06 15:31:52 -08001091 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001092 });
Yifan Hong158655a2016-11-08 12:34:07 -08001093 });
Martijn Coenen8adcb652017-02-03 17:37:36 +01001094 out << "};\n\n";
1095 out << "__attribute__((destructor))";
1096 out << "static void static_destructor() {\n";
1097 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001098 out << "::android::hardware::details::gBnConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001099 << iface->localName()
1100 << "::descriptor);\n";
Yifan Honga159f3b2017-03-16 14:53:51 -07001101 out << "::android::hardware::details::gBsConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001102 << iface->localName()
1103 << "::descriptor);\n";
1104 });
1105 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001106
Yifan Hongfe95aa22016-10-19 17:26:45 -07001107 err = generateInterfaceSource(out);
1108 }
1109
1110 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001111 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001112 }
1113
1114 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001115 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001116 }
1117
Steven Moreland40786312016-08-16 10:29:40 -07001118 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001119 err = generatePassthroughSource(out);
1120 }
1121
1122 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001123 const Interface *iface = mRootScope->getInterface();
1124
Yifan Hongc8934042016-11-17 17:10:52 -08001125 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001126 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001127 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001128 std::string package = iface->fqName().package()
1129 + iface->fqName().atVersion();
1130
Yifan Hongeefe4f22017-01-04 15:32:42 -08001131 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001132 }
Steven Moreland40786312016-08-16 10:29:40 -07001133 }
1134
Andreas Huber02ef12f2017-04-06 11:09:07 -07001135 HidlTypeAssertion::EmitAll(out);
1136 out << "\n";
1137
Andreas Huber881227d2016-08-02 14:20:21 -07001138 enterLeaveNamespace(out, false /* enter */);
1139
1140 return err;
1141}
1142
Steven Moreland67f67b42016-09-29 08:59:02 -07001143// static
1144void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001145 out.sIf(nonNull + " == nullptr", [&] {
1146 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1147 out.indent(2, [&] {
1148 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1149 });
1150 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001151}
1152
Andreas Huber881227d2016-08-02 14:20:21 -07001153status_t AST::generateTypeSource(
1154 Formatter &out, const std::string &ifaceName) const {
1155 return mRootScope->emitTypeDefinitions(out, ifaceName);
1156}
1157
Andreas Hubere7ff2282016-08-16 13:50:03 -07001158void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001159 Formatter &out,
1160 const std::vector<TypedVar *> &args,
1161 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001162 if (args.empty()) {
1163 return;
1164 }
1165
1166 for (const auto &arg : args) {
1167 const Type &type = arg->type();
1168
Yifan Hong3b320f82016-11-01 15:15:54 -07001169 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001170 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001171 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001172 << ";\n";
1173 }
1174
1175 out << "\n";
1176}
1177
Andreas Huber881227d2016-08-02 14:20:21 -07001178void AST::emitCppReaderWriter(
1179 Formatter &out,
1180 const std::string &parcelObj,
1181 bool parcelObjIsPointer,
1182 const TypedVar *arg,
1183 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001184 Type::ErrorMode mode,
1185 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001186 const Type &type = arg->type();
1187
Andreas Huber881227d2016-08-02 14:20:21 -07001188 type.emitReaderWriter(
1189 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001190 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001191 parcelObj,
1192 parcelObjIsPointer,
1193 isReader,
1194 mode);
1195}
1196
Yifan Hongbf459bc2016-08-23 16:50:37 -07001197void AST::emitCppResolveReferences(
1198 Formatter &out,
1199 const std::string &parcelObj,
1200 bool parcelObjIsPointer,
1201 const TypedVar *arg,
1202 bool isReader,
1203 Type::ErrorMode mode,
1204 bool addPrefixToName) const {
1205 const Type &type = arg->type();
1206 if(type.needsResolveReferences()) {
1207 type.emitResolveReferences(
1208 out,
1209 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1210 isReader, // nameIsPointer
1211 parcelObj,
1212 parcelObjIsPointer,
1213 isReader,
1214 mode);
1215 }
1216}
1217
Yifan Hong068c5522016-10-31 14:07:25 -07001218status_t AST::generateProxyMethodSource(Formatter &out,
1219 const std::string &klassName,
1220 const Method *method,
1221 const Interface *superInterface) const {
1222
1223 method->generateCppSignature(out,
1224 klassName,
1225 true /* specify namespaces */);
1226
1227 const bool returnsValue = !method->results().empty();
1228 const TypedVar *elidedReturn = method->canElideCallback();
1229
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001230 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001231
1232 out.indent();
1233
Martijn Coenen115d4282016-12-19 05:14:04 +01001234 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1235 method->cppImpl(IMPL_PROXY, out);
1236 out.unindent();
1237 out << "}\n\n";
1238 return OK;
1239 }
1240
Yifan Hong068c5522016-10-31 14:07:25 -07001241 if (returnsValue && elidedReturn == nullptr) {
1242 generateCheckNonNull(out, "_hidl_cb");
1243 }
1244
1245 status_t status = generateCppInstrumentationCall(
1246 out,
1247 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001248 method);
1249 if (status != OK) {
1250 return status;
1251 }
1252
1253 out << "::android::hardware::Parcel _hidl_data;\n";
1254 out << "::android::hardware::Parcel _hidl_reply;\n";
1255 out << "::android::status_t _hidl_err;\n";
1256 out << "::android::hardware::Status _hidl_status;\n\n";
1257
1258 declareCppReaderLocals(
1259 out, method->results(), true /* forResults */);
1260
1261 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001262 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001263 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001264 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1265
Martijn Coenenfff73352017-01-04 16:36:31 +01001266 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001267 // First DFS: write all buffers and resolve pointers for parent
1268 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001269 if (arg->type().isInterface()) {
1270 hasInterfaceArgument = true;
1271 }
Yifan Hong068c5522016-10-31 14:07:25 -07001272 emitCppReaderWriter(
1273 out,
1274 "_hidl_data",
1275 false /* parcelObjIsPointer */,
1276 arg,
1277 false /* reader */,
1278 Type::ErrorMode_Goto,
1279 false /* addPrefixToName */);
1280 }
1281
1282 // Second DFS: resolve references.
1283 for (const auto &arg : method->args()) {
1284 emitCppResolveReferences(
1285 out,
1286 "_hidl_data",
1287 false /* parcelObjIsPointer */,
1288 arg,
1289 false /* reader */,
1290 Type::ErrorMode_Goto,
1291 false /* addPrefixToName */);
1292 }
1293
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001294 if (hasInterfaceArgument) {
1295 // Start binder threadpool to handle incoming transactions
1296 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1297 }
Yifan Hong068c5522016-10-31 14:07:25 -07001298 out << "_hidl_err = remote()->transact("
1299 << method->getSerialId()
1300 << " /* "
1301 << method->name()
1302 << " */, _hidl_data, &_hidl_reply";
1303
1304 if (method->isOneway()) {
1305 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1306 }
1307 out << ");\n";
1308
1309 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1310
1311 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001312 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001313 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1314 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1315
1316
1317 // First DFS: write all buffers and resolve pointers for parent
1318 for (const auto &arg : method->results()) {
1319 emitCppReaderWriter(
1320 out,
1321 "_hidl_reply",
1322 false /* parcelObjIsPointer */,
1323 arg,
1324 true /* reader */,
1325 Type::ErrorMode_Goto,
1326 true /* addPrefixToName */);
1327 }
1328
1329 // Second DFS: resolve references.
1330 for (const auto &arg : method->results()) {
1331 emitCppResolveReferences(
1332 out,
1333 "_hidl_reply",
1334 false /* parcelObjIsPointer */,
1335 arg,
1336 true /* reader */,
1337 Type::ErrorMode_Goto,
1338 true /* addPrefixToName */);
1339 }
1340
1341 if (returnsValue && elidedReturn == nullptr) {
1342 out << "_hidl_cb(";
1343
Yifan Hong7d234ea2017-03-30 15:40:22 -07001344 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001345 if (arg->type().resultNeedsDeref()) {
1346 out << "*";
1347 }
1348 out << "_hidl_out_" << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001349 });
Yifan Hong068c5522016-10-31 14:07:25 -07001350
1351 out << ");\n\n";
1352 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001353 }
1354 status = generateCppInstrumentationCall(
1355 out,
1356 InstrumentationEvent::CLIENT_API_EXIT,
1357 method);
1358 if (status != OK) {
1359 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001360 }
1361
1362 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001363 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1364 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001365 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001366 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1367 } else {
1368 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1369 out << "return ::android::hardware::Return<void>();\n\n";
1370 }
1371
1372 out.unindent();
1373 out << "_hidl_error:\n";
1374 out.indent();
1375 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1376 out << "return ::android::hardware::Return<";
1377 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001378 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001379 } else {
1380 out << "void";
1381 }
1382 out << ">(_hidl_status);\n";
1383
1384 out.unindent();
1385 out << "}\n\n";
1386 return OK;
1387}
1388
Andreas Huber881227d2016-08-02 14:20:21 -07001389status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001390 Formatter &out, const FQName &fqName) const {
1391 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001392
1393 out << klassName
1394 << "::"
1395 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001396 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001397
1398 out.indent();
1399 out.indent();
1400
1401 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001402 << "<"
1403 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001404 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001405 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001406 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001407 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001408 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001409 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001410
Andreas Huber881227d2016-08-02 14:20:21 -07001411 out.unindent();
1412 out.unindent();
1413 out << "}\n\n";
1414
Yifan Hong068c5522016-10-31 14:07:25 -07001415 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1416 return generateProxyMethodSource(out, klassName, method, superInterface);
1417 });
Andreas Huber881227d2016-08-02 14:20:21 -07001418
Yifan Hong068c5522016-10-31 14:07:25 -07001419 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001420}
1421
1422status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001423 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001424 const Interface *iface) const {
1425 const std::string interfaceName = iface->localName();
1426 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001427
Steven Moreland40786312016-08-16 10:29:40 -07001428 out << klassName
1429 << "::"
1430 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001431 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001432
1433 out.indent();
1434 out.indent();
1435
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001436 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001437 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001438 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001439 out << ": "
1440 << gIBaseFqName.getInterfaceStubFqName().cppName()
1441 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001442 }
1443
1444 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001445 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001446 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001447 << "\") { \n";
1448 out.indent();
1449 out << "_hidl_mImpl = _hidl_impl;\n";
1450 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001451
1452 out.unindent();
1453 out.unindent();
1454 out << "}\n\n";
1455
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001456 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001457 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001458 // class properly.
1459 out << klassName
1460 << "::"
1461 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001462 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1463 << " const std::string &HidlInstrumentor_package,"
1464 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001465
1466 out.indent();
1467 out.indent();
1468
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001469 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001470 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001471 out.indent();
1472 out << "_hidl_mImpl = _hidl_impl;\n";
1473 out.unindent();
1474
1475 out.unindent();
1476 out.unindent();
1477 out << "}\n\n";
1478 }
1479
Yifan Hongbcffce22017-02-01 15:52:06 -08001480 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1481 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1482 return OK;
1483 }
1484 method->generateCppSignature(out, iface->getStubName());
1485 out << " ";
1486 out.block([&] {
1487 method->cppImpl(IMPL_STUB_IMPL, out);
1488 }).endl();
1489 return OK;
1490 });
Steven Moreland60818632017-02-04 00:33:42 -08001491 if (err != OK) {
1492 return err;
1493 }
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001494
Andreas Huber881227d2016-08-02 14:20:21 -07001495 out << "::android::status_t " << klassName << "::onTransact(\n";
1496
1497 out.indent();
1498 out.indent();
1499
Iliyan Malchev549e2592016-08-10 08:59:12 -07001500 out << "uint32_t _hidl_code,\n"
1501 << "const ::android::hardware::Parcel &_hidl_data,\n"
1502 << "::android::hardware::Parcel *_hidl_reply,\n"
1503 << "uint32_t _hidl_flags,\n"
1504 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001505
1506 out.unindent();
1507
Iliyan Malchev549e2592016-08-10 08:59:12 -07001508 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001509 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001510 out.indent();
1511
Yifan Hong10fe0b52016-10-19 14:20:17 -07001512 for (const auto &tuple : iface->allMethodsFromRoot()) {
1513 const Method *method = tuple.method();
1514 const Interface *superInterface = tuple.interface();
1515 out << "case "
1516 << method->getSerialId()
1517 << " /* "
1518 << method->name()
1519 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001520
Yifan Hong10fe0b52016-10-19 14:20:17 -07001521 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001522
Yifan Hong10fe0b52016-10-19 14:20:17 -07001523 status_t err =
1524 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001525
Yifan Hong10fe0b52016-10-19 14:20:17 -07001526 if (err != OK) {
1527 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001528 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001529
1530 out.unindent();
1531 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001532 }
1533
1534 out << "default:\n{\n";
1535 out.indent();
1536
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001537 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001538
1539 out.indent();
1540 out.indent();
1541
Iliyan Malchev549e2592016-08-10 08:59:12 -07001542 out << "_hidl_code, _hidl_data, _hidl_reply, "
1543 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001544
1545 out.unindent();
1546 out.unindent();
1547
1548 out.unindent();
1549 out << "}\n";
1550
1551 out.unindent();
1552 out << "}\n\n";
1553
Yifan Honga018ed52016-12-13 16:35:08 -08001554 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1555 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1556 out.indent(2, [&] {
1557 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1558 out << "_hidl_reply);\n";
1559 });
1560 });
Andreas Huber881227d2016-08-02 14:20:21 -07001561
Iliyan Malchev549e2592016-08-10 08:59:12 -07001562 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001563
1564 out.unindent();
1565 out << "}\n\n";
1566
1567 return OK;
1568}
1569
1570status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001571 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001572 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1573 method->cppImpl(IMPL_STUB, out);
1574 out << "break;\n";
1575 return OK;
1576 }
1577
Yifan Hongeefe4f22017-01-04 15:32:42 -08001578 out << "if (!_hidl_data.enforceInterface("
1579 << iface->fullName()
1580 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001581
Andreas Huber881227d2016-08-02 14:20:21 -07001582 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001583 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001584 out << "break;\n";
1585 out.unindent();
1586 out << "}\n\n";
1587
Andreas Huber5e44a292016-09-27 14:52:39 -07001588 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001589
Yifan Hongbf459bc2016-08-23 16:50:37 -07001590 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001591 for (const auto &arg : method->args()) {
1592 emitCppReaderWriter(
1593 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001594 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001595 false /* parcelObjIsPointer */,
1596 arg,
1597 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001598 Type::ErrorMode_Break,
1599 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001600 }
1601
Yifan Hongbf459bc2016-08-23 16:50:37 -07001602 // Second DFS: resolve references
1603 for (const auto &arg : method->args()) {
1604 emitCppResolveReferences(
1605 out,
1606 "_hidl_data",
1607 false /* parcelObjIsPointer */,
1608 arg,
1609 true /* reader */,
1610 Type::ErrorMode_Break,
1611 false /* addPrefixToName */);
1612 }
1613
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001614 status_t status = generateCppInstrumentationCall(
1615 out,
1616 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001617 method);
1618 if (status != OK) {
1619 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001620 }
1621
Andreas Huber881227d2016-08-02 14:20:21 -07001622 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001623 const TypedVar *elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -08001624 const std::string callee =
1625 (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL))
1626 ? "this" : "_hidl_mImpl";
Andreas Huber881227d2016-08-02 14:20:21 -07001627
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001628 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001629 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001630 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001631 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001632 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001633 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001634 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001635
Yifan Hong7d234ea2017-03-30 15:40:22 -07001636 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001637 if (arg->type().resultNeedsDeref()) {
1638 out << "*";
1639 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001640 out << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001641 });
Andreas Huber881227d2016-08-02 14:20:21 -07001642
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001643 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001644 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1645 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001646
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001647 elidedReturn->type().emitReaderWriter(
1648 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001649 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001650 "_hidl_reply",
1651 true, /* parcelObjIsPointer */
1652 false, /* isReader */
1653 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001654
Yifan Hongbf459bc2016-08-23 16:50:37 -07001655 emitCppResolveReferences(
1656 out,
1657 "_hidl_reply",
1658 true /* parcelObjIsPointer */,
1659 elidedReturn,
1660 false /* reader */,
1661 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001662 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001663
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001664 status_t status = generateCppInstrumentationCall(
1665 out,
1666 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001667 method);
1668 if (status != OK) {
1669 return status;
1670 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001671
Iliyan Malchev549e2592016-08-10 08:59:12 -07001672 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001673 } else {
1674 if (returnsValue) {
1675 out << "bool _hidl_callbackCalled = false;\n\n";
1676 }
Andreas Huber881227d2016-08-02 14:20:21 -07001677
Yifan Hongcd2ae452017-01-31 14:33:40 -08001678 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001679
Yifan Hong7d234ea2017-03-30 15:40:22 -07001680 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001681 if (arg->type().resultNeedsDeref()) {
1682 out << "*";
1683 }
1684
1685 out << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001686 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001687
1688 if (returnsValue) {
Yifan Hong7d234ea2017-03-30 15:40:22 -07001689 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001690 out << ", ";
1691 }
1692
1693 out << "[&](";
1694
Yifan Hong7d234ea2017-03-30 15:40:22 -07001695 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001696 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001697 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001698
1699 out << ") {\n";
1700 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001701 out << "if (_hidl_callbackCalled) {\n";
1702 out.indent();
1703 out << "LOG_ALWAYS_FATAL(\""
1704 << method->name()
1705 << ": _hidl_cb called a second time, but must be called once.\");\n";
1706 out.unindent();
1707 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001708 out << "_hidl_callbackCalled = true;\n\n";
1709
Yifan Hong859e53f2016-11-14 19:08:24 -08001710 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1711 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001712
Yifan Hongbf459bc2016-08-23 16:50:37 -07001713 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001714 for (const auto &arg : method->results()) {
1715 emitCppReaderWriter(
1716 out,
1717 "_hidl_reply",
1718 true /* parcelObjIsPointer */,
1719 arg,
1720 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001721 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001722 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001723 }
1724
Yifan Hongbf459bc2016-08-23 16:50:37 -07001725 // Second DFS: resolve references
1726 for (const auto &arg : method->results()) {
1727 emitCppResolveReferences(
1728 out,
1729 "_hidl_reply",
1730 true /* parcelObjIsPointer */,
1731 arg,
1732 false /* reader */,
1733 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001734 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001735 }
1736
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001737 status_t status = generateCppInstrumentationCall(
1738 out,
1739 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001740 method);
1741 if (status != OK) {
1742 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001743 }
1744
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001745 out << "_hidl_cb(*_hidl_reply);\n";
1746
1747 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001748 out << "});\n\n";
1749 } else {
1750 out << ");\n\n";
1751 status_t status = generateCppInstrumentationCall(
1752 out,
1753 InstrumentationEvent::SERVER_API_EXIT,
1754 method);
1755 if (status != OK) {
1756 return status;
1757 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001758 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001759
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001760 if (returnsValue) {
1761 out << "if (!_hidl_callbackCalled) {\n";
1762 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001763 out << "LOG_ALWAYS_FATAL(\""
1764 << method->name()
1765 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001766 out.unindent();
1767 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001768 } else {
1769 out << "::android::hardware::writeToParcel("
1770 << "::android::hardware::Status::ok(), "
1771 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001772 }
Andreas Huber881227d2016-08-02 14:20:21 -07001773 }
1774
1775 out << "break;\n";
1776
1777 return OK;
1778}
1779
Steven Moreland69e7c702016-09-09 11:16:32 -07001780status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1781 std::string ifaceName;
1782 if (!AST::isInterface(&ifaceName)) {
1783 // types.hal does not get a stub header.
1784 return OK;
1785 }
1786
1787 const Interface *iface = mRootScope->getInterface();
1788
Yifan Hongeefe4f22017-01-04 15:32:42 -08001789 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001790
1791 bool supportOneway = iface->hasOnewayMethods();
1792
1793 std::string path = outputPath;
1794 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1795 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1796 path.append(klassName);
1797 path.append(".h");
1798
1799 CHECK(Coordinator::MakeParentHierarchy(path));
1800 FILE *file = fopen(path.c_str(), "w");
1801
1802 if (file == NULL) {
1803 return -errno;
1804 }
1805
1806 Formatter out(file);
1807
1808 const std::string guard = makeHeaderGuard(klassName);
1809
1810 out << "#ifndef " << guard << "\n";
1811 out << "#define " << guard << "\n\n";
1812
1813 std::vector<std::string> packageComponents;
1814 getPackageAndVersionComponents(
1815 &packageComponents, false /* cpp_compatible */);
1816
Yifan Hongb0949432016-12-15 15:32:24 -08001817 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001818 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001819
1820 generateCppPackageInclude(out, mPackage, ifaceName);
1821 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001822
Yifan Hong7a118f52016-12-07 11:21:15 -08001823 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001824 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001825 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001826 }
1827
1828 enterLeaveNamespace(out, true /* enter */);
1829 out << "\n";
1830
1831 out << "struct "
1832 << klassName
1833 << " : " << ifaceName
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001834 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001835
1836 out.indent();
1837 out << "explicit "
1838 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001839 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001840 << ifaceName
1841 << "> impl);\n";
1842
Yifan Hong068c5522016-10-31 14:07:25 -07001843 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1844 return generatePassthroughMethod(out, method);
1845 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001846
1847 if (err != OK) {
1848 return err;
1849 }
1850
1851 out.unindent();
1852 out << "private:\n";
1853 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001854 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001855
1856 if (supportOneway) {
Yifan Hongef91d362017-03-20 17:18:13 -07001857 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001858
1859 out << "\n";
1860
1861 out << "::android::hardware::Return<void> addOnewayTask("
1862 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001863 }
1864
1865 out.unindent();
1866
1867 out << "};\n\n";
1868
1869 enterLeaveNamespace(out, false /* enter */);
1870
1871 out << "\n#endif // " << guard << "\n";
1872
1873 return OK;
1874}
1875
Yifan Hongfe95aa22016-10-19 17:26:45 -07001876status_t AST::generateInterfaceSource(Formatter &out) const {
1877 const Interface *iface = mRootScope->getInterface();
1878
Yifan Hong2d7126b2016-10-20 15:12:57 -07001879 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001880 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001881
Steven Morelandd4b068a2017-03-20 06:30:51 -07001882 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1883 bool reserved = method->isHidlReserved();
1884
1885 if (!reserved) {
1886 out << "// no default implementation for: ";
1887 }
1888 method->generateCppSignature(out, iface->localName());
1889 if (reserved) {
1890 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001891 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001892 }).endl();
1893 }
1894
1895 out << "\n";
1896
1897 return OK;
1898 });
1899 if (err != OK) {
1900 return err;
1901 }
1902
Yifan Hong3d746092016-12-07 14:26:33 -08001903 for (const Interface *superType : iface->typeChain()) {
Yifan Hong7783bb02017-03-29 03:39:09 -07001904 out << "// static \n::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -08001905 << childTypeResult
Yifan Hong7783bb02017-03-29 03:39:09 -07001906 << "> "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001907 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001908 << "::castFrom("
1909 << superType->getCppArgumentType()
Yifan Hong7783bb02017-03-29 03:39:09 -07001910 << " parent, bool "
1911 << (iface == superType ? "/* emitError */" : "emitError")
1912 << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001913 out.indent();
1914 if (iface == superType) {
1915 out << "return parent;\n";
1916 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001917 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001918 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001919 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001920 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001921 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001922 << ">(\n";
1923 out.indent();
1924 out.indent();
1925 out << "parent, \""
1926 << iface->fqName().string()
Yifan Hong7783bb02017-03-29 03:39:09 -07001927 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001928 out.unindent();
1929 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001930 }
Yifan Hong3d746092016-12-07 14:26:33 -08001931 out.unindent();
1932 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001933 }
1934
1935 return OK;
1936}
1937
Steven Moreland69e7c702016-09-09 11:16:32 -07001938status_t AST::generatePassthroughSource(Formatter &out) const {
1939 const Interface *iface = mRootScope->getInterface();
1940
Yifan Hongeefe4f22017-01-04 15:32:42 -08001941 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001942
1943 out << klassName
1944 << "::"
1945 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001946 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001947 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001948 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001949 << mPackage.string()
1950 << "\", \""
1951 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001952 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001953 if (iface->hasOnewayMethods()) {
1954 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001955 out.indent([&] {
Yifan Hongf01dad42017-03-20 19:03:11 -07001956 out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001957 });
1958 }
1959 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001960
1961 if (iface->hasOnewayMethods()) {
1962 out << "::android::hardware::Return<void> "
1963 << klassName
1964 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1965 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001966 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001967 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001968 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1969 out.indent();
1970 out.indent();
1971 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1972 out.unindent();
1973 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001974 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001975 out << "}\n";
1976
Steven Morelandd366c262016-10-11 15:29:10 -07001977 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001978
1979 out.unindent();
1980 out << "}\n\n";
1981
1982
1983 }
1984
1985 return OK;
1986}
1987
Martijn Coenen7b295242016-11-04 16:52:56 +01001988status_t AST::generateCppAtraceCall(Formatter &out,
1989 InstrumentationEvent event,
1990 const Method *method) const {
1991 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001992 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001993 switch (event) {
1994 case SERVER_API_ENTRY:
1995 {
1996 out << "atrace_begin(ATRACE_TAG_HAL, \""
1997 << baseString + "::server\");\n";
1998 break;
1999 }
2000 case CLIENT_API_ENTRY:
2001 {
2002 out << "atrace_begin(ATRACE_TAG_HAL, \""
2003 << baseString + "::client\");\n";
2004 break;
2005 }
2006 case PASSTHROUGH_ENTRY:
2007 {
2008 out << "atrace_begin(ATRACE_TAG_HAL, \""
2009 << baseString + "::passthrough\");\n";
2010 break;
2011 }
2012 case SERVER_API_EXIT:
2013 case CLIENT_API_EXIT:
2014 case PASSTHROUGH_EXIT:
2015 {
2016 out << "atrace_end(ATRACE_TAG_HAL);\n";
2017 break;
2018 }
2019 default:
2020 {
2021 LOG(ERROR) << "Unsupported instrumentation event: " << event;
2022 return UNKNOWN_ERROR;
2023 }
2024 }
2025
2026 return OK;
2027}
2028
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002029status_t AST::generateCppInstrumentationCall(
2030 Formatter &out,
2031 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07002032 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01002033 status_t err = generateCppAtraceCall(out, event, method);
2034 if (err != OK) {
2035 return err;
2036 }
2037
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002038 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
2039 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002040 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002041 std::string event_str = "";
2042 switch (event) {
2043 case SERVER_API_ENTRY:
2044 {
2045 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
2046 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002047 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002048 << (arg->type().resultNeedsDeref() ? "" : "&")
2049 << arg->name()
2050 << ");\n";
2051 }
2052 break;
2053 }
2054 case SERVER_API_EXIT:
2055 {
2056 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07002057 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002058 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07002059 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002060 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002061 }
2062 break;
2063 }
2064 case CLIENT_API_ENTRY:
2065 {
2066 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2067 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002068 out << "_hidl_args.push_back((void *)&"
2069 << arg->name()
2070 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002071 }
2072 break;
2073 }
2074 case CLIENT_API_EXIT:
2075 {
2076 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2077 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002078 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002079 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002080 << "_hidl_out_"
2081 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002082 << ");\n";
2083 }
2084 break;
2085 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002086 case PASSTHROUGH_ENTRY:
2087 {
2088 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2089 for (const auto &arg : method->args()) {
2090 out << "_hidl_args.push_back((void *)&"
2091 << arg->name()
2092 << ");\n";
2093 }
2094 break;
2095 }
2096 case PASSTHROUGH_EXIT:
2097 {
2098 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002099 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002100 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002101 << arg->name()
2102 << ");\n";
2103 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002104 break;
2105 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002106 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002107 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002108 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002109 return UNKNOWN_ERROR;
2110 }
2111 }
2112
Steven Moreland031ccf12016-10-31 15:54:38 -07002113 const Interface *iface = mRootScope->getInterface();
2114
Steven Moreland1ab31442016-11-03 18:37:51 -07002115 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002116 out.indent();
2117 out << "callback("
2118 << event_str
2119 << ", \""
2120 << mPackage.package()
2121 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002122 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002123 << "\", \""
2124 << iface->localName()
2125 << "\", \""
2126 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002127 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002128 out.unindent();
2129 out << "}\n";
2130 out.unindent();
2131 out << "}\n\n";
2132
2133 return OK;
2134}
2135
Andreas Huber881227d2016-08-02 14:20:21 -07002136} // namespace android