blob: 35cdcae3878072b07cc81ca7a62fc0a79e7b6bea [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"
Yifan Hongdd0b55d2017-04-04 13:27:25 -0700248 << (isTry ? "break" : "continue")
249 << ";\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000250 }).endl();
Yifan Hong7783bb02017-03-29 03:39:09 -0700251 out << "::android::hardware::Return<::android::sp<" << interfaceName
252 << ">> castRet = " << interfaceName << "::castFrom(base, true /* emitError */);\n";
253 out.sIf("!castRet.isOk()", [&] {
254 out.sIf("castRet.isDeadObject()", [&] {
255 // service is dead (castFrom cannot call interfaceChain)
256 out << "ALOGW(\"getService: found dead hwbinder service\");\n"
Yifan Hongdd0b55d2017-04-04 13:27:25 -0700257 << (isTry ? "break" : "continue")
258 << ";\n";
Yifan Hong7783bb02017-03-29 03:39:09 -0700259 }).sElse([&] {
260 out << "ALOGW(\"getService: cannot call into hwbinder service: %s"
261 << "; No permission? Check for selinux denials.\", "
262 << "castRet.description().c_str());\n"
263 << "break;\n";
264 }).endl();
265 }).endl();
266 out << "iface = castRet;\n";
267 out.sIf("iface == nullptr", [&] {
268 // returned service isn't of correct type; this is a bug
269 // to hwservicemanager or to the service itself (interfaceChain
270 // is not consistent).
271 out << "ALOGW(\"getService: received incompatible service; bug in hwservicemanager?\");\n"
272 << "break;\n";
273 }).endl();
Yifan Hong31f07ff2017-03-21 18:56:35 +0000274
275 out << "return iface;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800276 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800277
Yifan Hong31f07ff2017-03-21 18:56:35 +0000278 out.sIf("getStub || vintfPassthru || vintfEmpty", [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000279 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> pm\n";
Steven Morelande3fa5da2017-01-25 07:07:53 +0000280 out.indent(2, [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000281 out << "= ::android::hardware::getPassthroughServiceManager();\n";
Steven Morelande3fa5da2017-01-25 07:07:53 +0000282 });
Steven Morelandf10af872017-01-25 16:01:56 +0000283
284 out.sIf("pm != nullptr", [&] () {
285 out << "::android::hardware::Return<::android::sp<" << gIBaseFqName.cppName() << ">> ret = \n";
286 out.indent(2, [&] {
287 out << "pm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
Steven Moreland2c2dea82017-01-18 17:24:17 -0800288 });
Steven Morelandf10af872017-01-25 16:01:56 +0000289 out.sIf("ret.isOk()", [&] {
290 out << "::android::sp<" << gIBaseFqName.cppName()
291 << "> baseInterface = ret;\n";
292 out.sIf("baseInterface != nullptr", [&]() {
293 out << "iface = new " << fqName.getInterfacePassthroughName()
294 << "(" << interfaceName << "::castFrom(baseInterface));\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000295 }).endl();
Steven Morelandf10af872017-01-25 16:01:56 +0000296 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800297 }).endl();
298 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800299
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800300 out << "return iface;\n";
301 }).endl().endl();
Steven Morelandeec5f7a2017-03-30 12:11:24 -0700302}
303
304static void implementServiceManagerInteractions(Formatter &out,
305 const FQName &fqName, const std::string &package) {
306
307 const std::string interfaceName = fqName.getInterfaceName();
308
309 implementGetService(out, fqName, true /* isTry */);
310 implementGetService(out, fqName, false /* isTry */);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800311
Yifan Hongeefe4f22017-01-04 15:32:42 -0800312 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800313 << "const std::string &serviceName) ";
314 out.block([&] {
315 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
316 out.indent(2, [&] {
317 out << "= ::android::hardware::defaultServiceManager();\n";
318 });
319 out.sIf("sm == nullptr", [&] {
320 out << "return ::android::INVALID_OPERATION;\n";
321 }).endl();
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100322 out << "::android::hardware::Return<bool> ret = "
323 << "sm->add(serviceName.c_str(), this);\n"
324 << "return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800325 }).endl().endl();
326
Yifan Hongeefe4f22017-01-04 15:32:42 -0800327 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800328 out.indent(2, [&] {
329 out << "const std::string &serviceName,\n"
330 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
331 << "&notification) ";
332 });
333 out.block([&] {
334 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
335 out.indent(2, [&] {
336 out << "= ::android::hardware::defaultServiceManager();\n";
337 });
338 out.sIf("sm == nullptr", [&] {
339 out << "return false;\n";
340 }).endl();
341 out << "::android::hardware::Return<bool> success =\n";
342 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800343 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800344 out.indent(2, [&] {
345 out << "serviceName, notification);\n";
346 });
347 });
348 out << "return success.isOk() && success;\n";
349 }).endl().endl();
350}
351
Andreas Huberb82318c2016-08-02 14:45:54 -0700352status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700353
Andreas Huberb82318c2016-08-02 14:45:54 -0700354 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700355 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700356 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700357
358 std::string ifaceName;
359 bool isInterface = true;
360 if (!AST::isInterface(&ifaceName)) {
361 ifaceName = "types";
362 isInterface = false;
363 }
364 path.append(ifaceName);
365 path.append(".h");
366
Andreas Huberd2943e12016-08-05 11:59:31 -0700367 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700368 FILE *file = fopen(path.c_str(), "w");
369
370 if (file == NULL) {
371 return -errno;
372 }
373
374 Formatter out(file);
375
376 const std::string guard = makeHeaderGuard(ifaceName);
377
378 out << "#ifndef " << guard << "\n";
379 out << "#define " << guard << "\n\n";
380
Andreas Huber737080b2016-08-02 15:38:04 -0700381 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700382 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700383 }
384
385 if (!mImportedNames.empty()) {
386 out << "\n";
387 }
388
Steven Moreland0693f312016-11-09 15:06:14 -0800389 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800390 if (isIBase()) {
391 out << "// skipped #include IServiceNotification.h\n\n";
392 } else {
393 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
394 }
Steven Moreland0693f312016-11-09 15:06:14 -0800395 }
396
Yifan Hongc8934042016-11-17 17:10:52 -0800397 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700398 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700399
400 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200401 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700402 }
403
Martijn Coenenaf712c02016-11-16 15:26:27 +0100404 out << "#include <utils/NativeHandle.h>\n";
405 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700406
407 enterLeaveNamespace(out, true /* enter */);
408 out << "\n";
409
410 if (isInterface) {
411 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700412 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700413
414 const Interface *iface = mRootScope->getInterface();
415 const Interface *superType = iface->superType();
416
Steven Moreland40786312016-08-16 10:29:40 -0700417 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800418 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700419 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000420 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700421 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700422 }
423
424 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700425
426 out.indent();
427
Andreas Huber881227d2016-08-02 14:20:21 -0700428 }
429
430 status_t err = emitTypeDeclarations(out);
431
432 if (err != OK) {
433 return err;
434 }
435
436 if (isInterface) {
437 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800438
Yifan Hongc8934042016-11-17 17:10:52 -0800439 out << "virtual bool isRemote() const ";
440 if (!isIBase()) {
441 out << "override ";
442 }
443 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800444
Andreas Huber881227d2016-08-02 14:20:21 -0700445 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700446 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700447
Andreas Huber881227d2016-08-02 14:20:21 -0700448 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800449 const TypedVar *elidedReturn = method->canElideCallback();
450
451 if (elidedReturn == nullptr && returnsValue) {
452 out << "using "
453 << method->name()
Yifan Hong7d234ea2017-03-30 15:40:22 -0700454 << "_cb = std::function<void(";
455 method->emitCppResultSignature(out, true /* specify namespaces */);
456 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800457 }
Andreas Huber881227d2016-08-02 14:20:21 -0700458
Andreas Huber3599d922016-08-09 10:42:57 -0700459 method->dumpAnnotations(out);
460
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700461 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700462 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700463 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700464 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700465 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700466 }
467
468 out << method->name()
Yifan Hong7d234ea2017-03-30 15:40:22 -0700469 << "(";
470 method->emitCppArgSignature(out, true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700471
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700472 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700473 if (!method->args().empty()) {
474 out << ", ";
475 }
476
Steven Moreland67f67b42016-09-29 08:59:02 -0700477 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700478 }
479
Yifan Hong10fe0b52016-10-19 14:20:17 -0700480 out << ")";
481 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800482 if (!isIBase()) {
483 out << " override";
484 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700485 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700486 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700487 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700488 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700489 }
Steven Moreland40786312016-08-16 10:29:40 -0700490
Yifan Hong3d746092016-12-07 14:26:33 -0800491 out << "// cast static functions\n";
492 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700493
Yifan Hong3d746092016-12-07 14:26:33 -0800494 for (const Interface *superType : iface->typeChain()) {
Yifan Hong7783bb02017-03-29 03:39:09 -0700495 out << "static ::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -0800496 << childTypeResult
Yifan Hong7783bb02017-03-29 03:39:09 -0700497 << "> castFrom("
Yifan Hong3d746092016-12-07 14:26:33 -0800498 << superType->getCppArgumentType()
499 << " parent"
Yifan Hong7783bb02017-03-29 03:39:09 -0700500 << ", bool emitError = false);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700501 }
502
Steven Morelandd39133b2016-11-11 12:30:08 -0800503 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700504
Yifan Hongc8934042016-11-17 17:10:52 -0800505 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800506 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800507 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800508 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800509 }
Andreas Huber881227d2016-08-02 14:20:21 -0700510 }
511
512 if (isInterface) {
513 out.unindent();
514
Andreas Hubere3f769a2016-10-10 10:54:44 -0700515 out << "};\n\n";
516 }
517
518 err = mRootScope->emitGlobalTypeDeclarations(out);
519
520 if (err != OK) {
521 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700522 }
523
524 out << "\n";
525 enterLeaveNamespace(out, false /* enter */);
526
527 out << "\n#endif // " << guard << "\n";
528
529 return OK;
530}
531
Steven Moreland40786312016-08-16 10:29:40 -0700532status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
533 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800534 bool isInterface = AST::isInterface(&ifaceName);
535 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800536 std::string klassName{};
537
538 if(isInterface) {
539 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800540 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800541 } else {
542 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700543 }
544
Steven Moreland40786312016-08-16 10:29:40 -0700545 std::string path = outputPath;
546 path.append(mCoordinator->convertPackageRootToPath(mPackage));
547 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
548 path.append(klassName + ".h");
549
Yifan Hong244e82d2016-11-11 11:13:57 -0800550 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700551
552 if (file == NULL) {
553 return -errno;
554 }
555
556 Formatter out(file);
557
558 const std::string guard = makeHeaderGuard(klassName);
559
560 out << "#ifndef " << guard << "\n";
561 out << "#define " << guard << "\n\n";
562
Yifan Hong244e82d2016-11-11 11:13:57 -0800563 if (isInterface) {
564 generateCppPackageInclude(out, mPackage, ifaceName);
565 } else {
566 generateCppPackageInclude(out, mPackage, "types");
567 }
Steven Moreland40786312016-08-16 10:29:40 -0700568
Steven Morelandee88eed2016-10-31 17:49:00 -0700569 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700570
571 for (const auto &item : mImportedNames) {
572 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800573 generateCppPackageInclude(out, item, "hwtypes");
574 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800575 generateCppPackageInclude(out, item, item.getInterfaceStubName());
576 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700577 }
Steven Moreland40786312016-08-16 10:29:40 -0700578 }
579
580 out << "\n";
581
Martijn Coenen93915102016-09-01 01:35:52 +0200582 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700583 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100584 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700585
586 out << "\n";
587
588 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700589
Yifan Hong244e82d2016-11-11 11:13:57 -0800590 status_t err = mRootScope->emitGlobalHwDeclarations(out);
591 if (err != OK) {
592 return err;
593 }
Steven Moreland40786312016-08-16 10:29:40 -0700594
595 enterLeaveNamespace(out, false /* enter */);
596
597 out << "\n#endif // " << guard << "\n";
598
599 return OK;
600}
601
Andreas Huber881227d2016-08-02 14:20:21 -0700602status_t AST::emitTypeDeclarations(Formatter &out) const {
603 return mRootScope->emitTypeDeclarations(out);
604}
605
Yifan Hong7a118f52016-12-07 11:21:15 -0800606static void wrapPassthroughArg(Formatter &out,
607 const TypedVar *arg, bool addPrefixToName,
608 std::function<void(void)> handleError) {
609 if (!arg->type().isInterface()) {
610 return;
611 }
612 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
613 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
614 + arg->name();
615 const Interface &iface = static_cast<const Interface &>(arg->type());
616 out << iface.getCppStackType() << " " << wrappedName << ";\n";
617 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
618 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
619 out << wrappedName
620 << " = "
621 << iface.fqName().cppName()
Yifan Hong052425a2017-03-13 17:06:13 -0700622 << "::castFrom(::android::hardware::details::wrapPassthrough("
Yifan Hong7a118f52016-12-07 11:21:15 -0800623 << name << "));\n";
624 out.sIf(wrappedName + " == nullptr", [&] {
625 // Fatal error. Happens when the BsFoo class is not found in the binary
626 // or any dynamic libraries.
627 handleError();
628 }).endl();
629 }).sElse([&] {
630 out << wrappedName << " = " << name << ";\n";
631 }).endl().endl();
632}
633
Steven Moreland69e7c702016-09-09 11:16:32 -0700634status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700635 const Method *method) const {
636 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700637
638 out << " {\n";
639 out.indent();
640
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800641 if (method->isHidlReserved()
642 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
643 method->cppImpl(IMPL_PASSTHROUGH, out);
644 out.unindent();
645 out << "}\n\n";
646 return OK;
647 }
648
Steven Moreland69e7c702016-09-09 11:16:32 -0700649 const bool returnsValue = !method->results().empty();
650 const TypedVar *elidedReturn = method->canElideCallback();
651
Steven Moreland67f67b42016-09-29 08:59:02 -0700652 if (returnsValue && elidedReturn == nullptr) {
653 generateCheckNonNull(out, "_hidl_cb");
654 }
655
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700656 generateCppInstrumentationCall(
657 out,
658 InstrumentationEvent::PASSTHROUGH_ENTRY,
659 method);
660
Yifan Hong7a118f52016-12-07 11:21:15 -0800661
662 for (const auto &arg : method->args()) {
663 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
664 out << "return ::android::hardware::Status::fromExceptionCode(\n";
665 out.indent(2, [&] {
666 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800667 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800668 });
669 });
670 }
671
672 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700673 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700674
675 if (method->isOneway()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800676 out << "addOnewayTask([this, &_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700677 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800678 out << ", "
679 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
680 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700681 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700682 out << "] {\n";
683 out.indent();
684 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700685 }
686
687 out << "mImpl->"
688 << method->name()
689 << "(";
690
Yifan Hong7d234ea2017-03-30 15:40:22 -0700691 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800692 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700693 });
Steven Moreland69e7c702016-09-09 11:16:32 -0700694 if (returnsValue && elidedReturn == nullptr) {
695 if (!method->args().empty()) {
696 out << ", ";
697 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800698 out << "[&](";
Yifan Hong7d234ea2017-03-30 15:40:22 -0700699 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800700 out << "const auto &_hidl_out_"
701 << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700702 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800703
704 out << ") {\n";
705 out.indent();
706 status_t status = generateCppInstrumentationCall(
707 out,
708 InstrumentationEvent::PASSTHROUGH_EXIT,
709 method);
710 if (status != OK) {
711 return status;
712 }
713
Yifan Hong7a118f52016-12-07 11:21:15 -0800714 for (const auto &arg : method->results()) {
715 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
716 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
717 out.indent(2, [&] {
718 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800719 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800720 });
721 out << "return;\n";
722 });
723 }
724
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800725 out << "_hidl_cb(";
Yifan Hong7d234ea2017-03-30 15:40:22 -0700726 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800727 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
728 << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -0700729 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800730 out << ");\n";
731 out.unindent();
732 out << "});\n\n";
733 } else {
734 out << ");\n\n";
735 if (elidedReturn != nullptr) {
736 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800737 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800738 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000739 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800740 }
741 status_t status = generateCppInstrumentationCall(
742 out,
743 InstrumentationEvent::PASSTHROUGH_EXIT,
744 method);
745 if (status != OK) {
746 return status;
747 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700748 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700749
750 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700751 out.unindent();
752 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700753 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700754
755 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700756
757 out.unindent();
758 out << "}\n";
759
760 return OK;
761}
762
Yifan Hong068c5522016-10-31 14:07:25 -0700763status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700764
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700765 const Interface *iface = mRootScope->getInterface();
766
Yifan Hong10fe0b52016-10-19 14:20:17 -0700767 const Interface *prevIterface = nullptr;
768 for (const auto &tuple : iface->allMethodsFromRoot()) {
769 const Method *method = tuple.method();
770 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700771
Yifan Hong10fe0b52016-10-19 14:20:17 -0700772 if(prevIterface != superInterface) {
773 if (prevIterface != nullptr) {
774 out << "\n";
775 }
776 out << "// Methods from "
777 << superInterface->fullName()
778 << " follow.\n";
779 prevIterface = superInterface;
780 }
Yifan Hong068c5522016-10-31 14:07:25 -0700781 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700782
Yifan Hong10fe0b52016-10-19 14:20:17 -0700783 if (err != OK) {
784 return err;
785 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700786 }
787
Yifan Hong10fe0b52016-10-19 14:20:17 -0700788 out << "\n";
789
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700790 return OK;
791}
792
Andreas Huberb82318c2016-08-02 14:45:54 -0700793status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700794 std::string ifaceName;
795 if (!AST::isInterface(&ifaceName)) {
796 // types.hal does not get a stub header.
797 return OK;
798 }
799
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700800 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800801 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700802
Andreas Huberb82318c2016-08-02 14:45:54 -0700803 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700804 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700805 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700806 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700807 path.append(".h");
808
Andreas Huberd2943e12016-08-05 11:59:31 -0700809 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700810 FILE *file = fopen(path.c_str(), "w");
811
812 if (file == NULL) {
813 return -errno;
814 }
815
816 Formatter out(file);
817
Steven Moreland40786312016-08-16 10:29:40 -0700818 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700819
820 out << "#ifndef " << guard << "\n";
821 out << "#define " << guard << "\n\n";
822
Yifan Hongeefe4f22017-01-04 15:32:42 -0800823 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700824 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700825
826 enterLeaveNamespace(out, true /* enter */);
827 out << "\n";
828
829 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800830 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100831 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800832 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000833 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100834 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800835 out << " : public "
836 << gIBaseFqName.getInterfaceStubFqName().cppName()
837 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100838 }
Andreas Huber881227d2016-08-02 14:20:21 -0700839
840 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800841 out << "explicit "
842 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700843 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100844 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800845 out << "explicit "
846 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100847 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800848 << " const std::string& HidlInstrumentor_package,"
849 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700850 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700851 out << "::android::status_t onTransact(\n";
852 out.indent();
853 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700854 out << "uint32_t _hidl_code,\n";
855 out << "const ::android::hardware::Parcel &_hidl_data,\n";
856 out << "::android::hardware::Parcel *_hidl_reply,\n";
857 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700858 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700859 out.unindent();
860 out.unindent();
861
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100862 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
863 out.unindent();
864 out << "private:\n";
865 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800866
867 status_t err = generateMethods(out, [&](const Method *method, const Interface *iface) {
868 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
869 return OK;
870 }
871 const bool returnsValue = !method->results().empty();
872 const TypedVar *elidedReturn = method->canElideCallback();
873
874 if (elidedReturn == nullptr && returnsValue) {
875 out << "using " << method->name() << "_cb = "
876 << iface->fqName().cppName()
877 << "::" << method->name() << "_cb;\n";
878 }
879 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800880 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800881 return OK;
882 });
883 if (err != OK) {
884 return err;
885 }
886
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100887 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700888 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700889 out << "};\n\n";
890
891 enterLeaveNamespace(out, false /* enter */);
892
893 out << "\n#endif // " << guard << "\n";
894
895 return OK;
896}
897
Andreas Huberb82318c2016-08-02 14:45:54 -0700898status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700899 std::string ifaceName;
900 if (!AST::isInterface(&ifaceName)) {
901 // types.hal does not get a proxy header.
902 return OK;
903 }
904
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700905 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800906 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700907
Andreas Huberb82318c2016-08-02 14:45:54 -0700908 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700909 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700910 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800911 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700912 path.append(".h");
913
Andreas Huberd2943e12016-08-05 11:59:31 -0700914 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700915 FILE *file = fopen(path.c_str(), "w");
916
917 if (file == NULL) {
918 return -errno;
919 }
920
921 Formatter out(file);
922
Yifan Hongeefe4f22017-01-04 15:32:42 -0800923 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700924
925 out << "#ifndef " << guard << "\n";
926 out << "#define " << guard << "\n\n";
927
Martijn Coenen115d4282016-12-19 05:14:04 +0100928 out << "#include <hidl/HidlTransportSupport.h>\n\n";
929
Andreas Huber881227d2016-08-02 14:20:21 -0700930 std::vector<std::string> packageComponents;
931 getPackageAndVersionComponents(
932 &packageComponents, false /* cpp_compatible */);
933
Yifan Hongeefe4f22017-01-04 15:32:42 -0800934 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700935 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700936
937 enterLeaveNamespace(out, true /* enter */);
938 out << "\n";
939
940 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800941 << proxyName
942 << " : public ::android::hardware::BpInterface<"
943 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000944 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700945
946 out.indent();
947
Yifan Hongeefe4f22017-01-04 15:32:42 -0800948 out << "explicit "
949 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700950 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700951 << "\n\n";
952
Yifan Hong10fe0b52016-10-19 14:20:17 -0700953 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700954
Yifan Hong068c5522016-10-31 14:07:25 -0700955 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
956 method->generateCppSignature(out);
957 out << " override;\n";
958 return OK;
959 });
Steven Moreland9c387612016-09-07 09:54:26 -0700960
961 if (err != OK) {
962 return err;
963 }
Andreas Huber881227d2016-08-02 14:20:21 -0700964
965 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100966 out << "private:\n";
967 out.indent();
968 out << "std::mutex _hidl_mMutex;\n"
969 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
970 << " _hidl_mDeathRecipients;\n";
971 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700972 out << "};\n\n";
973
974 enterLeaveNamespace(out, false /* enter */);
975
976 out << "\n#endif // " << guard << "\n";
977
978 return OK;
979}
980
Andreas Huberb82318c2016-08-02 14:45:54 -0700981status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700982
Andreas Huberb82318c2016-08-02 14:45:54 -0700983 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700984 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700985 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700986
987 std::string ifaceName;
988 std::string baseName;
989
Yifan Hongfe95aa22016-10-19 17:26:45 -0700990 const Interface *iface = nullptr;
991 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700992 if (!AST::isInterface(&ifaceName)) {
993 baseName = "types";
994 isInterface = false;
995 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700996 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700997 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700998 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700999 }
1000
1001 path.append(baseName);
1002
1003 if (baseName != "types") {
1004 path.append("All");
1005 }
1006
1007 path.append(".cpp");
1008
Andreas Huberd2943e12016-08-05 11:59:31 -07001009 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -07001010 FILE *file = fopen(path.c_str(), "w");
1011
1012 if (file == NULL) {
1013 return -errno;
1014 }
1015
1016 Formatter out(file);
1017
Steven Moreland623c0042017-01-13 14:42:29 -08001018 out << "#define LOG_TAG \""
1019 << mPackage.string() << "::" << baseName
1020 << "\"\n\n";
1021
Steven Moreland05cd4232016-11-21 16:01:12 -08001022 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001023 out << "#include <cutils/trace.h>\n";
1024 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001025 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -07001026 // This is a no-op for IServiceManager itself.
1027 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
1028
Steven Morelandbec74ed2017-01-25 17:42:35 -08001029 // TODO(b/34274385) remove this
1030 out << "#include <hidl/LegacySupport.h>\n";
1031
Yifan Hongeefe4f22017-01-04 15:32:42 -08001032 generateCppPackageInclude(out, mPackage, iface->getProxyName());
1033 generateCppPackageInclude(out, mPackage, iface->getStubName());
1034 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001035
1036 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -07001037 generateCppPackageInclude(out,
1038 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -08001039 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001040 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -08001041
1042 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001043 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -07001044 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -08001045 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -07001046 }
1047
1048 out << "\n";
1049
1050 enterLeaveNamespace(out, true /* enter */);
1051 out << "\n";
1052
1053 status_t err = generateTypeSource(out, ifaceName);
1054
1055 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001056 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001057
1058 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -08001059 out << "const char* "
1060 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -07001061 << "::descriptor(\""
1062 << iface->fqName().string()
1063 << "\");\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +01001064 out << "__attribute__((constructor))";
1065 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001066 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001067 out << "::android::hardware::details::gBnConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001068 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001069 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001070 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001071 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001072 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001073 out << "return new "
1074 << iface->getStubName()
1075 << "(reinterpret_cast<"
1076 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001077 << " *>(iIntf));\n";
1078 });
Yifan Hongb04de382017-02-06 15:31:52 -08001079 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001080 });
Yifan Honga159f3b2017-03-16 14:53:51 -07001081 out << "::android::hardware::details::gBsConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001082 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001083 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001084 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001085 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -08001086 << gIBaseFqName.cppName()
1087 << "> {\n";
1088 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001089 out << "return new "
1090 << iface->getPassthroughName()
1091 << "(reinterpret_cast<"
1092 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001093 << " *>(iIntf));\n";
1094 });
Yifan Hongb04de382017-02-06 15:31:52 -08001095 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001096 });
Yifan Hong158655a2016-11-08 12:34:07 -08001097 });
Martijn Coenen8adcb652017-02-03 17:37:36 +01001098 out << "};\n\n";
1099 out << "__attribute__((destructor))";
1100 out << "static void static_destructor() {\n";
1101 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001102 out << "::android::hardware::details::gBnConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001103 << iface->localName()
1104 << "::descriptor);\n";
Yifan Honga159f3b2017-03-16 14:53:51 -07001105 out << "::android::hardware::details::gBsConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001106 << iface->localName()
1107 << "::descriptor);\n";
1108 });
1109 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001110
Yifan Hongfe95aa22016-10-19 17:26:45 -07001111 err = generateInterfaceSource(out);
1112 }
1113
1114 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001115 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001116 }
1117
1118 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001119 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001120 }
1121
Steven Moreland40786312016-08-16 10:29:40 -07001122 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001123 err = generatePassthroughSource(out);
1124 }
1125
1126 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001127 const Interface *iface = mRootScope->getInterface();
1128
Yifan Hongc8934042016-11-17 17:10:52 -08001129 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001130 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001131 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001132 std::string package = iface->fqName().package()
1133 + iface->fqName().atVersion();
1134
Yifan Hongeefe4f22017-01-04 15:32:42 -08001135 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001136 }
Steven Moreland40786312016-08-16 10:29:40 -07001137 }
1138
Andreas Huber881227d2016-08-02 14:20:21 -07001139 enterLeaveNamespace(out, false /* enter */);
1140
1141 return err;
1142}
1143
Steven Moreland67f67b42016-09-29 08:59:02 -07001144// static
1145void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001146 out.sIf(nonNull + " == nullptr", [&] {
1147 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1148 out.indent(2, [&] {
1149 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1150 });
1151 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001152}
1153
Andreas Huber881227d2016-08-02 14:20:21 -07001154status_t AST::generateTypeSource(
1155 Formatter &out, const std::string &ifaceName) const {
1156 return mRootScope->emitTypeDefinitions(out, ifaceName);
1157}
1158
Andreas Hubere7ff2282016-08-16 13:50:03 -07001159void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001160 Formatter &out,
1161 const std::vector<TypedVar *> &args,
1162 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001163 if (args.empty()) {
1164 return;
1165 }
1166
1167 for (const auto &arg : args) {
1168 const Type &type = arg->type();
1169
Yifan Hong3b320f82016-11-01 15:15:54 -07001170 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001171 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001172 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001173 << ";\n";
1174 }
1175
1176 out << "\n";
1177}
1178
Andreas Huber881227d2016-08-02 14:20:21 -07001179void AST::emitCppReaderWriter(
1180 Formatter &out,
1181 const std::string &parcelObj,
1182 bool parcelObjIsPointer,
1183 const TypedVar *arg,
1184 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001185 Type::ErrorMode mode,
1186 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001187 const Type &type = arg->type();
1188
Andreas Huber881227d2016-08-02 14:20:21 -07001189 type.emitReaderWriter(
1190 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001191 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001192 parcelObj,
1193 parcelObjIsPointer,
1194 isReader,
1195 mode);
1196}
1197
Yifan Hongbf459bc2016-08-23 16:50:37 -07001198void AST::emitCppResolveReferences(
1199 Formatter &out,
1200 const std::string &parcelObj,
1201 bool parcelObjIsPointer,
1202 const TypedVar *arg,
1203 bool isReader,
1204 Type::ErrorMode mode,
1205 bool addPrefixToName) const {
1206 const Type &type = arg->type();
1207 if(type.needsResolveReferences()) {
1208 type.emitResolveReferences(
1209 out,
1210 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1211 isReader, // nameIsPointer
1212 parcelObj,
1213 parcelObjIsPointer,
1214 isReader,
1215 mode);
1216 }
1217}
1218
Yifan Hong068c5522016-10-31 14:07:25 -07001219status_t AST::generateProxyMethodSource(Formatter &out,
1220 const std::string &klassName,
1221 const Method *method,
1222 const Interface *superInterface) const {
1223
1224 method->generateCppSignature(out,
1225 klassName,
1226 true /* specify namespaces */);
1227
1228 const bool returnsValue = !method->results().empty();
1229 const TypedVar *elidedReturn = method->canElideCallback();
1230
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001231 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001232
1233 out.indent();
1234
Martijn Coenen115d4282016-12-19 05:14:04 +01001235 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1236 method->cppImpl(IMPL_PROXY, out);
1237 out.unindent();
1238 out << "}\n\n";
1239 return OK;
1240 }
1241
Yifan Hong068c5522016-10-31 14:07:25 -07001242 if (returnsValue && elidedReturn == nullptr) {
1243 generateCheckNonNull(out, "_hidl_cb");
1244 }
1245
1246 status_t status = generateCppInstrumentationCall(
1247 out,
1248 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001249 method);
1250 if (status != OK) {
1251 return status;
1252 }
1253
1254 out << "::android::hardware::Parcel _hidl_data;\n";
1255 out << "::android::hardware::Parcel _hidl_reply;\n";
1256 out << "::android::status_t _hidl_err;\n";
1257 out << "::android::hardware::Status _hidl_status;\n\n";
1258
1259 declareCppReaderLocals(
1260 out, method->results(), true /* forResults */);
1261
1262 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001263 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001264 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001265 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1266
Martijn Coenenfff73352017-01-04 16:36:31 +01001267 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001268 // First DFS: write all buffers and resolve pointers for parent
1269 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001270 if (arg->type().isInterface()) {
1271 hasInterfaceArgument = true;
1272 }
Yifan Hong068c5522016-10-31 14:07:25 -07001273 emitCppReaderWriter(
1274 out,
1275 "_hidl_data",
1276 false /* parcelObjIsPointer */,
1277 arg,
1278 false /* reader */,
1279 Type::ErrorMode_Goto,
1280 false /* addPrefixToName */);
1281 }
1282
1283 // Second DFS: resolve references.
1284 for (const auto &arg : method->args()) {
1285 emitCppResolveReferences(
1286 out,
1287 "_hidl_data",
1288 false /* parcelObjIsPointer */,
1289 arg,
1290 false /* reader */,
1291 Type::ErrorMode_Goto,
1292 false /* addPrefixToName */);
1293 }
1294
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001295 if (hasInterfaceArgument) {
1296 // Start binder threadpool to handle incoming transactions
1297 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1298 }
Yifan Hong068c5522016-10-31 14:07:25 -07001299 out << "_hidl_err = remote()->transact("
1300 << method->getSerialId()
1301 << " /* "
1302 << method->name()
1303 << " */, _hidl_data, &_hidl_reply";
1304
1305 if (method->isOneway()) {
1306 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1307 }
1308 out << ");\n";
1309
1310 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1311
1312 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001313 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001314 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1315 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1316
1317
1318 // First DFS: write all buffers and resolve pointers for parent
1319 for (const auto &arg : method->results()) {
1320 emitCppReaderWriter(
1321 out,
1322 "_hidl_reply",
1323 false /* parcelObjIsPointer */,
1324 arg,
1325 true /* reader */,
1326 Type::ErrorMode_Goto,
1327 true /* addPrefixToName */);
1328 }
1329
1330 // Second DFS: resolve references.
1331 for (const auto &arg : method->results()) {
1332 emitCppResolveReferences(
1333 out,
1334 "_hidl_reply",
1335 false /* parcelObjIsPointer */,
1336 arg,
1337 true /* reader */,
1338 Type::ErrorMode_Goto,
1339 true /* addPrefixToName */);
1340 }
1341
1342 if (returnsValue && elidedReturn == nullptr) {
1343 out << "_hidl_cb(";
1344
Yifan Hong7d234ea2017-03-30 15:40:22 -07001345 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001346 if (arg->type().resultNeedsDeref()) {
1347 out << "*";
1348 }
1349 out << "_hidl_out_" << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001350 });
Yifan Hong068c5522016-10-31 14:07:25 -07001351
1352 out << ");\n\n";
1353 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001354 }
1355 status = generateCppInstrumentationCall(
1356 out,
1357 InstrumentationEvent::CLIENT_API_EXIT,
1358 method);
1359 if (status != OK) {
1360 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001361 }
1362
1363 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001364 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1365 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001366 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001367 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1368 } else {
1369 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1370 out << "return ::android::hardware::Return<void>();\n\n";
1371 }
1372
1373 out.unindent();
1374 out << "_hidl_error:\n";
1375 out.indent();
1376 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1377 out << "return ::android::hardware::Return<";
1378 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001379 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001380 } else {
1381 out << "void";
1382 }
1383 out << ">(_hidl_status);\n";
1384
1385 out.unindent();
1386 out << "}\n\n";
1387 return OK;
1388}
1389
Andreas Huber881227d2016-08-02 14:20:21 -07001390status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001391 Formatter &out, const FQName &fqName) const {
1392 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001393
1394 out << klassName
1395 << "::"
1396 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001397 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001398
1399 out.indent();
1400 out.indent();
1401
1402 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001403 << "<"
1404 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001405 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001406 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001407 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001408 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001409 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001410 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001411
Andreas Huber881227d2016-08-02 14:20:21 -07001412 out.unindent();
1413 out.unindent();
1414 out << "}\n\n";
1415
Yifan Hong068c5522016-10-31 14:07:25 -07001416 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1417 return generateProxyMethodSource(out, klassName, method, superInterface);
1418 });
Andreas Huber881227d2016-08-02 14:20:21 -07001419
Yifan Hong068c5522016-10-31 14:07:25 -07001420 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001421}
1422
1423status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001424 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001425 const Interface *iface) const {
1426 const std::string interfaceName = iface->localName();
1427 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001428
Steven Moreland40786312016-08-16 10:29:40 -07001429 out << klassName
1430 << "::"
1431 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001432 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001433
1434 out.indent();
1435 out.indent();
1436
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001437 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001438 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001439 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001440 out << ": "
1441 << gIBaseFqName.getInterfaceStubFqName().cppName()
1442 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001443 }
1444
1445 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001446 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001447 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001448 << "\") { \n";
1449 out.indent();
1450 out << "_hidl_mImpl = _hidl_impl;\n";
1451 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001452
1453 out.unindent();
1454 out.unindent();
1455 out << "}\n\n";
1456
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001457 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001458 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001459 // class properly.
1460 out << klassName
1461 << "::"
1462 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001463 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1464 << " const std::string &HidlInstrumentor_package,"
1465 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001466
1467 out.indent();
1468 out.indent();
1469
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001470 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001471 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001472 out.indent();
1473 out << "_hidl_mImpl = _hidl_impl;\n";
1474 out.unindent();
1475
1476 out.unindent();
1477 out.unindent();
1478 out << "}\n\n";
1479 }
1480
Yifan Hongbcffce22017-02-01 15:52:06 -08001481 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1482 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1483 return OK;
1484 }
1485 method->generateCppSignature(out, iface->getStubName());
1486 out << " ";
1487 out.block([&] {
1488 method->cppImpl(IMPL_STUB_IMPL, out);
1489 }).endl();
1490 return OK;
1491 });
Steven Moreland60818632017-02-04 00:33:42 -08001492 if (err != OK) {
1493 return err;
1494 }
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001495
Andreas Huber881227d2016-08-02 14:20:21 -07001496 out << "::android::status_t " << klassName << "::onTransact(\n";
1497
1498 out.indent();
1499 out.indent();
1500
Iliyan Malchev549e2592016-08-10 08:59:12 -07001501 out << "uint32_t _hidl_code,\n"
1502 << "const ::android::hardware::Parcel &_hidl_data,\n"
1503 << "::android::hardware::Parcel *_hidl_reply,\n"
1504 << "uint32_t _hidl_flags,\n"
1505 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001506
1507 out.unindent();
1508
Iliyan Malchev549e2592016-08-10 08:59:12 -07001509 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001510 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001511 out.indent();
1512
Yifan Hong10fe0b52016-10-19 14:20:17 -07001513 for (const auto &tuple : iface->allMethodsFromRoot()) {
1514 const Method *method = tuple.method();
1515 const Interface *superInterface = tuple.interface();
1516 out << "case "
1517 << method->getSerialId()
1518 << " /* "
1519 << method->name()
1520 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001521
Yifan Hong10fe0b52016-10-19 14:20:17 -07001522 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001523
Yifan Hong10fe0b52016-10-19 14:20:17 -07001524 status_t err =
1525 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001526
Yifan Hong10fe0b52016-10-19 14:20:17 -07001527 if (err != OK) {
1528 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001529 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001530
1531 out.unindent();
1532 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001533 }
1534
1535 out << "default:\n{\n";
1536 out.indent();
1537
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001538 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001539
1540 out.indent();
1541 out.indent();
1542
Iliyan Malchev549e2592016-08-10 08:59:12 -07001543 out << "_hidl_code, _hidl_data, _hidl_reply, "
1544 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001545
1546 out.unindent();
1547 out.unindent();
1548
1549 out.unindent();
1550 out << "}\n";
1551
1552 out.unindent();
1553 out << "}\n\n";
1554
Yifan Honga018ed52016-12-13 16:35:08 -08001555 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1556 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1557 out.indent(2, [&] {
1558 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1559 out << "_hidl_reply);\n";
1560 });
1561 });
Andreas Huber881227d2016-08-02 14:20:21 -07001562
Iliyan Malchev549e2592016-08-10 08:59:12 -07001563 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001564
1565 out.unindent();
1566 out << "}\n\n";
1567
1568 return OK;
1569}
1570
1571status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001572 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001573 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1574 method->cppImpl(IMPL_STUB, out);
1575 out << "break;\n";
1576 return OK;
1577 }
1578
Yifan Hongeefe4f22017-01-04 15:32:42 -08001579 out << "if (!_hidl_data.enforceInterface("
1580 << iface->fullName()
1581 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001582
Andreas Huber881227d2016-08-02 14:20:21 -07001583 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001584 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001585 out << "break;\n";
1586 out.unindent();
1587 out << "}\n\n";
1588
Andreas Huber5e44a292016-09-27 14:52:39 -07001589 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001590
Yifan Hongbf459bc2016-08-23 16:50:37 -07001591 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001592 for (const auto &arg : method->args()) {
1593 emitCppReaderWriter(
1594 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001595 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001596 false /* parcelObjIsPointer */,
1597 arg,
1598 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001599 Type::ErrorMode_Break,
1600 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001601 }
1602
Yifan Hongbf459bc2016-08-23 16:50:37 -07001603 // Second DFS: resolve references
1604 for (const auto &arg : method->args()) {
1605 emitCppResolveReferences(
1606 out,
1607 "_hidl_data",
1608 false /* parcelObjIsPointer */,
1609 arg,
1610 true /* reader */,
1611 Type::ErrorMode_Break,
1612 false /* addPrefixToName */);
1613 }
1614
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001615 status_t status = generateCppInstrumentationCall(
1616 out,
1617 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001618 method);
1619 if (status != OK) {
1620 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001621 }
1622
Andreas Huber881227d2016-08-02 14:20:21 -07001623 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001624 const TypedVar *elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -08001625 const std::string callee =
1626 (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL))
1627 ? "this" : "_hidl_mImpl";
Andreas Huber881227d2016-08-02 14:20:21 -07001628
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001629 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001630 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001631 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001632 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001633 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001634 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001635 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001636
Yifan Hong7d234ea2017-03-30 15:40:22 -07001637 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001638 if (arg->type().resultNeedsDeref()) {
1639 out << "*";
1640 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001641 out << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001642 });
Andreas Huber881227d2016-08-02 14:20:21 -07001643
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001644 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001645 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1646 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001647
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001648 elidedReturn->type().emitReaderWriter(
1649 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001650 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001651 "_hidl_reply",
1652 true, /* parcelObjIsPointer */
1653 false, /* isReader */
1654 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001655
Yifan Hongbf459bc2016-08-23 16:50:37 -07001656 emitCppResolveReferences(
1657 out,
1658 "_hidl_reply",
1659 true /* parcelObjIsPointer */,
1660 elidedReturn,
1661 false /* reader */,
1662 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001663 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001664
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001665 status_t status = generateCppInstrumentationCall(
1666 out,
1667 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001668 method);
1669 if (status != OK) {
1670 return status;
1671 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001672
Iliyan Malchev549e2592016-08-10 08:59:12 -07001673 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001674 } else {
1675 if (returnsValue) {
1676 out << "bool _hidl_callbackCalled = false;\n\n";
1677 }
Andreas Huber881227d2016-08-02 14:20:21 -07001678
Yifan Hongcd2ae452017-01-31 14:33:40 -08001679 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001680
Yifan Hong7d234ea2017-03-30 15:40:22 -07001681 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001682 if (arg->type().resultNeedsDeref()) {
1683 out << "*";
1684 }
1685
1686 out << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001687 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001688
1689 if (returnsValue) {
Yifan Hong7d234ea2017-03-30 15:40:22 -07001690 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001691 out << ", ";
1692 }
1693
1694 out << "[&](";
1695
Yifan Hong7d234ea2017-03-30 15:40:22 -07001696 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001697 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong7d234ea2017-03-30 15:40:22 -07001698 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001699
1700 out << ") {\n";
1701 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001702 out << "if (_hidl_callbackCalled) {\n";
1703 out.indent();
1704 out << "LOG_ALWAYS_FATAL(\""
1705 << method->name()
1706 << ": _hidl_cb called a second time, but must be called once.\");\n";
1707 out.unindent();
1708 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001709 out << "_hidl_callbackCalled = true;\n\n";
1710
Yifan Hong859e53f2016-11-14 19:08:24 -08001711 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1712 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001713
Yifan Hongbf459bc2016-08-23 16:50:37 -07001714 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001715 for (const auto &arg : method->results()) {
1716 emitCppReaderWriter(
1717 out,
1718 "_hidl_reply",
1719 true /* parcelObjIsPointer */,
1720 arg,
1721 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001722 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001723 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001724 }
1725
Yifan Hongbf459bc2016-08-23 16:50:37 -07001726 // Second DFS: resolve references
1727 for (const auto &arg : method->results()) {
1728 emitCppResolveReferences(
1729 out,
1730 "_hidl_reply",
1731 true /* parcelObjIsPointer */,
1732 arg,
1733 false /* reader */,
1734 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001735 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001736 }
1737
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001738 status_t status = generateCppInstrumentationCall(
1739 out,
1740 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001741 method);
1742 if (status != OK) {
1743 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001744 }
1745
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001746 out << "_hidl_cb(*_hidl_reply);\n";
1747
1748 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001749 out << "});\n\n";
1750 } else {
1751 out << ");\n\n";
1752 status_t status = generateCppInstrumentationCall(
1753 out,
1754 InstrumentationEvent::SERVER_API_EXIT,
1755 method);
1756 if (status != OK) {
1757 return status;
1758 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001759 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001760
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001761 if (returnsValue) {
1762 out << "if (!_hidl_callbackCalled) {\n";
1763 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001764 out << "LOG_ALWAYS_FATAL(\""
1765 << method->name()
1766 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001767 out.unindent();
1768 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001769 } else {
1770 out << "::android::hardware::writeToParcel("
1771 << "::android::hardware::Status::ok(), "
1772 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001773 }
Andreas Huber881227d2016-08-02 14:20:21 -07001774 }
1775
1776 out << "break;\n";
1777
1778 return OK;
1779}
1780
Steven Moreland69e7c702016-09-09 11:16:32 -07001781status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1782 std::string ifaceName;
1783 if (!AST::isInterface(&ifaceName)) {
1784 // types.hal does not get a stub header.
1785 return OK;
1786 }
1787
1788 const Interface *iface = mRootScope->getInterface();
1789
Yifan Hongeefe4f22017-01-04 15:32:42 -08001790 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001791
1792 bool supportOneway = iface->hasOnewayMethods();
1793
1794 std::string path = outputPath;
1795 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1796 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1797 path.append(klassName);
1798 path.append(".h");
1799
1800 CHECK(Coordinator::MakeParentHierarchy(path));
1801 FILE *file = fopen(path.c_str(), "w");
1802
1803 if (file == NULL) {
1804 return -errno;
1805 }
1806
1807 Formatter out(file);
1808
1809 const std::string guard = makeHeaderGuard(klassName);
1810
1811 out << "#ifndef " << guard << "\n";
1812 out << "#define " << guard << "\n\n";
1813
1814 std::vector<std::string> packageComponents;
1815 getPackageAndVersionComponents(
1816 &packageComponents, false /* cpp_compatible */);
1817
Yifan Hongb0949432016-12-15 15:32:24 -08001818 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001819 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001820
1821 generateCppPackageInclude(out, mPackage, ifaceName);
1822 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001823
Yifan Hong7a118f52016-12-07 11:21:15 -08001824 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001825 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001826 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001827 }
1828
1829 enterLeaveNamespace(out, true /* enter */);
1830 out << "\n";
1831
1832 out << "struct "
1833 << klassName
1834 << " : " << ifaceName
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001835 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001836
1837 out.indent();
1838 out << "explicit "
1839 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001840 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001841 << ifaceName
1842 << "> impl);\n";
1843
Yifan Hong068c5522016-10-31 14:07:25 -07001844 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1845 return generatePassthroughMethod(out, method);
1846 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001847
1848 if (err != OK) {
1849 return err;
1850 }
1851
1852 out.unindent();
1853 out << "private:\n";
1854 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001855 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001856
1857 if (supportOneway) {
Yifan Hongef91d362017-03-20 17:18:13 -07001858 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001859
1860 out << "\n";
1861
1862 out << "::android::hardware::Return<void> addOnewayTask("
1863 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001864 }
1865
1866 out.unindent();
1867
1868 out << "};\n\n";
1869
1870 enterLeaveNamespace(out, false /* enter */);
1871
1872 out << "\n#endif // " << guard << "\n";
1873
1874 return OK;
1875}
1876
Yifan Hongfe95aa22016-10-19 17:26:45 -07001877status_t AST::generateInterfaceSource(Formatter &out) const {
1878 const Interface *iface = mRootScope->getInterface();
1879
Yifan Hong2d7126b2016-10-20 15:12:57 -07001880 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001881 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001882
Steven Morelandd4b068a2017-03-20 06:30:51 -07001883 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1884 bool reserved = method->isHidlReserved();
1885
1886 if (!reserved) {
1887 out << "// no default implementation for: ";
1888 }
1889 method->generateCppSignature(out, iface->localName());
1890 if (reserved) {
1891 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001892 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001893 }).endl();
1894 }
1895
1896 out << "\n";
1897
1898 return OK;
1899 });
1900 if (err != OK) {
1901 return err;
1902 }
1903
Yifan Hong3d746092016-12-07 14:26:33 -08001904 for (const Interface *superType : iface->typeChain()) {
Yifan Hong7783bb02017-03-29 03:39:09 -07001905 out << "// static \n::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -08001906 << childTypeResult
Yifan Hong7783bb02017-03-29 03:39:09 -07001907 << "> "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001908 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001909 << "::castFrom("
1910 << superType->getCppArgumentType()
Yifan Hong7783bb02017-03-29 03:39:09 -07001911 << " parent, bool "
1912 << (iface == superType ? "/* emitError */" : "emitError")
1913 << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001914 out.indent();
1915 if (iface == superType) {
1916 out << "return parent;\n";
1917 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001918 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001919 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001920 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001921 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001922 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001923 << ">(\n";
1924 out.indent();
1925 out.indent();
1926 out << "parent, \""
1927 << iface->fqName().string()
Yifan Hong7783bb02017-03-29 03:39:09 -07001928 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001929 out.unindent();
1930 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001931 }
Yifan Hong3d746092016-12-07 14:26:33 -08001932 out.unindent();
1933 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001934 }
1935
1936 return OK;
1937}
1938
Steven Moreland69e7c702016-09-09 11:16:32 -07001939status_t AST::generatePassthroughSource(Formatter &out) const {
1940 const Interface *iface = mRootScope->getInterface();
1941
Yifan Hongeefe4f22017-01-04 15:32:42 -08001942 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001943
1944 out << klassName
1945 << "::"
1946 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001947 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001948 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001949 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001950 << mPackage.string()
1951 << "\", \""
1952 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001953 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001954 if (iface->hasOnewayMethods()) {
1955 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001956 out.indent([&] {
Yifan Hongf01dad42017-03-20 19:03:11 -07001957 out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001958 });
1959 }
1960 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001961
1962 if (iface->hasOnewayMethods()) {
1963 out << "::android::hardware::Return<void> "
1964 << klassName
1965 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1966 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001967 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001968 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001969 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1970 out.indent();
1971 out.indent();
1972 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1973 out.unindent();
1974 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001975 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001976 out << "}\n";
1977
Steven Morelandd366c262016-10-11 15:29:10 -07001978 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001979
1980 out.unindent();
1981 out << "}\n\n";
1982
1983
1984 }
1985
1986 return OK;
1987}
1988
Martijn Coenen7b295242016-11-04 16:52:56 +01001989status_t AST::generateCppAtraceCall(Formatter &out,
1990 InstrumentationEvent event,
1991 const Method *method) const {
1992 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001993 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001994 switch (event) {
1995 case SERVER_API_ENTRY:
1996 {
1997 out << "atrace_begin(ATRACE_TAG_HAL, \""
1998 << baseString + "::server\");\n";
1999 break;
2000 }
2001 case CLIENT_API_ENTRY:
2002 {
2003 out << "atrace_begin(ATRACE_TAG_HAL, \""
2004 << baseString + "::client\");\n";
2005 break;
2006 }
2007 case PASSTHROUGH_ENTRY:
2008 {
2009 out << "atrace_begin(ATRACE_TAG_HAL, \""
2010 << baseString + "::passthrough\");\n";
2011 break;
2012 }
2013 case SERVER_API_EXIT:
2014 case CLIENT_API_EXIT:
2015 case PASSTHROUGH_EXIT:
2016 {
2017 out << "atrace_end(ATRACE_TAG_HAL);\n";
2018 break;
2019 }
2020 default:
2021 {
2022 LOG(ERROR) << "Unsupported instrumentation event: " << event;
2023 return UNKNOWN_ERROR;
2024 }
2025 }
2026
2027 return OK;
2028}
2029
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002030status_t AST::generateCppInstrumentationCall(
2031 Formatter &out,
2032 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07002033 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01002034 status_t err = generateCppAtraceCall(out, event, method);
2035 if (err != OK) {
2036 return err;
2037 }
2038
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002039 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
2040 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002041 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002042 std::string event_str = "";
2043 switch (event) {
2044 case SERVER_API_ENTRY:
2045 {
2046 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
2047 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002048 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002049 << (arg->type().resultNeedsDeref() ? "" : "&")
2050 << arg->name()
2051 << ");\n";
2052 }
2053 break;
2054 }
2055 case SERVER_API_EXIT:
2056 {
2057 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07002058 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002059 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07002060 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002061 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002062 }
2063 break;
2064 }
2065 case CLIENT_API_ENTRY:
2066 {
2067 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2068 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002069 out << "_hidl_args.push_back((void *)&"
2070 << arg->name()
2071 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002072 }
2073 break;
2074 }
2075 case CLIENT_API_EXIT:
2076 {
2077 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2078 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002079 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002080 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002081 << "_hidl_out_"
2082 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002083 << ");\n";
2084 }
2085 break;
2086 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002087 case PASSTHROUGH_ENTRY:
2088 {
2089 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2090 for (const auto &arg : method->args()) {
2091 out << "_hidl_args.push_back((void *)&"
2092 << arg->name()
2093 << ");\n";
2094 }
2095 break;
2096 }
2097 case PASSTHROUGH_EXIT:
2098 {
2099 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002100 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002101 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002102 << arg->name()
2103 << ");\n";
2104 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002105 break;
2106 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002107 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002108 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002109 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002110 return UNKNOWN_ERROR;
2111 }
2112 }
2113
Steven Moreland031ccf12016-10-31 15:54:38 -07002114 const Interface *iface = mRootScope->getInterface();
2115
Steven Moreland1ab31442016-11-03 18:37:51 -07002116 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002117 out.indent();
2118 out << "callback("
2119 << event_str
2120 << ", \""
2121 << mPackage.package()
2122 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002123 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002124 << "\", \""
2125 << iface->localName()
2126 << "\", \""
2127 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002128 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002129 out.unindent();
2130 out << "}\n";
2131 out.unindent();
2132 out << "}\n\n";
2133
2134 return OK;
2135}
2136
Andreas Huber881227d2016-08-02 14:20:21 -07002137} // namespace android