blob: 27d843c84ba2129ec37dc51bad077483ca62e1ca [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Huber881227d2016-08-02 14:20:21 -070017#include "AST.h"
18
19#include "Coordinator.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070020#include "EnumType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070021#include "Interface.h"
22#include "Method.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070023#include "ScalarType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070024#include "Scope.h"
25
Andreas Huberdca261f2016-08-04 13:47:51 -070026#include <algorithm>
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070027#include <hidl-util/Formatter.h>
Steven Moreland5708edf2016-11-04 15:33:31 +000028#include <hidl-util/StringHelper.h>
Andreas Huber881227d2016-08-02 14:20:21 -070029#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070030#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070031#include <vector>
32
33namespace android {
34
Andreas Huberb82318c2016-08-02 14:45:54 -070035status_t AST::generateCpp(const std::string &outputPath) const {
36 status_t err = generateInterfaceHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070037
38 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070039 err = generateStubHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070040 }
41
42 if (err == OK) {
Steven Moreland40786312016-08-16 10:29:40 -070043 err = generateHwBinderHeader(outputPath);
44 }
45
46 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070047 err = generateProxyHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070048 }
49
50 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070051 err = generateAllSource(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070052 }
53
Steven Moreland69e7c702016-09-09 11:16:32 -070054 if (err == OK) {
Yifan Hong7a118f52016-12-07 11:21:15 -080055 err = generatePassthroughHeader(outputPath);
Steven Moreland69e7c702016-09-09 11:16:32 -070056 }
57
Andreas Huber881227d2016-08-02 14:20:21 -070058 return err;
59}
60
Andreas Huber737080b2016-08-02 15:38:04 -070061void AST::getPackageComponents(
62 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070063 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070064}
65
66void AST::getPackageAndVersionComponents(
67 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070068 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070069}
70
Steven Moreland5708edf2016-11-04 15:33:31 +000071std::string AST::makeHeaderGuard(const std::string &baseName,
72 bool indicateGenerated) const {
73 std::string guard;
Andreas Huber881227d2016-08-02 14:20:21 -070074
Steven Moreland5708edf2016-11-04 15:33:31 +000075 if (indicateGenerated) {
76 guard += "HIDL_GENERATED_";
77 }
78
79 guard += StringHelper::Uppercase(mPackage.tokenName());
Andreas Huber881227d2016-08-02 14:20:21 -070080 guard += "_";
Steven Moreland5708edf2016-11-04 15:33:31 +000081 guard += StringHelper::Uppercase(baseName);
82 guard += "_H";
Andreas Huber881227d2016-08-02 14:20:21 -070083
84 return guard;
85}
86
Steven Morelandee88eed2016-10-31 17:49:00 -070087// static
88void AST::generateCppPackageInclude(
89 Formatter &out,
90 const FQName &package,
91 const std::string &klass) {
92
93 out << "#include <";
94
95 std::vector<std::string> components;
96 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
97
98 for (const auto &component : components) {
99 out << component << "/";
100 }
101
102 out << klass
103 << ".h>\n";
104}
105
Andreas Huber881227d2016-08-02 14:20:21 -0700106void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
107 std::vector<std::string> packageComponents;
108 getPackageAndVersionComponents(
109 &packageComponents, true /* cpp_compatible */);
110
111 if (enter) {
112 for (const auto &component : packageComponents) {
113 out << "namespace " << component << " {\n";
114 }
Andreas Huber0e00de42016-08-03 09:56:02 -0700115
Andreas Huber2831d512016-08-15 09:33:47 -0700116 out.setNamespace(mPackage.cppNamespace() + "::");
Andreas Huber881227d2016-08-02 14:20:21 -0700117 } else {
Andreas Huber0e00de42016-08-03 09:56:02 -0700118 out.setNamespace(std::string());
119
Andreas Huber881227d2016-08-02 14:20:21 -0700120 for (auto it = packageComponents.rbegin();
121 it != packageComponents.rend();
122 ++it) {
123 out << "} // namespace " << *it << "\n";
124 }
125 }
126}
127
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700128static void declareGetService(Formatter &out, const std::string &interfaceName, bool isTry) {
129 const std::string functionName = isTry ? "tryGetService" : "getService";
130
131 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800132 << "const std::string &serviceName=\"default\", bool getStub=false);\n";
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700133 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800134 << "const char serviceName[], bool getStub=false)"
135 << " { std::string str(serviceName ? serviceName : \"\");"
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700136 << " return " << functionName << "(str, getStub); }\n";
137 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800138 << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
139 // without c_str the std::string constructor is ambiguous
140 << " { std::string str(serviceName.c_str());"
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700141 << " return " << functionName << "(str, getStub); }\n";
142 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
143 << "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
144}
145
146static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
147 declareGetService(out, interfaceName, true /* isTry */);
148 declareGetService(out, interfaceName, false /* isTry */);
149
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800150 out << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800151 out << "static bool registerForNotifications(\n";
152 out.indent(2, [&] {
153 out << "const std::string &serviceName,\n"
154 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
155 << "&notification);\n";
156 });
157
158}
159
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700160static void implementGetService(Formatter &out,
161 const FQName &fqName,
162 bool isTry) {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800163
164 const std::string interfaceName = fqName.getInterfaceName();
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700165 const std::string functionName = isTry ? "tryGetService" : "getService";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800166
167 out << "// static\n"
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700168 << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
Yifan Hong31f07ff2017-03-21 18:56:35 +0000169 << "const std::string &serviceName, const bool getStub) ";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800170 out.block([&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000171 out << "::android::sp<" << interfaceName << "> iface = nullptr;\n";
Yifan Hongd3b58ed2017-01-30 14:13:10 -0800172 out << "::android::vintf::Transport transport = ::android::hardware::getTransport("
Yifan Hong152866b2017-02-28 15:34:27 -0800173 << interfaceName << "::descriptor, serviceName);\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000174
Yifan Hong31f07ff2017-03-21 18:56:35 +0000175 // TODO(b/34274385) remove sysprop check
176 out << "const bool vintfHwbinder = (transport == ::android::vintf::Transport::HWBINDER) ||\n"
177 << " (transport == ::android::vintf::Transport::TOGGLED &&\n"
178 << " ::android::hardware::details::blockingHalBinderizationEnabled());\n"
179 << "const bool vintfPassthru = (transport == ::android::vintf::Transport::PASSTHROUGH) ||\n"
180 << " (transport == ::android::vintf::Transport::TOGGLED &&\n"
181 << " !::android::hardware::details::blockingHalBinderizationEnabled());\n"
182 << "const bool vintfEmpty = (transport == ::android::vintf::Transport::EMPTY);\n\n";
183
184 // if (getStub) {
185 // getPassthroughServiceManager()->get only once.
186 // } else {
187 // if (vintfHwbinder) {
188 // while (no alive service) {
189 // waitForHwService
190 // defaultServiceManager()->get
191 // }
192 // } else if (vintfEmpty) {
193 // defaultServiceManager()->get only once.
194 // getPassthroughServiceManager()->get only once.
195 // } else if (vintfPassthru) {
196 // getPassthroughServiceManager()->get only once.
197 // }
198 // }
199
Yifan Hongf1ef44f2017-03-23 17:17:57 +0000200 out << "bool tried = false;\n";
201 out.sWhile("!getStub && (vintfHwbinder || (vintfEmpty && !tried))", [&] {
Yifan Hong31f07ff2017-03-21 18:56:35 +0000202
203 out.sIf("tried", [&] {
204 // sleep only after the first trial.
205 out << "ALOGI(\"getService: retrying in 1s...\");\n"
206 << "sleep(1);\n";
207 }).endl();
208
Yifan Hongf1ef44f2017-03-23 17:17:57 +0000209 out << "tried = true;\n";
210
Steven Morelandf10af872017-01-25 16:01:56 +0000211 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800212 out.indent(2, [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000213 out << "= ::android::hardware::defaultServiceManager();\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800214 });
Yifan Hong31f07ff2017-03-21 18:56:35 +0000215 out.sIf("sm == nullptr", [&] {
216 // hwbinder is not available on this device, so future tries
217 // would also be null. I can only "break" here and
218 // (vintfEmpty) try passthrough or (vintfHwbinder) return nullptr.
219 out << "ALOGE(\"getService: defaultServiceManager() is null\");\n"
220 << "break;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800221 }).endl();
Yifan Hong31f07ff2017-03-21 18:56:35 +0000222
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700223 if (!isTry) {
224 out.sIf("vintfHwbinder", [&] {
225 out << "::android::hardware::details::waitForHwService("
226 << interfaceName << "::descriptor" << ", serviceName);\n";
227 }).endl();
228 }
Yifan Hong31f07ff2017-03-21 18:56:35 +0000229
230 out << "::android::hardware::Return<::android::sp<"
231 << gIBaseFqName.cppName() << ">> ret = \n";
232 out.indent(2, [&] {
233 out << "sm->get(" << interfaceName << "::descriptor, serviceName);\n";
234 });
235
236 out.sIf("!ret.isOk()", [&] {
Steven Moreland42394ce2017-03-27 17:03:04 -0700237 // hwservicemanager fails, may be security issue
Yifan Hong31f07ff2017-03-21 18:56:35 +0000238 out << "ALOGE(\"getService: defaultServiceManager()->get returns %s\", "
239 << "ret.description().c_str());\n"
Steven Moreland42394ce2017-03-27 17:03:04 -0700240 << "break;\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000241 }).endl();
242
Yifan Hong7783bb02017-03-29 03:39:09 -0700243 out << "::android::sp<" << gIBaseFqName.cppName() << "> base = ret;\n";
244 out.sIf("base == nullptr", [&] {
245 // race condition. hwservicemanager drops the service
246 // from waitForHwService to here
Steven Morelanddff644c2017-03-24 10:59:01 -0700247 out << "ALOGW(\"getService: found null hwbinder interface\");\n"
Steven Moreland9cca95b2017-03-29 00:55:32 -0700248 << "break;\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000249 }).endl();
Yifan Hong7783bb02017-03-29 03:39:09 -0700250 out << "::android::hardware::Return<::android::sp<" << interfaceName
251 << ">> castRet = " << interfaceName << "::castFrom(base, true /* emitError */);\n";
252 out.sIf("!castRet.isOk()", [&] {
253 out.sIf("castRet.isDeadObject()", [&] {
254 // service is dead (castFrom cannot call interfaceChain)
255 out << "ALOGW(\"getService: found dead hwbinder service\");\n"
256 << "break;\n";
257 }).sElse([&] {
258 out << "ALOGW(\"getService: cannot call into hwbinder service: %s"
259 << "; No permission? Check for selinux denials.\", "
260 << "castRet.description().c_str());\n"
261 << "break;\n";
262 }).endl();
263 }).endl();
264 out << "iface = castRet;\n";
265 out.sIf("iface == nullptr", [&] {
266 // returned service isn't of correct type; this is a bug
267 // to hwservicemanager or to the service itself (interfaceChain
268 // is not consistent).
269 out << "ALOGW(\"getService: received incompatible service; bug in hwservicemanager?\");\n"
270 << "break;\n";
271 }).endl();
Yifan Hong31f07ff2017-03-21 18:56:35 +0000272
273 out << "return iface;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800274 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800275
Yifan Hong31f07ff2017-03-21 18:56:35 +0000276 out.sIf("getStub || vintfPassthru || vintfEmpty", [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000277 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> pm\n";
Steven Morelande3fa5da2017-01-25 07:07:53 +0000278 out.indent(2, [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000279 out << "= ::android::hardware::getPassthroughServiceManager();\n";
Steven Morelande3fa5da2017-01-25 07:07:53 +0000280 });
Steven Morelandf10af872017-01-25 16:01:56 +0000281
282 out.sIf("pm != nullptr", [&] () {
283 out << "::android::hardware::Return<::android::sp<" << gIBaseFqName.cppName() << ">> ret = \n";
284 out.indent(2, [&] {
285 out << "pm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
Steven Moreland2c2dea82017-01-18 17:24:17 -0800286 });
Steven Morelandf10af872017-01-25 16:01:56 +0000287 out.sIf("ret.isOk()", [&] {
288 out << "::android::sp<" << gIBaseFqName.cppName()
289 << "> baseInterface = ret;\n";
290 out.sIf("baseInterface != nullptr", [&]() {
291 out << "iface = new " << fqName.getInterfacePassthroughName()
292 << "(" << interfaceName << "::castFrom(baseInterface));\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000293 }).endl();
Steven Morelandf10af872017-01-25 16:01:56 +0000294 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800295 }).endl();
296 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800297
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800298 out << "return iface;\n";
299 }).endl().endl();
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700300}
301
302static void implementServiceManagerInteractions(Formatter &out,
303 const FQName &fqName, const std::string &package) {
304
305 const std::string interfaceName = fqName.getInterfaceName();
306
307 implementGetService(out, fqName, true /* isTry */);
308 implementGetService(out, fqName, false /* isTry */);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800309
Yifan Hongeefe4f22017-01-04 15:32:42 -0800310 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800311 << "const std::string &serviceName) ";
312 out.block([&] {
313 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
314 out.indent(2, [&] {
315 out << "= ::android::hardware::defaultServiceManager();\n";
316 });
317 out.sIf("sm == nullptr", [&] {
318 out << "return ::android::INVALID_OPERATION;\n";
319 }).endl();
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100320 out << "::android::hardware::Return<bool> ret = "
321 << "sm->add(serviceName.c_str(), this);\n"
322 << "return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800323 }).endl().endl();
324
Yifan Hongeefe4f22017-01-04 15:32:42 -0800325 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800326 out.indent(2, [&] {
327 out << "const std::string &serviceName,\n"
328 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
329 << "&notification) ";
330 });
331 out.block([&] {
332 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
333 out.indent(2, [&] {
334 out << "= ::android::hardware::defaultServiceManager();\n";
335 });
336 out.sIf("sm == nullptr", [&] {
337 out << "return false;\n";
338 }).endl();
339 out << "::android::hardware::Return<bool> success =\n";
340 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800341 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800342 out.indent(2, [&] {
343 out << "serviceName, notification);\n";
344 });
345 });
346 out << "return success.isOk() && success;\n";
347 }).endl().endl();
348}
349
Andreas Huberb82318c2016-08-02 14:45:54 -0700350status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700351
Andreas Huberb82318c2016-08-02 14:45:54 -0700352 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700353 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700354 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700355
356 std::string ifaceName;
357 bool isInterface = true;
358 if (!AST::isInterface(&ifaceName)) {
359 ifaceName = "types";
360 isInterface = false;
361 }
362 path.append(ifaceName);
363 path.append(".h");
364
Andreas Huberd2943e12016-08-05 11:59:31 -0700365 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700366 FILE *file = fopen(path.c_str(), "w");
367
368 if (file == NULL) {
369 return -errno;
370 }
371
372 Formatter out(file);
373
374 const std::string guard = makeHeaderGuard(ifaceName);
375
376 out << "#ifndef " << guard << "\n";
377 out << "#define " << guard << "\n\n";
378
Andreas Huber737080b2016-08-02 15:38:04 -0700379 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700380 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700381 }
382
383 if (!mImportedNames.empty()) {
384 out << "\n";
385 }
386
Steven Moreland0693f312016-11-09 15:06:14 -0800387 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800388 if (isIBase()) {
389 out << "// skipped #include IServiceNotification.h\n\n";
390 } else {
391 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
392 }
Steven Moreland0693f312016-11-09 15:06:14 -0800393 }
394
Yifan Hongc8934042016-11-17 17:10:52 -0800395 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700396 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700397
398 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200399 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700400 }
401
Martijn Coenenaf712c02016-11-16 15:26:27 +0100402 out << "#include <utils/NativeHandle.h>\n";
403 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700404
405 enterLeaveNamespace(out, true /* enter */);
406 out << "\n";
407
408 if (isInterface) {
409 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700410 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700411
412 const Interface *iface = mRootScope->getInterface();
413 const Interface *superType = iface->superType();
414
Steven Moreland40786312016-08-16 10:29:40 -0700415 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800416 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700417 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000418 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700419 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700420 }
421
422 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700423
424 out.indent();
425
Andreas Huber881227d2016-08-02 14:20:21 -0700426 }
427
428 status_t err = emitTypeDeclarations(out);
429
430 if (err != OK) {
431 return err;
432 }
433
434 if (isInterface) {
435 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800436
Yifan Hongc8934042016-11-17 17:10:52 -0800437 out << "virtual bool isRemote() const ";
438 if (!isIBase()) {
439 out << "override ";
440 }
441 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800442
Andreas Huber881227d2016-08-02 14:20:21 -0700443 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700444 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700445
Andreas Huber881227d2016-08-02 14:20:21 -0700446 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800447 const TypedVar *elidedReturn = method->canElideCallback();
448
449 if (elidedReturn == nullptr && returnsValue) {
450 out << "using "
451 << method->name()
Yifan Hong7d234ea2017-03-30 15:40:22 -0700452 << "_cb = std::function<void(";
453 method->emitCppResultSignature(out, true /* specify namespaces */);
454 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800455 }
Andreas Huber881227d2016-08-02 14:20:21 -0700456
Andreas Huber3599d922016-08-09 10:42:57 -0700457 method->dumpAnnotations(out);
458
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700459 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700460 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700461 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700462 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700463 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700464 }
465
466 out << method->name()
Yifan Hong7d234ea2017-03-30 15:40:22 -0700467 << "(";
468 method->emitCppArgSignature(out, true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700469
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700470 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700471 if (!method->args().empty()) {
472 out << ", ";
473 }
474
Steven Moreland67f67b42016-09-29 08:59:02 -0700475 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700476 }
477
Yifan Hong10fe0b52016-10-19 14:20:17 -0700478 out << ")";
479 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800480 if (!isIBase()) {
481 out << " override";
482 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700483 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700484 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700485 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700486 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700487 }
Steven Moreland40786312016-08-16 10:29:40 -0700488
Yifan Hong3d746092016-12-07 14:26:33 -0800489 out << "// cast static functions\n";
490 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700491
Yifan Hong3d746092016-12-07 14:26:33 -0800492 for (const Interface *superType : iface->typeChain()) {
Yifan Hong7783bb02017-03-29 03:39:09 -0700493 out << "static ::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -0800494 << childTypeResult
Yifan Hong7783bb02017-03-29 03:39:09 -0700495 << "> castFrom("
Yifan Hong3d746092016-12-07 14:26:33 -0800496 << superType->getCppArgumentType()
497 << " parent"
Yifan Hong7783bb02017-03-29 03:39:09 -0700498 << ", bool emitError = false);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700499 }
500
Steven Morelandd39133b2016-11-11 12:30:08 -0800501 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700502
Yifan Hongc8934042016-11-17 17:10:52 -0800503 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800504 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800505 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800506 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800507 }
Andreas Huber881227d2016-08-02 14:20:21 -0700508 }
509
510 if (isInterface) {
511 out.unindent();
512
Andreas Hubere3f769a2016-10-10 10:54:44 -0700513 out << "};\n\n";
514 }
515
516 err = mRootScope->emitGlobalTypeDeclarations(out);
517
518 if (err != OK) {
519 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700520 }
521
522 out << "\n";
523 enterLeaveNamespace(out, false /* enter */);
524
525 out << "\n#endif // " << guard << "\n";
526
527 return OK;
528}
529
Steven Moreland40786312016-08-16 10:29:40 -0700530status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
531 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800532 bool isInterface = AST::isInterface(&ifaceName);
533 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800534 std::string klassName{};
535
536 if(isInterface) {
537 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800538 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800539 } else {
540 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700541 }
542
Steven Moreland40786312016-08-16 10:29:40 -0700543 std::string path = outputPath;
544 path.append(mCoordinator->convertPackageRootToPath(mPackage));
545 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
546 path.append(klassName + ".h");
547
Yifan Hong244e82d2016-11-11 11:13:57 -0800548 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700549
550 if (file == NULL) {
551 return -errno;
552 }
553
554 Formatter out(file);
555
556 const std::string guard = makeHeaderGuard(klassName);
557
558 out << "#ifndef " << guard << "\n";
559 out << "#define " << guard << "\n\n";
560
Yifan Hong244e82d2016-11-11 11:13:57 -0800561 if (isInterface) {
562 generateCppPackageInclude(out, mPackage, ifaceName);
563 } else {
564 generateCppPackageInclude(out, mPackage, "types");
565 }
Steven Moreland40786312016-08-16 10:29:40 -0700566
Steven Morelandee88eed2016-10-31 17:49:00 -0700567 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700568
569 for (const auto &item : mImportedNames) {
570 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800571 generateCppPackageInclude(out, item, "hwtypes");
572 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800573 generateCppPackageInclude(out, item, item.getInterfaceStubName());
574 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700575 }
Steven Moreland40786312016-08-16 10:29:40 -0700576 }
577
578 out << "\n";
579
Martijn Coenen93915102016-09-01 01:35:52 +0200580 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700581 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100582 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700583
584 out << "\n";
585
586 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700587
Yifan Hong244e82d2016-11-11 11:13:57 -0800588 status_t err = mRootScope->emitGlobalHwDeclarations(out);
589 if (err != OK) {
590 return err;
591 }
Steven Moreland40786312016-08-16 10:29:40 -0700592
593 enterLeaveNamespace(out, false /* enter */);
594
595 out << "\n#endif // " << guard << "\n";
596
597 return OK;
598}
599
Andreas Huber881227d2016-08-02 14:20:21 -0700600status_t AST::emitTypeDeclarations(Formatter &out) const {
601 return mRootScope->emitTypeDeclarations(out);
602}
603
Yifan Hong7a118f52016-12-07 11:21:15 -0800604static void wrapPassthroughArg(Formatter &out,
605 const TypedVar *arg, bool addPrefixToName,
606 std::function<void(void)> handleError) {
607 if (!arg->type().isInterface()) {
608 return;
609 }
610 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
611 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
612 + arg->name();
613 const Interface &iface = static_cast<const Interface &>(arg->type());
614 out << iface.getCppStackType() << " " << wrappedName << ";\n";
615 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
616 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
617 out << wrappedName
618 << " = "
619 << iface.fqName().cppName()
Yifan Hong052425a2017-03-13 17:06:13 -0700620 << "::castFrom(::android::hardware::details::wrapPassthrough("
Yifan Hong7a118f52016-12-07 11:21:15 -0800621 << name << "));\n";
622 out.sIf(wrappedName + " == nullptr", [&] {
623 // Fatal error. Happens when the BsFoo class is not found in the binary
624 // or any dynamic libraries.
625 handleError();
626 }).endl();
627 }).sElse([&] {
628 out << wrappedName << " = " << name << ";\n";
629 }).endl().endl();
630}
631
Steven Moreland69e7c702016-09-09 11:16:32 -0700632status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700633 const Method *method) const {
634 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700635
636 out << " {\n";
637 out.indent();
638
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800639 if (method->isHidlReserved()
640 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
641 method->cppImpl(IMPL_PASSTHROUGH, out);
642 out.unindent();
643 out << "}\n\n";
644 return OK;
645 }
646
Steven Moreland69e7c702016-09-09 11:16:32 -0700647 const bool returnsValue = !method->results().empty();
648 const TypedVar *elidedReturn = method->canElideCallback();
649
Steven Moreland67f67b42016-09-29 08:59:02 -0700650 if (returnsValue && elidedReturn == nullptr) {
651 generateCheckNonNull(out, "_hidl_cb");
652 }
653
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700654 generateCppInstrumentationCall(
655 out,
656 InstrumentationEvent::PASSTHROUGH_ENTRY,
657 method);
658
Yifan Hong7a118f52016-12-07 11:21:15 -0800659
660 for (const auto &arg : method->args()) {
661 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
662 out << "return ::android::hardware::Status::fromExceptionCode(\n";
663 out.indent(2, [&] {
664 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800665 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800666 });
667 });
668 }
669
670 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700671 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700672
673 if (method->isOneway()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800674 out << "addOnewayTask([this, &_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700675 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800676 out << ", "
677 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
678 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700679 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700680 out << "] {\n";
681 out.indent();
682 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700683 }
684
685 out << "mImpl->"
686 << method->name()
687 << "(";
688
Yifan Hong7d234ea2017-03-30 15:40:22 -0700689 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800690 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700691 });
Steven Moreland69e7c702016-09-09 11:16:32 -0700692 if (returnsValue && elidedReturn == nullptr) {
693 if (!method->args().empty()) {
694 out << ", ";
695 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800696 out << "[&](";
Yifan Hong7d234ea2017-03-30 15:40:22 -0700697 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800698 out << "const auto &_hidl_out_"
699 << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700700 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800701
702 out << ") {\n";
703 out.indent();
704 status_t status = generateCppInstrumentationCall(
705 out,
706 InstrumentationEvent::PASSTHROUGH_EXIT,
707 method);
708 if (status != OK) {
709 return status;
710 }
711
Yifan Hong7a118f52016-12-07 11:21:15 -0800712 for (const auto &arg : method->results()) {
713 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
714 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
715 out.indent(2, [&] {
716 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800717 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800718 });
719 out << "return;\n";
720 });
721 }
722
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800723 out << "_hidl_cb(";
Yifan Hong7d234ea2017-03-30 15:40:22 -0700724 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800725 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
726 << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700727 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800728 out << ");\n";
729 out.unindent();
730 out << "});\n\n";
731 } else {
732 out << ");\n\n";
733 if (elidedReturn != nullptr) {
734 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800735 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800736 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000737 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800738 }
739 status_t status = generateCppInstrumentationCall(
740 out,
741 InstrumentationEvent::PASSTHROUGH_EXIT,
742 method);
743 if (status != OK) {
744 return status;
745 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700746 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700747
748 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700749 out.unindent();
750 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700751 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700752
753 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700754
755 out.unindent();
756 out << "}\n";
757
758 return OK;
759}
760
Yifan Hong068c5522016-10-31 14:07:25 -0700761status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700762
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700763 const Interface *iface = mRootScope->getInterface();
764
Yifan Hong10fe0b52016-10-19 14:20:17 -0700765 const Interface *prevIterface = nullptr;
766 for (const auto &tuple : iface->allMethodsFromRoot()) {
767 const Method *method = tuple.method();
768 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700769
Yifan Hong10fe0b52016-10-19 14:20:17 -0700770 if(prevIterface != superInterface) {
771 if (prevIterface != nullptr) {
772 out << "\n";
773 }
774 out << "// Methods from "
775 << superInterface->fullName()
776 << " follow.\n";
777 prevIterface = superInterface;
778 }
Yifan Hong068c5522016-10-31 14:07:25 -0700779 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700780
Yifan Hong10fe0b52016-10-19 14:20:17 -0700781 if (err != OK) {
782 return err;
783 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700784 }
785
Yifan Hong10fe0b52016-10-19 14:20:17 -0700786 out << "\n";
787
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700788 return OK;
789}
790
Andreas Huberb82318c2016-08-02 14:45:54 -0700791status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700792 std::string ifaceName;
793 if (!AST::isInterface(&ifaceName)) {
794 // types.hal does not get a stub header.
795 return OK;
796 }
797
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700798 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800799 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700800
Andreas Huberb82318c2016-08-02 14:45:54 -0700801 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700802 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700803 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700804 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700805 path.append(".h");
806
Andreas Huberd2943e12016-08-05 11:59:31 -0700807 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700808 FILE *file = fopen(path.c_str(), "w");
809
810 if (file == NULL) {
811 return -errno;
812 }
813
814 Formatter out(file);
815
Steven Moreland40786312016-08-16 10:29:40 -0700816 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700817
818 out << "#ifndef " << guard << "\n";
819 out << "#define " << guard << "\n\n";
820
Yifan Hongeefe4f22017-01-04 15:32:42 -0800821 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700822 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700823
824 enterLeaveNamespace(out, true /* enter */);
825 out << "\n";
826
827 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800828 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100829 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800830 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000831 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100832 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800833 out << " : public "
834 << gIBaseFqName.getInterfaceStubFqName().cppName()
835 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100836 }
Andreas Huber881227d2016-08-02 14:20:21 -0700837
838 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800839 out << "explicit "
840 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700841 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100842 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800843 out << "explicit "
844 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100845 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800846 << " const std::string& HidlInstrumentor_package,"
847 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700848 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700849 out << "::android::status_t onTransact(\n";
850 out.indent();
851 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700852 out << "uint32_t _hidl_code,\n";
853 out << "const ::android::hardware::Parcel &_hidl_data,\n";
854 out << "::android::hardware::Parcel *_hidl_reply,\n";
855 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700856 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700857 out.unindent();
858 out.unindent();
859
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100860 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
861 out.unindent();
862 out << "private:\n";
863 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800864
865 status_t err = generateMethods(out, [&](const Method *method, const Interface *iface) {
866 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
867 return OK;
868 }
869 const bool returnsValue = !method->results().empty();
870 const TypedVar *elidedReturn = method->canElideCallback();
871
872 if (elidedReturn == nullptr && returnsValue) {
873 out << "using " << method->name() << "_cb = "
874 << iface->fqName().cppName()
875 << "::" << method->name() << "_cb;\n";
876 }
877 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800878 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800879 return OK;
880 });
881 if (err != OK) {
882 return err;
883 }
884
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100885 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700886 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700887 out << "};\n\n";
888
889 enterLeaveNamespace(out, false /* enter */);
890
891 out << "\n#endif // " << guard << "\n";
892
893 return OK;
894}
895
Andreas Huberb82318c2016-08-02 14:45:54 -0700896status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700897 std::string ifaceName;
898 if (!AST::isInterface(&ifaceName)) {
899 // types.hal does not get a proxy header.
900 return OK;
901 }
902
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700903 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800904 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700905
Andreas Huberb82318c2016-08-02 14:45:54 -0700906 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700907 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700908 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800909 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700910 path.append(".h");
911
Andreas Huberd2943e12016-08-05 11:59:31 -0700912 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700913 FILE *file = fopen(path.c_str(), "w");
914
915 if (file == NULL) {
916 return -errno;
917 }
918
919 Formatter out(file);
920
Yifan Hongeefe4f22017-01-04 15:32:42 -0800921 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700922
923 out << "#ifndef " << guard << "\n";
924 out << "#define " << guard << "\n\n";
925
Martijn Coenen115d4282016-12-19 05:14:04 +0100926 out << "#include <hidl/HidlTransportSupport.h>\n\n";
927
Andreas Huber881227d2016-08-02 14:20:21 -0700928 std::vector<std::string> packageComponents;
929 getPackageAndVersionComponents(
930 &packageComponents, false /* cpp_compatible */);
931
Yifan Hongeefe4f22017-01-04 15:32:42 -0800932 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700933 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700934
935 enterLeaveNamespace(out, true /* enter */);
936 out << "\n";
937
938 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800939 << proxyName
940 << " : public ::android::hardware::BpInterface<"
941 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000942 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700943
944 out.indent();
945
Yifan Hongeefe4f22017-01-04 15:32:42 -0800946 out << "explicit "
947 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700948 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700949 << "\n\n";
950
Yifan Hong10fe0b52016-10-19 14:20:17 -0700951 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700952
Yifan Hong068c5522016-10-31 14:07:25 -0700953 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
954 method->generateCppSignature(out);
955 out << " override;\n";
956 return OK;
957 });
Steven Moreland9c387612016-09-07 09:54:26 -0700958
959 if (err != OK) {
960 return err;
961 }
Andreas Huber881227d2016-08-02 14:20:21 -0700962
963 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100964 out << "private:\n";
965 out.indent();
966 out << "std::mutex _hidl_mMutex;\n"
967 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
968 << " _hidl_mDeathRecipients;\n";
969 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700970 out << "};\n\n";
971
972 enterLeaveNamespace(out, false /* enter */);
973
974 out << "\n#endif // " << guard << "\n";
975
976 return OK;
977}
978
Andreas Huberb82318c2016-08-02 14:45:54 -0700979status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700980
Andreas Huberb82318c2016-08-02 14:45:54 -0700981 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700982 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700983 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700984
985 std::string ifaceName;
986 std::string baseName;
987
Yifan Hongfe95aa22016-10-19 17:26:45 -0700988 const Interface *iface = nullptr;
989 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700990 if (!AST::isInterface(&ifaceName)) {
991 baseName = "types";
992 isInterface = false;
993 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700994 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700995 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700996 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700997 }
998
999 path.append(baseName);
1000
1001 if (baseName != "types") {
1002 path.append("All");
1003 }
1004
1005 path.append(".cpp");
1006
Andreas Huberd2943e12016-08-05 11:59:31 -07001007 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -07001008 FILE *file = fopen(path.c_str(), "w");
1009
1010 if (file == NULL) {
1011 return -errno;
1012 }
1013
1014 Formatter out(file);
1015
Steven Moreland623c0042017-01-13 14:42:29 -08001016 out << "#define LOG_TAG \""
1017 << mPackage.string() << "::" << baseName
1018 << "\"\n\n";
1019
Steven Moreland05cd4232016-11-21 16:01:12 -08001020 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001021 out << "#include <cutils/trace.h>\n";
1022 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001023 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -07001024 // This is a no-op for IServiceManager itself.
1025 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
1026
Steven Morelandbec74ed2017-01-25 17:42:35 -08001027 // TODO(b/34274385) remove this
1028 out << "#include <hidl/LegacySupport.h>\n";
1029
Yifan Hongeefe4f22017-01-04 15:32:42 -08001030 generateCppPackageInclude(out, mPackage, iface->getProxyName());
1031 generateCppPackageInclude(out, mPackage, iface->getStubName());
1032 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001033
1034 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -07001035 generateCppPackageInclude(out,
1036 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -08001037 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001038 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -08001039
1040 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001041 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -07001042 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -08001043 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -07001044 }
1045
1046 out << "\n";
1047
1048 enterLeaveNamespace(out, true /* enter */);
1049 out << "\n";
1050
1051 status_t err = generateTypeSource(out, ifaceName);
1052
1053 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001054 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001055
1056 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -08001057 out << "const char* "
1058 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -07001059 << "::descriptor(\""
1060 << iface->fqName().string()
1061 << "\");\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +01001062 out << "__attribute__((constructor))";
1063 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001064 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001065 out << "::android::hardware::details::gBnConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001066 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001067 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001068 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001069 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001070 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001071 out << "return new "
1072 << iface->getStubName()
1073 << "(reinterpret_cast<"
1074 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001075 << " *>(iIntf));\n";
1076 });
Yifan Hongb04de382017-02-06 15:31:52 -08001077 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001078 });
Yifan Honga159f3b2017-03-16 14:53:51 -07001079 out << "::android::hardware::details::gBsConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001080 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001081 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001082 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001083 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -08001084 << gIBaseFqName.cppName()
1085 << "> {\n";
1086 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001087 out << "return new "
1088 << iface->getPassthroughName()
1089 << "(reinterpret_cast<"
1090 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001091 << " *>(iIntf));\n";
1092 });
Yifan Hongb04de382017-02-06 15:31:52 -08001093 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001094 });
Yifan Hong158655a2016-11-08 12:34:07 -08001095 });
Martijn Coenen8adcb652017-02-03 17:37:36 +01001096 out << "};\n\n";
1097 out << "__attribute__((destructor))";
1098 out << "static void static_destructor() {\n";
1099 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001100 out << "::android::hardware::details::gBnConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001101 << iface->localName()
1102 << "::descriptor);\n";
Yifan Honga159f3b2017-03-16 14:53:51 -07001103 out << "::android::hardware::details::gBsConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001104 << iface->localName()
1105 << "::descriptor);\n";
1106 });
1107 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001108
Yifan Hongfe95aa22016-10-19 17:26:45 -07001109 err = generateInterfaceSource(out);
1110 }
1111
1112 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001113 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001114 }
1115
1116 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001117 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001118 }
1119
Steven Moreland40786312016-08-16 10:29:40 -07001120 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001121 err = generatePassthroughSource(out);
1122 }
1123
1124 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001125 const Interface *iface = mRootScope->getInterface();
1126
Yifan Hongc8934042016-11-17 17:10:52 -08001127 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001128 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001129 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001130 std::string package = iface->fqName().package()
1131 + iface->fqName().atVersion();
1132
Yifan Hongeefe4f22017-01-04 15:32:42 -08001133 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001134 }
Steven Moreland40786312016-08-16 10:29:40 -07001135 }
1136
Andreas Huber881227d2016-08-02 14:20:21 -07001137 enterLeaveNamespace(out, false /* enter */);
1138
1139 return err;
1140}
1141
Steven Moreland67f67b42016-09-29 08:59:02 -07001142// static
1143void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001144 out.sIf(nonNull + " == nullptr", [&] {
1145 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1146 out.indent(2, [&] {
1147 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1148 });
1149 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001150}
1151
Andreas Huber881227d2016-08-02 14:20:21 -07001152status_t AST::generateTypeSource(
1153 Formatter &out, const std::string &ifaceName) const {
1154 return mRootScope->emitTypeDefinitions(out, ifaceName);
1155}
1156
Andreas Hubere7ff2282016-08-16 13:50:03 -07001157void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001158 Formatter &out,
1159 const std::vector<TypedVar *> &args,
1160 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001161 if (args.empty()) {
1162 return;
1163 }
1164
1165 for (const auto &arg : args) {
1166 const Type &type = arg->type();
1167
Yifan Hong3b320f82016-11-01 15:15:54 -07001168 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001169 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001170 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001171 << ";\n";
1172 }
1173
1174 out << "\n";
1175}
1176
Andreas Huber881227d2016-08-02 14:20:21 -07001177void AST::emitCppReaderWriter(
1178 Formatter &out,
1179 const std::string &parcelObj,
1180 bool parcelObjIsPointer,
1181 const TypedVar *arg,
1182 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001183 Type::ErrorMode mode,
1184 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001185 const Type &type = arg->type();
1186
Andreas Huber881227d2016-08-02 14:20:21 -07001187 type.emitReaderWriter(
1188 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001189 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001190 parcelObj,
1191 parcelObjIsPointer,
1192 isReader,
1193 mode);
1194}
1195
Yifan Hongbf459bc2016-08-23 16:50:37 -07001196void AST::emitCppResolveReferences(
1197 Formatter &out,
1198 const std::string &parcelObj,
1199 bool parcelObjIsPointer,
1200 const TypedVar *arg,
1201 bool isReader,
1202 Type::ErrorMode mode,
1203 bool addPrefixToName) const {
1204 const Type &type = arg->type();
1205 if(type.needsResolveReferences()) {
1206 type.emitResolveReferences(
1207 out,
1208 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1209 isReader, // nameIsPointer
1210 parcelObj,
1211 parcelObjIsPointer,
1212 isReader,
1213 mode);
1214 }
1215}
1216
Yifan Hong068c5522016-10-31 14:07:25 -07001217status_t AST::generateProxyMethodSource(Formatter &out,
1218 const std::string &klassName,
1219 const Method *method,
1220 const Interface *superInterface) const {
1221
1222 method->generateCppSignature(out,
1223 klassName,
1224 true /* specify namespaces */);
1225
1226 const bool returnsValue = !method->results().empty();
1227 const TypedVar *elidedReturn = method->canElideCallback();
1228
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001229 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001230
1231 out.indent();
1232
Martijn Coenen115d4282016-12-19 05:14:04 +01001233 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1234 method->cppImpl(IMPL_PROXY, out);
1235 out.unindent();
1236 out << "}\n\n";
1237 return OK;
1238 }
1239
Yifan Hong068c5522016-10-31 14:07:25 -07001240 if (returnsValue && elidedReturn == nullptr) {
1241 generateCheckNonNull(out, "_hidl_cb");
1242 }
1243
1244 status_t status = generateCppInstrumentationCall(
1245 out,
1246 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001247 method);
1248 if (status != OK) {
1249 return status;
1250 }
1251
1252 out << "::android::hardware::Parcel _hidl_data;\n";
1253 out << "::android::hardware::Parcel _hidl_reply;\n";
1254 out << "::android::status_t _hidl_err;\n";
1255 out << "::android::hardware::Status _hidl_status;\n\n";
1256
1257 declareCppReaderLocals(
1258 out, method->results(), true /* forResults */);
1259
1260 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001261 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001262 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001263 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1264
Martijn Coenenfff73352017-01-04 16:36:31 +01001265 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001266 // First DFS: write all buffers and resolve pointers for parent
1267 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001268 if (arg->type().isInterface()) {
1269 hasInterfaceArgument = true;
1270 }
Yifan Hong068c5522016-10-31 14:07:25 -07001271 emitCppReaderWriter(
1272 out,
1273 "_hidl_data",
1274 false /* parcelObjIsPointer */,
1275 arg,
1276 false /* reader */,
1277 Type::ErrorMode_Goto,
1278 false /* addPrefixToName */);
1279 }
1280
1281 // Second DFS: resolve references.
1282 for (const auto &arg : method->args()) {
1283 emitCppResolveReferences(
1284 out,
1285 "_hidl_data",
1286 false /* parcelObjIsPointer */,
1287 arg,
1288 false /* reader */,
1289 Type::ErrorMode_Goto,
1290 false /* addPrefixToName */);
1291 }
1292
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001293 if (hasInterfaceArgument) {
1294 // Start binder threadpool to handle incoming transactions
1295 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1296 }
Yifan Hong068c5522016-10-31 14:07:25 -07001297 out << "_hidl_err = remote()->transact("
1298 << method->getSerialId()
1299 << " /* "
1300 << method->name()
1301 << " */, _hidl_data, &_hidl_reply";
1302
1303 if (method->isOneway()) {
1304 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1305 }
1306 out << ");\n";
1307
1308 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1309
1310 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001311 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001312 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1313 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1314
1315
1316 // First DFS: write all buffers and resolve pointers for parent
1317 for (const auto &arg : method->results()) {
1318 emitCppReaderWriter(
1319 out,
1320 "_hidl_reply",
1321 false /* parcelObjIsPointer */,
1322 arg,
1323 true /* reader */,
1324 Type::ErrorMode_Goto,
1325 true /* addPrefixToName */);
1326 }
1327
1328 // Second DFS: resolve references.
1329 for (const auto &arg : method->results()) {
1330 emitCppResolveReferences(
1331 out,
1332 "_hidl_reply",
1333 false /* parcelObjIsPointer */,
1334 arg,
1335 true /* reader */,
1336 Type::ErrorMode_Goto,
1337 true /* addPrefixToName */);
1338 }
1339
1340 if (returnsValue && elidedReturn == nullptr) {
1341 out << "_hidl_cb(";
1342
Yifan Hong7d234ea2017-03-30 15:40:22 -07001343 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001344 if (arg->type().resultNeedsDeref()) {
1345 out << "*";
1346 }
1347 out << "_hidl_out_" << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001348 });
Yifan Hong068c5522016-10-31 14:07:25 -07001349
1350 out << ");\n\n";
1351 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001352 }
1353 status = generateCppInstrumentationCall(
1354 out,
1355 InstrumentationEvent::CLIENT_API_EXIT,
1356 method);
1357 if (status != OK) {
1358 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001359 }
1360
1361 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001362 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1363 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001364 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001365 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1366 } else {
1367 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1368 out << "return ::android::hardware::Return<void>();\n\n";
1369 }
1370
1371 out.unindent();
1372 out << "_hidl_error:\n";
1373 out.indent();
1374 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1375 out << "return ::android::hardware::Return<";
1376 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001377 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001378 } else {
1379 out << "void";
1380 }
1381 out << ">(_hidl_status);\n";
1382
1383 out.unindent();
1384 out << "}\n\n";
1385 return OK;
1386}
1387
Andreas Huber881227d2016-08-02 14:20:21 -07001388status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001389 Formatter &out, const FQName &fqName) const {
1390 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001391
1392 out << klassName
1393 << "::"
1394 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001395 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001396
1397 out.indent();
1398 out.indent();
1399
1400 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001401 << "<"
1402 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001403 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001404 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001405 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001406 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001407 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001408 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001409
Andreas Huber881227d2016-08-02 14:20:21 -07001410 out.unindent();
1411 out.unindent();
1412 out << "}\n\n";
1413
Yifan Hong068c5522016-10-31 14:07:25 -07001414 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1415 return generateProxyMethodSource(out, klassName, method, superInterface);
1416 });
Andreas Huber881227d2016-08-02 14:20:21 -07001417
Yifan Hong068c5522016-10-31 14:07:25 -07001418 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001419}
1420
1421status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001422 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001423 const Interface *iface) const {
1424 const std::string interfaceName = iface->localName();
1425 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001426
Steven Moreland40786312016-08-16 10:29:40 -07001427 out << klassName
1428 << "::"
1429 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001430 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001431
1432 out.indent();
1433 out.indent();
1434
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001435 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001436 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001437 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001438 out << ": "
1439 << gIBaseFqName.getInterfaceStubFqName().cppName()
1440 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001441 }
1442
1443 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001444 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001445 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001446 << "\") { \n";
1447 out.indent();
1448 out << "_hidl_mImpl = _hidl_impl;\n";
1449 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001450
1451 out.unindent();
1452 out.unindent();
1453 out << "}\n\n";
1454
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001455 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001456 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001457 // class properly.
1458 out << klassName
1459 << "::"
1460 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001461 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1462 << " const std::string &HidlInstrumentor_package,"
1463 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001464
1465 out.indent();
1466 out.indent();
1467
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001468 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001469 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001470 out.indent();
1471 out << "_hidl_mImpl = _hidl_impl;\n";
1472 out.unindent();
1473
1474 out.unindent();
1475 out.unindent();
1476 out << "}\n\n";
1477 }
1478
Yifan Hongbcffce22017-02-01 15:52:06 -08001479 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1480 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1481 return OK;
1482 }
1483 method->generateCppSignature(out, iface->getStubName());
1484 out << " ";
1485 out.block([&] {
1486 method->cppImpl(IMPL_STUB_IMPL, out);
1487 }).endl();
1488 return OK;
1489 });
Steven Moreland60818632017-02-04 00:33:42 -08001490 if (err != OK) {
1491 return err;
1492 }
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001493
Andreas Huber881227d2016-08-02 14:20:21 -07001494 out << "::android::status_t " << klassName << "::onTransact(\n";
1495
1496 out.indent();
1497 out.indent();
1498
Iliyan Malchev549e2592016-08-10 08:59:12 -07001499 out << "uint32_t _hidl_code,\n"
1500 << "const ::android::hardware::Parcel &_hidl_data,\n"
1501 << "::android::hardware::Parcel *_hidl_reply,\n"
1502 << "uint32_t _hidl_flags,\n"
1503 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001504
1505 out.unindent();
1506
Iliyan Malchev549e2592016-08-10 08:59:12 -07001507 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001508 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001509 out.indent();
1510
Yifan Hong10fe0b52016-10-19 14:20:17 -07001511 for (const auto &tuple : iface->allMethodsFromRoot()) {
1512 const Method *method = tuple.method();
1513 const Interface *superInterface = tuple.interface();
1514 out << "case "
1515 << method->getSerialId()
1516 << " /* "
1517 << method->name()
1518 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001519
Yifan Hong10fe0b52016-10-19 14:20:17 -07001520 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001521
Yifan Hong10fe0b52016-10-19 14:20:17 -07001522 status_t err =
1523 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001524
Yifan Hong10fe0b52016-10-19 14:20:17 -07001525 if (err != OK) {
1526 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001527 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001528
1529 out.unindent();
1530 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001531 }
1532
1533 out << "default:\n{\n";
1534 out.indent();
1535
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001536 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001537
1538 out.indent();
1539 out.indent();
1540
Iliyan Malchev549e2592016-08-10 08:59:12 -07001541 out << "_hidl_code, _hidl_data, _hidl_reply, "
1542 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001543
1544 out.unindent();
1545 out.unindent();
1546
1547 out.unindent();
1548 out << "}\n";
1549
1550 out.unindent();
1551 out << "}\n\n";
1552
Yifan Honga018ed52016-12-13 16:35:08 -08001553 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1554 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1555 out.indent(2, [&] {
1556 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1557 out << "_hidl_reply);\n";
1558 });
1559 });
Andreas Huber881227d2016-08-02 14:20:21 -07001560
Iliyan Malchev549e2592016-08-10 08:59:12 -07001561 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001562
1563 out.unindent();
1564 out << "}\n\n";
1565
1566 return OK;
1567}
1568
1569status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001570 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001571 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1572 method->cppImpl(IMPL_STUB, out);
1573 out << "break;\n";
1574 return OK;
1575 }
1576
Yifan Hongeefe4f22017-01-04 15:32:42 -08001577 out << "if (!_hidl_data.enforceInterface("
1578 << iface->fullName()
1579 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001580
Andreas Huber881227d2016-08-02 14:20:21 -07001581 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001582 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001583 out << "break;\n";
1584 out.unindent();
1585 out << "}\n\n";
1586
Andreas Huber5e44a292016-09-27 14:52:39 -07001587 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001588
Yifan Hongbf459bc2016-08-23 16:50:37 -07001589 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001590 for (const auto &arg : method->args()) {
1591 emitCppReaderWriter(
1592 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001593 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001594 false /* parcelObjIsPointer */,
1595 arg,
1596 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001597 Type::ErrorMode_Break,
1598 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001599 }
1600
Yifan Hongbf459bc2016-08-23 16:50:37 -07001601 // Second DFS: resolve references
1602 for (const auto &arg : method->args()) {
1603 emitCppResolveReferences(
1604 out,
1605 "_hidl_data",
1606 false /* parcelObjIsPointer */,
1607 arg,
1608 true /* reader */,
1609 Type::ErrorMode_Break,
1610 false /* addPrefixToName */);
1611 }
1612
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001613 status_t status = generateCppInstrumentationCall(
1614 out,
1615 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001616 method);
1617 if (status != OK) {
1618 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001619 }
1620
Andreas Huber881227d2016-08-02 14:20:21 -07001621 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001622 const TypedVar *elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -08001623 const std::string callee =
1624 (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL))
1625 ? "this" : "_hidl_mImpl";
Andreas Huber881227d2016-08-02 14:20:21 -07001626
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001627 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001628 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001629 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001630 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001631 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001632 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001633 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001634
Yifan Hong7d234ea2017-03-30 15:40:22 -07001635 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001636 if (arg->type().resultNeedsDeref()) {
1637 out << "*";
1638 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001639 out << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001640 });
Andreas Huber881227d2016-08-02 14:20:21 -07001641
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001642 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001643 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1644 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001645
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001646 elidedReturn->type().emitReaderWriter(
1647 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001648 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001649 "_hidl_reply",
1650 true, /* parcelObjIsPointer */
1651 false, /* isReader */
1652 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001653
Yifan Hongbf459bc2016-08-23 16:50:37 -07001654 emitCppResolveReferences(
1655 out,
1656 "_hidl_reply",
1657 true /* parcelObjIsPointer */,
1658 elidedReturn,
1659 false /* reader */,
1660 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001661 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001662
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001663 status_t status = generateCppInstrumentationCall(
1664 out,
1665 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001666 method);
1667 if (status != OK) {
1668 return status;
1669 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001670
Iliyan Malchev549e2592016-08-10 08:59:12 -07001671 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001672 } else {
1673 if (returnsValue) {
1674 out << "bool _hidl_callbackCalled = false;\n\n";
1675 }
Andreas Huber881227d2016-08-02 14:20:21 -07001676
Yifan Hongcd2ae452017-01-31 14:33:40 -08001677 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001678
Yifan Hong7d234ea2017-03-30 15:40:22 -07001679 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001680 if (arg->type().resultNeedsDeref()) {
1681 out << "*";
1682 }
1683
1684 out << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001685 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001686
1687 if (returnsValue) {
Yifan Hong7d234ea2017-03-30 15:40:22 -07001688 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001689 out << ", ";
1690 }
1691
1692 out << "[&](";
1693
Yifan Hong7d234ea2017-03-30 15:40:22 -07001694 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001695 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001696 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001697
1698 out << ") {\n";
1699 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001700 out << "if (_hidl_callbackCalled) {\n";
1701 out.indent();
1702 out << "LOG_ALWAYS_FATAL(\""
1703 << method->name()
1704 << ": _hidl_cb called a second time, but must be called once.\");\n";
1705 out.unindent();
1706 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001707 out << "_hidl_callbackCalled = true;\n\n";
1708
Yifan Hong859e53f2016-11-14 19:08:24 -08001709 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1710 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001711
Yifan Hongbf459bc2016-08-23 16:50:37 -07001712 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001713 for (const auto &arg : method->results()) {
1714 emitCppReaderWriter(
1715 out,
1716 "_hidl_reply",
1717 true /* parcelObjIsPointer */,
1718 arg,
1719 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001720 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001721 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001722 }
1723
Yifan Hongbf459bc2016-08-23 16:50:37 -07001724 // Second DFS: resolve references
1725 for (const auto &arg : method->results()) {
1726 emitCppResolveReferences(
1727 out,
1728 "_hidl_reply",
1729 true /* parcelObjIsPointer */,
1730 arg,
1731 false /* reader */,
1732 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001733 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001734 }
1735
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001736 status_t status = generateCppInstrumentationCall(
1737 out,
1738 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001739 method);
1740 if (status != OK) {
1741 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001742 }
1743
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001744 out << "_hidl_cb(*_hidl_reply);\n";
1745
1746 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001747 out << "});\n\n";
1748 } else {
1749 out << ");\n\n";
1750 status_t status = generateCppInstrumentationCall(
1751 out,
1752 InstrumentationEvent::SERVER_API_EXIT,
1753 method);
1754 if (status != OK) {
1755 return status;
1756 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001757 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001758
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001759 if (returnsValue) {
1760 out << "if (!_hidl_callbackCalled) {\n";
1761 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001762 out << "LOG_ALWAYS_FATAL(\""
1763 << method->name()
1764 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001765 out.unindent();
1766 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001767 } else {
1768 out << "::android::hardware::writeToParcel("
1769 << "::android::hardware::Status::ok(), "
1770 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001771 }
Andreas Huber881227d2016-08-02 14:20:21 -07001772 }
1773
1774 out << "break;\n";
1775
1776 return OK;
1777}
1778
Steven Moreland69e7c702016-09-09 11:16:32 -07001779status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1780 std::string ifaceName;
1781 if (!AST::isInterface(&ifaceName)) {
1782 // types.hal does not get a stub header.
1783 return OK;
1784 }
1785
1786 const Interface *iface = mRootScope->getInterface();
1787
Yifan Hongeefe4f22017-01-04 15:32:42 -08001788 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001789
1790 bool supportOneway = iface->hasOnewayMethods();
1791
1792 std::string path = outputPath;
1793 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1794 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1795 path.append(klassName);
1796 path.append(".h");
1797
1798 CHECK(Coordinator::MakeParentHierarchy(path));
1799 FILE *file = fopen(path.c_str(), "w");
1800
1801 if (file == NULL) {
1802 return -errno;
1803 }
1804
1805 Formatter out(file);
1806
1807 const std::string guard = makeHeaderGuard(klassName);
1808
1809 out << "#ifndef " << guard << "\n";
1810 out << "#define " << guard << "\n\n";
1811
1812 std::vector<std::string> packageComponents;
1813 getPackageAndVersionComponents(
1814 &packageComponents, false /* cpp_compatible */);
1815
Yifan Hongb0949432016-12-15 15:32:24 -08001816 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001817 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001818
1819 generateCppPackageInclude(out, mPackage, ifaceName);
1820 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001821
Yifan Hong7a118f52016-12-07 11:21:15 -08001822 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001823 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001824 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001825 }
1826
1827 enterLeaveNamespace(out, true /* enter */);
1828 out << "\n";
1829
1830 out << "struct "
1831 << klassName
1832 << " : " << ifaceName
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001833 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001834
1835 out.indent();
1836 out << "explicit "
1837 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001838 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001839 << ifaceName
1840 << "> impl);\n";
1841
Yifan Hong068c5522016-10-31 14:07:25 -07001842 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1843 return generatePassthroughMethod(out, method);
1844 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001845
1846 if (err != OK) {
1847 return err;
1848 }
1849
1850 out.unindent();
1851 out << "private:\n";
1852 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001853 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001854
1855 if (supportOneway) {
Yifan Hongef91d362017-03-20 17:18:13 -07001856 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001857
1858 out << "\n";
1859
1860 out << "::android::hardware::Return<void> addOnewayTask("
1861 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001862 }
1863
1864 out.unindent();
1865
1866 out << "};\n\n";
1867
1868 enterLeaveNamespace(out, false /* enter */);
1869
1870 out << "\n#endif // " << guard << "\n";
1871
1872 return OK;
1873}
1874
Yifan Hongfe95aa22016-10-19 17:26:45 -07001875status_t AST::generateInterfaceSource(Formatter &out) const {
1876 const Interface *iface = mRootScope->getInterface();
1877
Yifan Hong2d7126b2016-10-20 15:12:57 -07001878 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001879 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001880
Steven Morelandd4b068a2017-03-20 06:30:51 -07001881 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1882 bool reserved = method->isHidlReserved();
1883
1884 if (!reserved) {
1885 out << "// no default implementation for: ";
1886 }
1887 method->generateCppSignature(out, iface->localName());
1888 if (reserved) {
1889 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001890 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001891 }).endl();
1892 }
1893
1894 out << "\n";
1895
1896 return OK;
1897 });
1898 if (err != OK) {
1899 return err;
1900 }
1901
Yifan Hong3d746092016-12-07 14:26:33 -08001902 for (const Interface *superType : iface->typeChain()) {
Yifan Hong7783bb02017-03-29 03:39:09 -07001903 out << "// static \n::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -08001904 << childTypeResult
Yifan Hong7783bb02017-03-29 03:39:09 -07001905 << "> "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001906 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001907 << "::castFrom("
1908 << superType->getCppArgumentType()
Yifan Hong7783bb02017-03-29 03:39:09 -07001909 << " parent, bool "
1910 << (iface == superType ? "/* emitError */" : "emitError")
1911 << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001912 out.indent();
1913 if (iface == superType) {
1914 out << "return parent;\n";
1915 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001916 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001917 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001918 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001919 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001920 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001921 << ">(\n";
1922 out.indent();
1923 out.indent();
1924 out << "parent, \""
1925 << iface->fqName().string()
Yifan Hong7783bb02017-03-29 03:39:09 -07001926 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001927 out.unindent();
1928 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001929 }
Yifan Hong3d746092016-12-07 14:26:33 -08001930 out.unindent();
1931 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001932 }
1933
1934 return OK;
1935}
1936
Steven Moreland69e7c702016-09-09 11:16:32 -07001937status_t AST::generatePassthroughSource(Formatter &out) const {
1938 const Interface *iface = mRootScope->getInterface();
1939
Yifan Hongeefe4f22017-01-04 15:32:42 -08001940 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001941
1942 out << klassName
1943 << "::"
1944 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001945 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001946 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001947 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001948 << mPackage.string()
1949 << "\", \""
1950 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001951 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001952 if (iface->hasOnewayMethods()) {
1953 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001954 out.indent([&] {
Yifan Hongf01dad42017-03-20 19:03:11 -07001955 out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001956 });
1957 }
1958 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001959
1960 if (iface->hasOnewayMethods()) {
1961 out << "::android::hardware::Return<void> "
1962 << klassName
1963 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1964 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001965 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001966 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001967 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1968 out.indent();
1969 out.indent();
1970 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1971 out.unindent();
1972 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001973 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001974 out << "}\n";
1975
Steven Morelandd366c262016-10-11 15:29:10 -07001976 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001977
1978 out.unindent();
1979 out << "}\n\n";
1980
1981
1982 }
1983
1984 return OK;
1985}
1986
Martijn Coenen7b295242016-11-04 16:52:56 +01001987status_t AST::generateCppAtraceCall(Formatter &out,
1988 InstrumentationEvent event,
1989 const Method *method) const {
1990 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001991 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001992 switch (event) {
1993 case SERVER_API_ENTRY:
1994 {
1995 out << "atrace_begin(ATRACE_TAG_HAL, \""
1996 << baseString + "::server\");\n";
1997 break;
1998 }
1999 case CLIENT_API_ENTRY:
2000 {
2001 out << "atrace_begin(ATRACE_TAG_HAL, \""
2002 << baseString + "::client\");\n";
2003 break;
2004 }
2005 case PASSTHROUGH_ENTRY:
2006 {
2007 out << "atrace_begin(ATRACE_TAG_HAL, \""
2008 << baseString + "::passthrough\");\n";
2009 break;
2010 }
2011 case SERVER_API_EXIT:
2012 case CLIENT_API_EXIT:
2013 case PASSTHROUGH_EXIT:
2014 {
2015 out << "atrace_end(ATRACE_TAG_HAL);\n";
2016 break;
2017 }
2018 default:
2019 {
2020 LOG(ERROR) << "Unsupported instrumentation event: " << event;
2021 return UNKNOWN_ERROR;
2022 }
2023 }
2024
2025 return OK;
2026}
2027
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002028status_t AST::generateCppInstrumentationCall(
2029 Formatter &out,
2030 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07002031 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01002032 status_t err = generateCppAtraceCall(out, event, method);
2033 if (err != OK) {
2034 return err;
2035 }
2036
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002037 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
2038 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002039 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002040 std::string event_str = "";
2041 switch (event) {
2042 case SERVER_API_ENTRY:
2043 {
2044 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
2045 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002046 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002047 << (arg->type().resultNeedsDeref() ? "" : "&")
2048 << arg->name()
2049 << ");\n";
2050 }
2051 break;
2052 }
2053 case SERVER_API_EXIT:
2054 {
2055 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07002056 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002057 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07002058 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002059 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002060 }
2061 break;
2062 }
2063 case CLIENT_API_ENTRY:
2064 {
2065 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2066 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002067 out << "_hidl_args.push_back((void *)&"
2068 << arg->name()
2069 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002070 }
2071 break;
2072 }
2073 case CLIENT_API_EXIT:
2074 {
2075 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2076 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002077 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002078 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002079 << "_hidl_out_"
2080 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002081 << ");\n";
2082 }
2083 break;
2084 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002085 case PASSTHROUGH_ENTRY:
2086 {
2087 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2088 for (const auto &arg : method->args()) {
2089 out << "_hidl_args.push_back((void *)&"
2090 << arg->name()
2091 << ");\n";
2092 }
2093 break;
2094 }
2095 case PASSTHROUGH_EXIT:
2096 {
2097 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002098 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002099 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002100 << arg->name()
2101 << ");\n";
2102 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002103 break;
2104 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002105 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002106 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002107 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002108 return UNKNOWN_ERROR;
2109 }
2110 }
2111
Steven Moreland031ccf12016-10-31 15:54:38 -07002112 const Interface *iface = mRootScope->getInterface();
2113
Steven Moreland1ab31442016-11-03 18:37:51 -07002114 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002115 out.indent();
2116 out << "callback("
2117 << event_str
2118 << ", \""
2119 << mPackage.package()
2120 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002121 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002122 << "\", \""
2123 << iface->localName()
2124 << "\", \""
2125 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002126 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002127 out.unindent();
2128 out << "}\n";
2129 out.unindent();
2130 out << "}\n\n";
2131
2132 return OK;
2133}
2134
Andreas Huber881227d2016-08-02 14:20:21 -07002135} // namespace android