blob: 04033a71ec296d9d968362de5fa152a547fe1445 [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Huber881227d2016-08-02 14:20:21 -070017#include "AST.h"
18
19#include "Coordinator.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070020#include "EnumType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070021#include "Interface.h"
Andreas Huber6755e9d2017-04-06 11:09:07 -070022#include "HidlTypeAssertion.h"
Andreas Huber881227d2016-08-02 14:20:21 -070023#include "Method.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070024#include "ScalarType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070025#include "Scope.h"
26
Andreas Huberdca261f2016-08-04 13:47:51 -070027#include <algorithm>
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070028#include <hidl-util/Formatter.h>
Steven Moreland5708edf2016-11-04 15:33:31 +000029#include <hidl-util/StringHelper.h>
Andreas Huber881227d2016-08-02 14:20:21 -070030#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070031#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070032#include <vector>
33
34namespace android {
35
Andreas Huberb82318c2016-08-02 14:45:54 -070036status_t AST::generateCpp(const std::string &outputPath) const {
Steven Moreland1cbf0362017-05-09 14:32:53 -070037 status_t err = generateCppHeaders(outputPath);
38
39 if (err == OK) {
40 err = generateCppSources(outputPath);
41 }
42
43 return err;
44}
45
46status_t AST::generateCppHeaders(const std::string &outputPath) const {
Andreas Huberb82318c2016-08-02 14:45:54 -070047 status_t err = generateInterfaceHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070048
49 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070050 err = generateStubHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070051 }
52
53 if (err == OK) {
Steven Moreland40786312016-08-16 10:29:40 -070054 err = generateHwBinderHeader(outputPath);
55 }
56
57 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070058 err = generateProxyHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070059 }
60
61 if (err == OK) {
Yifan Hong7a118f52016-12-07 11:21:15 -080062 err = generatePassthroughHeader(outputPath);
Steven Moreland69e7c702016-09-09 11:16:32 -070063 }
64
Andreas Huber881227d2016-08-02 14:20:21 -070065 return err;
66}
67
Andreas Huber737080b2016-08-02 15:38:04 -070068void AST::getPackageComponents(
69 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070070 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070071}
72
73void AST::getPackageAndVersionComponents(
74 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070075 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070076}
77
Steven Moreland5708edf2016-11-04 15:33:31 +000078std::string AST::makeHeaderGuard(const std::string &baseName,
79 bool indicateGenerated) const {
80 std::string guard;
Andreas Huber881227d2016-08-02 14:20:21 -070081
Steven Moreland5708edf2016-11-04 15:33:31 +000082 if (indicateGenerated) {
83 guard += "HIDL_GENERATED_";
84 }
85
86 guard += StringHelper::Uppercase(mPackage.tokenName());
Andreas Huber881227d2016-08-02 14:20:21 -070087 guard += "_";
Steven Moreland5708edf2016-11-04 15:33:31 +000088 guard += StringHelper::Uppercase(baseName);
89 guard += "_H";
Andreas Huber881227d2016-08-02 14:20:21 -070090
91 return guard;
92}
93
Steven Morelandee88eed2016-10-31 17:49:00 -070094void AST::generateCppPackageInclude(
95 Formatter &out,
96 const FQName &package,
97 const std::string &klass) {
98
99 out << "#include <";
100
101 std::vector<std::string> components;
102 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
103
104 for (const auto &component : components) {
105 out << component << "/";
106 }
107
108 out << klass
109 << ".h>\n";
110}
111
Andreas Huber881227d2016-08-02 14:20:21 -0700112void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
113 std::vector<std::string> packageComponents;
114 getPackageAndVersionComponents(
115 &packageComponents, true /* cpp_compatible */);
116
117 if (enter) {
118 for (const auto &component : packageComponents) {
119 out << "namespace " << component << " {\n";
120 }
Andreas Huber0e00de42016-08-03 09:56:02 -0700121
Andreas Huber2831d512016-08-15 09:33:47 -0700122 out.setNamespace(mPackage.cppNamespace() + "::");
Andreas Huber881227d2016-08-02 14:20:21 -0700123 } else {
Andreas Huber0e00de42016-08-03 09:56:02 -0700124 out.setNamespace(std::string());
125
Andreas Huber881227d2016-08-02 14:20:21 -0700126 for (auto it = packageComponents.rbegin();
127 it != packageComponents.rend();
128 ++it) {
129 out << "} // namespace " << *it << "\n";
130 }
131 }
132}
133
Steven Moreland038903b2017-03-30 12:11:24 -0700134static void declareGetService(Formatter &out, const std::string &interfaceName, bool isTry) {
135 const std::string functionName = isTry ? "tryGetService" : "getService";
136
137 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800138 << "const std::string &serviceName=\"default\", bool getStub=false);\n";
Steven Moreland038903b2017-03-30 12:11:24 -0700139 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800140 << "const char serviceName[], bool getStub=false)"
141 << " { std::string str(serviceName ? serviceName : \"\");"
Steven Moreland038903b2017-03-30 12:11:24 -0700142 << " return " << functionName << "(str, getStub); }\n";
143 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800144 << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
145 // without c_str the std::string constructor is ambiguous
146 << " { std::string str(serviceName.c_str());"
Steven Moreland038903b2017-03-30 12:11:24 -0700147 << " return " << functionName << "(str, getStub); }\n";
148 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
149 << "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
150}
151
152static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
153 declareGetService(out, interfaceName, true /* isTry */);
154 declareGetService(out, interfaceName, false /* isTry */);
155
Steven Moreland90831502017-03-27 12:08:40 -0700156 out << "__attribute__ ((warn_unused_result))"
157 << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800158 out << "static bool registerForNotifications(\n";
159 out.indent(2, [&] {
160 out << "const std::string &serviceName,\n"
161 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
162 << "&notification);\n";
163 });
164
165}
166
Steven Moreland038903b2017-03-30 12:11:24 -0700167static void implementGetService(Formatter &out,
168 const FQName &fqName,
169 bool isTry) {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800170
171 const std::string interfaceName = fqName.getInterfaceName();
Steven Moreland038903b2017-03-30 12:11:24 -0700172 const std::string functionName = isTry ? "tryGetService" : "getService";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800173
174 out << "// static\n"
Steven Moreland038903b2017-03-30 12:11:24 -0700175 << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
Yifan Hong31f07ff2017-03-21 18:56:35 +0000176 << "const std::string &serviceName, const bool getStub) ";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800177 out.block([&] {
Steven Morelandbcf51802017-04-06 09:17:44 -0700178 out << "using ::android::hardware::defaultServiceManager;\n";
179 out << "using ::android::hardware::details::waitForHwService;\n";
180 out << "using ::android::hardware::getPassthroughServiceManager;\n";
181 out << "using ::android::hardware::Return;\n";
182 out << "using ::android::sp;\n";
183 out << "using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;\n\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000184
Steven Morelandbcf51802017-04-06 09:17:44 -0700185 out << "sp<" << interfaceName << "> iface = nullptr;\n";
186
187 out.endl();
188
189 out << "const sp<::android::hidl::manager::V1_0::IServiceManager> sm"
190 << " = defaultServiceManager();\n";
191
192 out.sIf("sm == nullptr", [&] {
193 // hwbinder is not available on this device, so future tries
194 // would also be null. I can only return nullptr.
195 out << "ALOGE(\"getService: defaultServiceManager() is null\");\n"
196 << "return nullptr;\n";
197 }).endl().endl();
198
199 out << "Return<Transport> transportRet = sm->getTransport("
200 << interfaceName << "::descriptor, serviceName);\n\n";
201
202 out.sIf("!transportRet.isOk()", [&] {
203 out << "ALOGE(\"getService: defaultServiceManager()->getTransport returns %s\", "
204 << "transportRet.description().c_str());\n";
205 out << "return nullptr;\n";
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700206 }).endl();
Steven Morelandbcf51802017-04-06 09:17:44 -0700207
208 out << "Transport transport = transportRet;\n";
209 out << "const bool vintfHwbinder = (transport == Transport::HWBINDER);\n"
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700210 << "const bool vintfPassthru = (transport == Transport::PASSTHROUGH);\n\n";
211
212 // This means that you must set TREBLE_TESTING_OVERRIDE when running a test such
213 // as hidl_test. Ideally these binaries set this value themselves. This allows
214 // test modules to dynamically add and unset services even though they are not
215 // declared in the device manifest. This prevents a problem where framework
216 // changes are accidentally made in a way that is not backwards compatible. For
217 // instance, consider the following situation for two devices developed in the
218 // same tree:
219 // A: serves @1.1::IFoo, declares @1.0::IFoo (incorrect)
220 // B: serves @1.0::IFoo, declares @1.0::IFoo (correct configuration)
221 // If development is done on device A, then framework code like: "V1_1::IFoo::
222 // getService()->doV1_0Api()" will work. However, this will unintentionally break
223 // the feature for devices like device B for which "V1_1::IFoo::getService()
224 // will return nullptr. In order to prevent problems like this, we only allow
225 // fetching an interface if it is declared in a VINTF manifest.
226 out << "#ifdef __ANDROID_TREBLE__\n\n"
227 << "#ifdef __ANDROID_DEBUGGABLE__\n"
228 << "const char* env = std::getenv(\"TREBLE_TESTING_OVERRIDE\");\n"
229 << "const bool vintfLegacy = (transport == Transport::EMPTY) && env && !strcmp(env, \"true\");\n"
230 << "#else // __ANDROID_TREBLE__ but not __ANDROID_DEBUGGABLE__\n"
231 << "const bool vintfLegacy = false;\n"
232 << "#endif // __ANDROID_DEBUGGABLE__\n\n"
233 << "#else // not __ANDROID_TREBLE__\n"
234 << "const bool vintfLegacy = (transport == Transport::EMPTY);\n\n"
235 << "#endif // __ANDROID_TREBLE__\n\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000236
237 // if (getStub) {
238 // getPassthroughServiceManager()->get only once.
239 // } else {
240 // if (vintfHwbinder) {
241 // while (no alive service) {
242 // waitForHwService
243 // defaultServiceManager()->get
244 // }
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700245 // } else if (vintfLegacy) {
Yifan Hong31f07ff2017-03-21 18:56:35 +0000246 // defaultServiceManager()->get only once.
247 // getPassthroughServiceManager()->get only once.
248 // } else if (vintfPassthru) {
249 // getPassthroughServiceManager()->get only once.
250 // }
251 // }
252
Yifan Hong223fd472017-03-23 17:17:57 +0000253 out << "bool tried = false;\n";
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700254 out.sWhile("!getStub && (vintfHwbinder || (vintfLegacy && !tried))", [&] {
Yifan Hong31f07ff2017-03-21 18:56:35 +0000255
256 out.sIf("tried", [&] {
257 // sleep only after the first trial.
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700258 out << "ALOGI(\"" << functionName << ": retrying in 1s...\");\n"
Yifan Hong31f07ff2017-03-21 18:56:35 +0000259 << "sleep(1);\n";
260 }).endl();
261
Yifan Hong223fd472017-03-23 17:17:57 +0000262 out << "tried = true;\n";
263
Yifan Hong31f07ff2017-03-21 18:56:35 +0000264
Steven Moreland038903b2017-03-30 12:11:24 -0700265 if (!isTry) {
266 out.sIf("vintfHwbinder", [&] {
Steven Morelandbcf51802017-04-06 09:17:44 -0700267 out << "waitForHwService("
268 << interfaceName << "::descriptor, serviceName);\n";
Steven Moreland038903b2017-03-30 12:11:24 -0700269 }).endl();
270 }
Yifan Hong31f07ff2017-03-21 18:56:35 +0000271
Steven Morelandbcf51802017-04-06 09:17:44 -0700272 out << "Return<sp<" << gIBaseFqName.cppName() << ">> ret = \n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000273 out.indent(2, [&] {
274 out << "sm->get(" << interfaceName << "::descriptor, serviceName);\n";
275 });
276
277 out.sIf("!ret.isOk()", [&] {
Steven Moreland42394ce2017-03-27 17:03:04 -0700278 // hwservicemanager fails, may be security issue
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700279 out << "ALOGE(\"" << interfaceName << ": defaultServiceManager()->get returns %s\", "
Yifan Hong31f07ff2017-03-21 18:56:35 +0000280 << "ret.description().c_str());\n"
Steven Moreland42394ce2017-03-27 17:03:04 -0700281 << "break;\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000282 }).endl();
283
Steven Morelandbcf51802017-04-06 09:17:44 -0700284 out << "sp<" << gIBaseFqName.cppName() << "> base = ret;\n";
Yifan Hong200209c2017-03-29 03:39:09 -0700285 out.sIf("base == nullptr", [&] {
286 // race condition. hwservicemanager drops the service
287 // from waitForHwService to here
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700288 out << "ALOGW(\"" << interfaceName << ": found null hwbinder interface\");\n"
Yifan Hong9c74a5b2017-04-04 13:27:25 -0700289 << (isTry ? "break" : "continue")
290 << ";\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000291 }).endl();
Steven Morelandbcf51802017-04-06 09:17:44 -0700292 out << "Return<sp<" << interfaceName
Yifan Hong200209c2017-03-29 03:39:09 -0700293 << ">> castRet = " << interfaceName << "::castFrom(base, true /* emitError */);\n";
294 out.sIf("!castRet.isOk()", [&] {
295 out.sIf("castRet.isDeadObject()", [&] {
296 // service is dead (castFrom cannot call interfaceChain)
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700297 out << "ALOGW(\"" << interfaceName << ": found dead hwbinder service\");\n"
Yifan Hong9c74a5b2017-04-04 13:27:25 -0700298 << (isTry ? "break" : "continue")
299 << ";\n";
Yifan Hong200209c2017-03-29 03:39:09 -0700300 }).sElse([&] {
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700301 out << "ALOGW(\"" << interfaceName << ": cannot call into hwbinder service: %s"
Yifan Hong200209c2017-03-29 03:39:09 -0700302 << "; No permission? Check for selinux denials.\", "
303 << "castRet.description().c_str());\n"
304 << "break;\n";
305 }).endl();
306 }).endl();
307 out << "iface = castRet;\n";
308 out.sIf("iface == nullptr", [&] {
309 // returned service isn't of correct type; this is a bug
310 // to hwservicemanager or to the service itself (interfaceChain
311 // is not consistent).
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700312 out << "ALOGW(\"" << interfaceName << ": received incompatible service; bug in hwservicemanager?\");\n"
Yifan Hong200209c2017-03-29 03:39:09 -0700313 << "break;\n";
314 }).endl();
Yifan Hong31f07ff2017-03-21 18:56:35 +0000315
316 out << "return iface;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800317 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800318
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700319 out.sIf("getStub || vintfPassthru || vintfLegacy", [&] {
Steven Morelandbcf51802017-04-06 09:17:44 -0700320 out << "const sp<::android::hidl::manager::V1_0::IServiceManager> pm"
321 << " = getPassthroughServiceManager();\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000322
323 out.sIf("pm != nullptr", [&] () {
Steven Morelandbcf51802017-04-06 09:17:44 -0700324 out << "Return<sp<" << gIBaseFqName.cppName() << ">> ret = \n";
Steven Morelandf10af872017-01-25 16:01:56 +0000325 out.indent(2, [&] {
326 out << "pm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
Steven Moreland2c2dea82017-01-18 17:24:17 -0800327 });
Steven Morelandf10af872017-01-25 16:01:56 +0000328 out.sIf("ret.isOk()", [&] {
Steven Morelandbcf51802017-04-06 09:17:44 -0700329 out << "sp<" << gIBaseFqName.cppName()
Steven Morelandf10af872017-01-25 16:01:56 +0000330 << "> baseInterface = ret;\n";
331 out.sIf("baseInterface != nullptr", [&]() {
332 out << "iface = new " << fqName.getInterfacePassthroughName()
333 << "(" << interfaceName << "::castFrom(baseInterface));\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000334 }).endl();
Steven Morelandf10af872017-01-25 16:01:56 +0000335 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800336 }).endl();
337 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800338
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800339 out << "return iface;\n";
340 }).endl().endl();
Steven Moreland038903b2017-03-30 12:11:24 -0700341}
342
343static void implementServiceManagerInteractions(Formatter &out,
344 const FQName &fqName, const std::string &package) {
345
346 const std::string interfaceName = fqName.getInterfaceName();
347
348 implementGetService(out, fqName, true /* isTry */);
349 implementGetService(out, fqName, false /* isTry */);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800350
Yifan Hongeefe4f22017-01-04 15:32:42 -0800351 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800352 << "const std::string &serviceName) ";
353 out.block([&] {
Steven Moreland58b478b2017-04-09 10:54:50 -0700354 out << "::android::hardware::details::onRegistration(\""
355 << fqName.getPackageAndVersion().string() << "\", \""
356 << interfaceName
357 << "\", serviceName);\n\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800358 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
359 out.indent(2, [&] {
360 out << "= ::android::hardware::defaultServiceManager();\n";
361 });
362 out.sIf("sm == nullptr", [&] {
363 out << "return ::android::INVALID_OPERATION;\n";
364 }).endl();
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100365 out << "::android::hardware::Return<bool> ret = "
366 << "sm->add(serviceName.c_str(), this);\n"
367 << "return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800368 }).endl().endl();
369
Yifan Hongeefe4f22017-01-04 15:32:42 -0800370 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800371 out.indent(2, [&] {
372 out << "const std::string &serviceName,\n"
373 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
374 << "&notification) ";
375 });
376 out.block([&] {
377 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
378 out.indent(2, [&] {
379 out << "= ::android::hardware::defaultServiceManager();\n";
380 });
381 out.sIf("sm == nullptr", [&] {
382 out << "return false;\n";
383 }).endl();
384 out << "::android::hardware::Return<bool> success =\n";
385 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800386 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800387 out.indent(2, [&] {
388 out << "serviceName, notification);\n";
389 });
390 });
391 out << "return success.isOk() && success;\n";
392 }).endl().endl();
393}
394
Andreas Huberb82318c2016-08-02 14:45:54 -0700395status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700396 const Interface *iface = getInterface();
397 std::string ifaceName = iface ? iface->localName() : "types";
Andreas Huber881227d2016-08-02 14:20:21 -0700398
Andreas Huberb82318c2016-08-02 14:45:54 -0700399 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700400 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700401 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700402 path.append(ifaceName);
403 path.append(".h");
404
Andreas Huberd2943e12016-08-05 11:59:31 -0700405 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700406 FILE *file = fopen(path.c_str(), "w");
407
408 if (file == NULL) {
409 return -errno;
410 }
411
412 Formatter out(file);
413
414 const std::string guard = makeHeaderGuard(ifaceName);
415
416 out << "#ifndef " << guard << "\n";
417 out << "#define " << guard << "\n\n";
418
Andreas Huber737080b2016-08-02 15:38:04 -0700419 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700420 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700421 }
422
423 if (!mImportedNames.empty()) {
424 out << "\n";
425 }
426
Steven Moreland19f11b52017-05-12 18:22:21 -0700427 if (iface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800428 if (isIBase()) {
429 out << "// skipped #include IServiceNotification.h\n\n";
430 } else {
431 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
432 }
Steven Moreland0693f312016-11-09 15:06:14 -0800433 }
434
Yifan Hongc8934042016-11-17 17:10:52 -0800435 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700436 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700437
Steven Moreland19f11b52017-05-12 18:22:21 -0700438 if (iface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200439 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700440 }
441
Martijn Coenenaf712c02016-11-16 15:26:27 +0100442 out << "#include <utils/NativeHandle.h>\n";
443 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700444
445 enterLeaveNamespace(out, true /* enter */);
446 out << "\n";
447
Steven Moreland19f11b52017-05-12 18:22:21 -0700448 if (iface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700449 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700450 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700451
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700452 const Interface *superType = iface->superType();
453
Steven Moreland40786312016-08-16 10:29:40 -0700454 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800455 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700456 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000457 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700458 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700459 }
460
461 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700462
463 out.indent();
464
Andreas Huber881227d2016-08-02 14:20:21 -0700465 }
466
467 status_t err = emitTypeDeclarations(out);
468
469 if (err != OK) {
470 return err;
471 }
472
Steven Moreland19f11b52017-05-12 18:22:21 -0700473 if (iface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800474 out << "virtual bool isRemote() const ";
475 if (!isIBase()) {
476 out << "override ";
477 }
478 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800479
Andreas Huber881227d2016-08-02 14:20:21 -0700480 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700481 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700482
Andreas Huber881227d2016-08-02 14:20:21 -0700483 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800484 const TypedVar *elidedReturn = method->canElideCallback();
485
486 if (elidedReturn == nullptr && returnsValue) {
487 out << "using "
488 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700489 << "_cb = std::function<void(";
490 method->emitCppResultSignature(out, true /* specify namespaces */);
491 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800492 }
Andreas Huber881227d2016-08-02 14:20:21 -0700493
Andreas Huber3599d922016-08-09 10:42:57 -0700494 method->dumpAnnotations(out);
495
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700496 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700497 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700498 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700499 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700500 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700501 }
502
503 out << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700504 << "(";
505 method->emitCppArgSignature(out, true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700506
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700507 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700508 if (!method->args().empty()) {
509 out << ", ";
510 }
511
Steven Moreland67f67b42016-09-29 08:59:02 -0700512 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700513 }
514
Yifan Hong10fe0b52016-10-19 14:20:17 -0700515 out << ")";
516 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800517 if (!isIBase()) {
518 out << " override";
519 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700520 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700521 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700522 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700523 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700524 }
Steven Moreland40786312016-08-16 10:29:40 -0700525
Yifan Hong3d746092016-12-07 14:26:33 -0800526 out << "// cast static functions\n";
527 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700528
Yifan Hong3d746092016-12-07 14:26:33 -0800529 for (const Interface *superType : iface->typeChain()) {
Yifan Hong200209c2017-03-29 03:39:09 -0700530 out << "static ::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -0800531 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -0700532 << "> castFrom("
Yifan Hong3d746092016-12-07 14:26:33 -0800533 << superType->getCppArgumentType()
534 << " parent"
Yifan Hong200209c2017-03-29 03:39:09 -0700535 << ", bool emitError = false);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700536 }
537
Steven Morelandd39133b2016-11-11 12:30:08 -0800538 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700539
Yifan Hongc8934042016-11-17 17:10:52 -0800540 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800541 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800542 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800543 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800544 }
Andreas Huber881227d2016-08-02 14:20:21 -0700545 }
546
Steven Moreland19f11b52017-05-12 18:22:21 -0700547 if (iface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700548 out.unindent();
549
Andreas Hubere3f769a2016-10-10 10:54:44 -0700550 out << "};\n\n";
551 }
552
553 err = mRootScope->emitGlobalTypeDeclarations(out);
554
555 if (err != OK) {
556 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700557 }
558
559 out << "\n";
560 enterLeaveNamespace(out, false /* enter */);
561
562 out << "\n#endif // " << guard << "\n";
563
564 return OK;
565}
566
Steven Moreland40786312016-08-16 10:29:40 -0700567status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700568 const Interface *iface = getInterface();
569 std::string klassName = iface ? iface->getHwName() : "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700570
Steven Moreland40786312016-08-16 10:29:40 -0700571 std::string path = outputPath;
572 path.append(mCoordinator->convertPackageRootToPath(mPackage));
573 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
574 path.append(klassName + ".h");
575
Yifan Hong244e82d2016-11-11 11:13:57 -0800576 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700577
578 if (file == NULL) {
579 return -errno;
580 }
581
582 Formatter out(file);
583
584 const std::string guard = makeHeaderGuard(klassName);
585
586 out << "#ifndef " << guard << "\n";
587 out << "#define " << guard << "\n\n";
588
Steven Moreland19f11b52017-05-12 18:22:21 -0700589 generateCppPackageInclude(out, mPackage, iface ? iface->localName() : "types");
Steven Moreland40786312016-08-16 10:29:40 -0700590
Steven Morelandee88eed2016-10-31 17:49:00 -0700591 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700592
593 for (const auto &item : mImportedNames) {
594 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800595 generateCppPackageInclude(out, item, "hwtypes");
596 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800597 generateCppPackageInclude(out, item, item.getInterfaceStubName());
598 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700599 }
Steven Moreland40786312016-08-16 10:29:40 -0700600 }
601
602 out << "\n";
603
Martijn Coenen93915102016-09-01 01:35:52 +0200604 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700605 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100606 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700607
608 out << "\n";
609
610 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700611
Yifan Hong244e82d2016-11-11 11:13:57 -0800612 status_t err = mRootScope->emitGlobalHwDeclarations(out);
613 if (err != OK) {
614 return err;
615 }
Steven Moreland40786312016-08-16 10:29:40 -0700616
617 enterLeaveNamespace(out, false /* enter */);
618
619 out << "\n#endif // " << guard << "\n";
620
621 return OK;
622}
623
Andreas Huber881227d2016-08-02 14:20:21 -0700624status_t AST::emitTypeDeclarations(Formatter &out) const {
625 return mRootScope->emitTypeDeclarations(out);
626}
627
Yifan Hong7a118f52016-12-07 11:21:15 -0800628static void wrapPassthroughArg(Formatter &out,
629 const TypedVar *arg, bool addPrefixToName,
630 std::function<void(void)> handleError) {
631 if (!arg->type().isInterface()) {
632 return;
633 }
634 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
635 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
636 + arg->name();
637 const Interface &iface = static_cast<const Interface &>(arg->type());
638 out << iface.getCppStackType() << " " << wrappedName << ";\n";
639 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
640 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
641 out << wrappedName
642 << " = "
643 << iface.fqName().cppName()
Yifan Hong341112d2017-04-20 18:12:05 -0700644 << "::castFrom(::android::hardware::details::wrapPassthrough<"
645 << iface.fqName().cppName()
646 << ">("
Yifan Hong7a118f52016-12-07 11:21:15 -0800647 << name << "));\n";
648 out.sIf(wrappedName + " == nullptr", [&] {
649 // Fatal error. Happens when the BsFoo class is not found in the binary
650 // or any dynamic libraries.
651 handleError();
652 }).endl();
653 }).sElse([&] {
654 out << wrappedName << " = " << name << ";\n";
655 }).endl().endl();
656}
657
Steven Moreland69e7c702016-09-09 11:16:32 -0700658status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700659 const Method *method) const {
660 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700661
662 out << " {\n";
663 out.indent();
664
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800665 if (method->isHidlReserved()
666 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
667 method->cppImpl(IMPL_PASSTHROUGH, out);
668 out.unindent();
669 out << "}\n\n";
670 return OK;
671 }
672
Steven Moreland69e7c702016-09-09 11:16:32 -0700673 const bool returnsValue = !method->results().empty();
674 const TypedVar *elidedReturn = method->canElideCallback();
675
Steven Moreland67f67b42016-09-29 08:59:02 -0700676 if (returnsValue && elidedReturn == nullptr) {
677 generateCheckNonNull(out, "_hidl_cb");
678 }
679
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700680 generateCppInstrumentationCall(
681 out,
682 InstrumentationEvent::PASSTHROUGH_ENTRY,
683 method);
684
Yifan Hong7a118f52016-12-07 11:21:15 -0800685
686 for (const auto &arg : method->args()) {
687 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
688 out << "return ::android::hardware::Status::fromExceptionCode(\n";
689 out.indent(2, [&] {
690 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800691 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800692 });
693 });
694 }
695
696 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700697 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700698
699 if (method->isOneway()) {
Steven Moreland836cb312017-06-05 17:25:55 -0700700 out << "addOnewayTask([mImpl = this->mImpl\n"
701 << "#ifdef __ANDROID_DEBUGGABLE__\n"
702 ", mEnableInstrumentation = this->mEnableInstrumentation, "
703 "mInstrumentationCallbacks = this->mInstrumentationCallbacks\n"
704 << "#endif // __ANDROID_DEBUGGABLE__\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700705 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800706 out << ", "
707 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
708 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700709 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700710 out << "] {\n";
711 out.indent();
Steven Moreland69e7c702016-09-09 11:16:32 -0700712 }
713
714 out << "mImpl->"
715 << method->name()
716 << "(";
717
Yifan Hong932464e2017-03-30 15:40:22 -0700718 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800719 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700720 });
Steven Moreland69e7c702016-09-09 11:16:32 -0700721 if (returnsValue && elidedReturn == nullptr) {
Steven Moreland340c8822017-05-02 14:41:49 -0700722 // never true if oneway since oneway methods don't return values
723
Steven Moreland69e7c702016-09-09 11:16:32 -0700724 if (!method->args().empty()) {
725 out << ", ";
726 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800727 out << "[&](";
Yifan Hong932464e2017-03-30 15:40:22 -0700728 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800729 out << "const auto &_hidl_out_"
730 << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700731 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800732
733 out << ") {\n";
734 out.indent();
735 status_t status = generateCppInstrumentationCall(
736 out,
737 InstrumentationEvent::PASSTHROUGH_EXIT,
738 method);
739 if (status != OK) {
740 return status;
741 }
742
Yifan Hong7a118f52016-12-07 11:21:15 -0800743 for (const auto &arg : method->results()) {
744 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
745 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
746 out.indent(2, [&] {
747 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800748 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800749 });
750 out << "return;\n";
751 });
752 }
753
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800754 out << "_hidl_cb(";
Yifan Hong932464e2017-03-30 15:40:22 -0700755 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800756 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
757 << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700758 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800759 out << ");\n";
760 out.unindent();
761 out << "});\n\n";
762 } else {
763 out << ");\n\n";
Steven Moreland30b76e92017-06-02 18:52:24 -0700764
765 // used by generateCppInstrumentationCall
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800766 if (elidedReturn != nullptr) {
Steven Moreland30b76e92017-06-02 18:52:24 -0700767 out << "#ifdef __ANDROID_DEBUGGABLE__\n"
768 << elidedReturn->type().getCppResultType() << " _hidl_out_" << elidedReturn->name()
769 << " = _hidl_return;\n"
770 << "#endif // __ANDROID_DEBUGGABLE__\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800771 }
772 status_t status = generateCppInstrumentationCall(
773 out,
774 InstrumentationEvent::PASSTHROUGH_EXIT,
775 method);
776 if (status != OK) {
777 return status;
778 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700779 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700780
781 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700782 out.unindent();
783 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700784 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700785
786 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700787
788 out.unindent();
789 out << "}\n";
790
791 return OK;
792}
793
Yifan Hong068c5522016-10-31 14:07:25 -0700794status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700795 const Interface *iface = mRootScope->getInterface();
796
Yifan Hong10fe0b52016-10-19 14:20:17 -0700797 const Interface *prevIterface = nullptr;
798 for (const auto &tuple : iface->allMethodsFromRoot()) {
799 const Method *method = tuple.method();
800 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700801
Yifan Hong10fe0b52016-10-19 14:20:17 -0700802 if(prevIterface != superInterface) {
803 if (prevIterface != nullptr) {
804 out << "\n";
805 }
806 out << "// Methods from "
807 << superInterface->fullName()
808 << " follow.\n";
809 prevIterface = superInterface;
810 }
Yifan Hong068c5522016-10-31 14:07:25 -0700811 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700812
Yifan Hong10fe0b52016-10-19 14:20:17 -0700813 if (err != OK) {
814 return err;
815 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700816 }
817
Yifan Hong10fe0b52016-10-19 14:20:17 -0700818 out << "\n";
819
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700820 return OK;
821}
822
Andreas Huberb82318c2016-08-02 14:45:54 -0700823status_t AST::generateStubHeader(const std::string &outputPath) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700824 if (!AST::isInterface()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700825 // types.hal does not get a stub header.
826 return OK;
827 }
828
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700829 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800830 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700831
Andreas Huberb82318c2016-08-02 14:45:54 -0700832 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700833 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700834 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700835 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700836 path.append(".h");
837
Andreas Huberd2943e12016-08-05 11:59:31 -0700838 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700839 FILE *file = fopen(path.c_str(), "w");
840
841 if (file == NULL) {
842 return -errno;
843 }
844
845 Formatter out(file);
846
Steven Moreland40786312016-08-16 10:29:40 -0700847 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700848
849 out << "#ifndef " << guard << "\n";
850 out << "#define " << guard << "\n\n";
851
Yifan Hongeefe4f22017-01-04 15:32:42 -0800852 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700853 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700854
855 enterLeaveNamespace(out, true /* enter */);
856 out << "\n";
857
858 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800859 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100860 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800861 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000862 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100863 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800864 out << " : public "
865 << gIBaseFqName.getInterfaceStubFqName().cppName()
866 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100867 }
Andreas Huber881227d2016-08-02 14:20:21 -0700868
869 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800870 out << "explicit "
871 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -0700872 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100873 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800874 out << "explicit "
875 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -0700876 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800877 << " const std::string& HidlInstrumentor_package,"
878 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700879 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700880 out << "::android::status_t onTransact(\n";
881 out.indent();
882 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700883 out << "uint32_t _hidl_code,\n";
884 out << "const ::android::hardware::Parcel &_hidl_data,\n";
885 out << "::android::hardware::Parcel *_hidl_reply,\n";
886 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700887 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700888 out.unindent();
889 out.unindent();
890
Steven Moreland19f11b52017-05-12 18:22:21 -0700891 out << "::android::sp<" << iface->localName() << "> getImpl() { return _hidl_mImpl; };\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100892 out.unindent();
893 out << "private:\n";
894 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800895
896 status_t err = generateMethods(out, [&](const Method *method, const Interface *iface) {
897 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
898 return OK;
899 }
900 const bool returnsValue = !method->results().empty();
901 const TypedVar *elidedReturn = method->canElideCallback();
902
903 if (elidedReturn == nullptr && returnsValue) {
904 out << "using " << method->name() << "_cb = "
905 << iface->fqName().cppName()
906 << "::" << method->name() << "_cb;\n";
907 }
908 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800909 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800910 return OK;
911 });
912 if (err != OK) {
913 return err;
914 }
915
Steven Moreland19f11b52017-05-12 18:22:21 -0700916 out << "::android::sp<" << iface->localName() << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700917 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700918 out << "};\n\n";
919
920 enterLeaveNamespace(out, false /* enter */);
921
922 out << "\n#endif // " << guard << "\n";
923
924 return OK;
925}
926
Andreas Huberb82318c2016-08-02 14:45:54 -0700927status_t AST::generateProxyHeader(const std::string &outputPath) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700928 if (!AST::isInterface()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700929 // types.hal does not get a proxy header.
930 return OK;
931 }
932
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700933 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800934 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700935
Andreas Huberb82318c2016-08-02 14:45:54 -0700936 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700937 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700938 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800939 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700940 path.append(".h");
941
Andreas Huberd2943e12016-08-05 11:59:31 -0700942 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700943 FILE *file = fopen(path.c_str(), "w");
944
945 if (file == NULL) {
946 return -errno;
947 }
948
949 Formatter out(file);
950
Yifan Hongeefe4f22017-01-04 15:32:42 -0800951 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700952
953 out << "#ifndef " << guard << "\n";
954 out << "#define " << guard << "\n\n";
955
Martijn Coenen115d4282016-12-19 05:14:04 +0100956 out << "#include <hidl/HidlTransportSupport.h>\n\n";
957
Andreas Huber881227d2016-08-02 14:20:21 -0700958 std::vector<std::string> packageComponents;
959 getPackageAndVersionComponents(
960 &packageComponents, false /* cpp_compatible */);
961
Yifan Hongeefe4f22017-01-04 15:32:42 -0800962 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700963 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700964
965 enterLeaveNamespace(out, true /* enter */);
966 out << "\n";
967
968 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800969 << proxyName
970 << " : public ::android::hardware::BpInterface<"
971 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000972 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700973
974 out.indent();
975
Yifan Hongeefe4f22017-01-04 15:32:42 -0800976 out << "explicit "
977 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700978 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700979 << "\n\n";
980
Yifan Hong10fe0b52016-10-19 14:20:17 -0700981 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700982
Yifan Hong068c5522016-10-31 14:07:25 -0700983 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
984 method->generateCppSignature(out);
985 out << " override;\n";
986 return OK;
987 });
Steven Moreland9c387612016-09-07 09:54:26 -0700988
989 if (err != OK) {
990 return err;
991 }
Andreas Huber881227d2016-08-02 14:20:21 -0700992
993 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100994 out << "private:\n";
995 out.indent();
996 out << "std::mutex _hidl_mMutex;\n"
997 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
998 << " _hidl_mDeathRecipients;\n";
999 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -07001000 out << "};\n\n";
1001
1002 enterLeaveNamespace(out, false /* enter */);
1003
1004 out << "\n#endif // " << guard << "\n";
1005
1006 return OK;
1007}
1008
Steven Moreland1cbf0362017-05-09 14:32:53 -07001009status_t AST::generateCppSources(const std::string &outputPath) const {
Steven Moreland19f11b52017-05-12 18:22:21 -07001010 std::string baseName = getBaseName();
1011 const Interface *iface = getInterface();
Andreas Huber881227d2016-08-02 14:20:21 -07001012
Andreas Huberb82318c2016-08-02 14:45:54 -07001013 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -07001014 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -07001015 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -07001016 path.append(baseName);
1017
1018 if (baseName != "types") {
1019 path.append("All");
1020 }
1021
1022 path.append(".cpp");
1023
Andreas Huberd2943e12016-08-05 11:59:31 -07001024 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -07001025 FILE *file = fopen(path.c_str(), "w");
1026
1027 if (file == NULL) {
1028 return -errno;
1029 }
1030
1031 Formatter out(file);
1032
Steven Moreland623c0042017-01-13 14:42:29 -08001033 out << "#define LOG_TAG \""
1034 << mPackage.string() << "::" << baseName
1035 << "\"\n\n";
1036
Steven Moreland05cd4232016-11-21 16:01:12 -08001037 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001038 out << "#include <cutils/trace.h>\n";
1039 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Steven Moreland19f11b52017-05-12 18:22:21 -07001040 if (iface) {
Steven Moreland19d5c172016-10-20 19:20:25 -07001041 // This is a no-op for IServiceManager itself.
1042 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
1043
Yifan Hongeefe4f22017-01-04 15:32:42 -08001044 generateCppPackageInclude(out, mPackage, iface->getProxyName());
1045 generateCppPackageInclude(out, mPackage, iface->getStubName());
1046 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001047
1048 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -07001049 generateCppPackageInclude(out,
1050 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -08001051 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001052 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -08001053
1054 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001055 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -07001056 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -08001057 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -07001058 }
1059
1060 out << "\n";
1061
1062 enterLeaveNamespace(out, true /* enter */);
1063 out << "\n";
1064
Steven Moreland19f11b52017-05-12 18:22:21 -07001065 status_t err = generateTypeSource(out, iface ? iface->localName() : "");
Andreas Huber881227d2016-08-02 14:20:21 -07001066
Steven Moreland19f11b52017-05-12 18:22:21 -07001067 if (err == OK && iface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001068 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001069
1070 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -08001071 out << "const char* "
1072 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -07001073 << "::descriptor(\""
1074 << iface->fqName().string()
1075 << "\");\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +01001076 out << "__attribute__((constructor))";
1077 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001078 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001079 out << "::android::hardware::details::gBnConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001080 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001081 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001082 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001083 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001084 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001085 out << "return new "
1086 << iface->getStubName()
Yifan Hong341112d2017-04-20 18:12:05 -07001087 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001088 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001089 << " *>(iIntf));\n";
1090 });
Yifan Hongb04de382017-02-06 15:31:52 -08001091 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001092 });
Yifan Honga159f3b2017-03-16 14:53:51 -07001093 out << "::android::hardware::details::gBsConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001094 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001095 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001096 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001097 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -08001098 << gIBaseFqName.cppName()
1099 << "> {\n";
1100 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001101 out << "return new "
1102 << iface->getPassthroughName()
Yifan Hong341112d2017-04-20 18:12:05 -07001103 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001104 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001105 << " *>(iIntf));\n";
1106 });
Yifan Hongb04de382017-02-06 15:31:52 -08001107 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001108 });
Yifan Hong158655a2016-11-08 12:34:07 -08001109 });
Martijn Coenen8adcb652017-02-03 17:37:36 +01001110 out << "};\n\n";
1111 out << "__attribute__((destructor))";
1112 out << "static void static_destructor() {\n";
1113 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001114 out << "::android::hardware::details::gBnConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001115 << iface->localName()
1116 << "::descriptor);\n";
Yifan Honga159f3b2017-03-16 14:53:51 -07001117 out << "::android::hardware::details::gBsConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001118 << iface->localName()
1119 << "::descriptor);\n";
1120 });
1121 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001122
Yifan Hongfe95aa22016-10-19 17:26:45 -07001123 err = generateInterfaceSource(out);
1124 }
1125
Steven Moreland19f11b52017-05-12 18:22:21 -07001126 if (err == OK && iface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001127 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001128 }
1129
Steven Moreland19f11b52017-05-12 18:22:21 -07001130 if (err == OK && iface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001131 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001132 }
1133
Steven Moreland19f11b52017-05-12 18:22:21 -07001134 if (err == OK && iface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001135 err = generatePassthroughSource(out);
1136 }
1137
Steven Moreland19f11b52017-05-12 18:22:21 -07001138 if (err == OK && iface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001139 const Interface *iface = mRootScope->getInterface();
1140
Yifan Hongc8934042016-11-17 17:10:52 -08001141 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001142 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001143 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001144 std::string package = iface->fqName().package()
1145 + iface->fqName().atVersion();
1146
Yifan Hongeefe4f22017-01-04 15:32:42 -08001147 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001148 }
Steven Moreland40786312016-08-16 10:29:40 -07001149 }
1150
Andreas Huber6755e9d2017-04-06 11:09:07 -07001151 HidlTypeAssertion::EmitAll(out);
1152 out << "\n";
1153
Andreas Huber881227d2016-08-02 14:20:21 -07001154 enterLeaveNamespace(out, false /* enter */);
1155
1156 return err;
1157}
1158
Steven Moreland67f67b42016-09-29 08:59:02 -07001159void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001160 out.sIf(nonNull + " == nullptr", [&] {
1161 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1162 out.indent(2, [&] {
Steven Moreland610002f2017-06-16 13:02:49 -07001163 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT,\n"
1164 << "\"Null synchronous callback passed.\");\n";
Yifan Honga018ed52016-12-13 16:35:08 -08001165 });
1166 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001167}
1168
Andreas Huber881227d2016-08-02 14:20:21 -07001169status_t AST::generateTypeSource(
1170 Formatter &out, const std::string &ifaceName) const {
1171 return mRootScope->emitTypeDefinitions(out, ifaceName);
1172}
1173
Andreas Hubere7ff2282016-08-16 13:50:03 -07001174void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001175 Formatter &out,
1176 const std::vector<TypedVar *> &args,
1177 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001178 if (args.empty()) {
1179 return;
1180 }
1181
1182 for (const auto &arg : args) {
1183 const Type &type = arg->type();
1184
Yifan Hong3b320f82016-11-01 15:15:54 -07001185 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001186 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001187 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001188 << ";\n";
1189 }
1190
1191 out << "\n";
1192}
1193
Andreas Huber881227d2016-08-02 14:20:21 -07001194void AST::emitCppReaderWriter(
1195 Formatter &out,
1196 const std::string &parcelObj,
1197 bool parcelObjIsPointer,
1198 const TypedVar *arg,
1199 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001200 Type::ErrorMode mode,
1201 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001202 const Type &type = arg->type();
1203
Andreas Huber881227d2016-08-02 14:20:21 -07001204 type.emitReaderWriter(
1205 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001206 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001207 parcelObj,
1208 parcelObjIsPointer,
1209 isReader,
1210 mode);
1211}
1212
Yifan Hongbf459bc2016-08-23 16:50:37 -07001213void AST::emitCppResolveReferences(
1214 Formatter &out,
1215 const std::string &parcelObj,
1216 bool parcelObjIsPointer,
1217 const TypedVar *arg,
1218 bool isReader,
1219 Type::ErrorMode mode,
1220 bool addPrefixToName) const {
1221 const Type &type = arg->type();
1222 if(type.needsResolveReferences()) {
1223 type.emitResolveReferences(
1224 out,
1225 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1226 isReader, // nameIsPointer
1227 parcelObj,
1228 parcelObjIsPointer,
1229 isReader,
1230 mode);
1231 }
1232}
1233
Yifan Hong068c5522016-10-31 14:07:25 -07001234status_t AST::generateProxyMethodSource(Formatter &out,
1235 const std::string &klassName,
1236 const Method *method,
1237 const Interface *superInterface) const {
1238
1239 method->generateCppSignature(out,
1240 klassName,
1241 true /* specify namespaces */);
1242
1243 const bool returnsValue = !method->results().empty();
1244 const TypedVar *elidedReturn = method->canElideCallback();
1245
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001246 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001247
1248 out.indent();
1249
Martijn Coenen115d4282016-12-19 05:14:04 +01001250 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1251 method->cppImpl(IMPL_PROXY, out);
1252 out.unindent();
1253 out << "}\n\n";
1254 return OK;
1255 }
1256
Yifan Hong068c5522016-10-31 14:07:25 -07001257 if (returnsValue && elidedReturn == nullptr) {
1258 generateCheckNonNull(out, "_hidl_cb");
1259 }
1260
1261 status_t status = generateCppInstrumentationCall(
1262 out,
1263 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001264 method);
1265 if (status != OK) {
1266 return status;
1267 }
1268
1269 out << "::android::hardware::Parcel _hidl_data;\n";
1270 out << "::android::hardware::Parcel _hidl_reply;\n";
1271 out << "::android::status_t _hidl_err;\n";
1272 out << "::android::hardware::Status _hidl_status;\n\n";
1273
1274 declareCppReaderLocals(
1275 out, method->results(), true /* forResults */);
1276
1277 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001278 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001279 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001280 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1281
Martijn Coenenfff73352017-01-04 16:36:31 +01001282 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001283 // First DFS: write all buffers and resolve pointers for parent
1284 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001285 if (arg->type().isInterface()) {
1286 hasInterfaceArgument = true;
1287 }
Yifan Hong068c5522016-10-31 14:07:25 -07001288 emitCppReaderWriter(
1289 out,
1290 "_hidl_data",
1291 false /* parcelObjIsPointer */,
1292 arg,
1293 false /* reader */,
1294 Type::ErrorMode_Goto,
1295 false /* addPrefixToName */);
1296 }
1297
1298 // Second DFS: resolve references.
1299 for (const auto &arg : method->args()) {
1300 emitCppResolveReferences(
1301 out,
1302 "_hidl_data",
1303 false /* parcelObjIsPointer */,
1304 arg,
1305 false /* reader */,
1306 Type::ErrorMode_Goto,
1307 false /* addPrefixToName */);
1308 }
1309
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001310 if (hasInterfaceArgument) {
1311 // Start binder threadpool to handle incoming transactions
1312 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1313 }
Yifan Hong068c5522016-10-31 14:07:25 -07001314 out << "_hidl_err = remote()->transact("
1315 << method->getSerialId()
1316 << " /* "
1317 << method->name()
1318 << " */, _hidl_data, &_hidl_reply";
1319
1320 if (method->isOneway()) {
1321 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1322 }
1323 out << ");\n";
1324
1325 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1326
1327 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001328 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001329 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1330 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1331
1332
1333 // First DFS: write all buffers and resolve pointers for parent
1334 for (const auto &arg : method->results()) {
1335 emitCppReaderWriter(
1336 out,
1337 "_hidl_reply",
1338 false /* parcelObjIsPointer */,
1339 arg,
1340 true /* reader */,
1341 Type::ErrorMode_Goto,
1342 true /* addPrefixToName */);
1343 }
1344
1345 // Second DFS: resolve references.
1346 for (const auto &arg : method->results()) {
1347 emitCppResolveReferences(
1348 out,
1349 "_hidl_reply",
1350 false /* parcelObjIsPointer */,
1351 arg,
1352 true /* reader */,
1353 Type::ErrorMode_Goto,
1354 true /* addPrefixToName */);
1355 }
1356
1357 if (returnsValue && elidedReturn == nullptr) {
1358 out << "_hidl_cb(";
1359
Yifan Hong932464e2017-03-30 15:40:22 -07001360 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001361 if (arg->type().resultNeedsDeref()) {
1362 out << "*";
1363 }
1364 out << "_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001365 });
Yifan Hong068c5522016-10-31 14:07:25 -07001366
1367 out << ");\n\n";
1368 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001369 }
1370 status = generateCppInstrumentationCall(
1371 out,
1372 InstrumentationEvent::CLIENT_API_EXIT,
1373 method);
1374 if (status != OK) {
1375 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001376 }
1377
1378 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001379 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1380 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001381 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001382 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1383 } else {
1384 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1385 out << "return ::android::hardware::Return<void>();\n\n";
1386 }
1387
1388 out.unindent();
1389 out << "_hidl_error:\n";
1390 out.indent();
1391 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1392 out << "return ::android::hardware::Return<";
1393 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001394 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001395 } else {
1396 out << "void";
1397 }
1398 out << ">(_hidl_status);\n";
1399
1400 out.unindent();
1401 out << "}\n\n";
1402 return OK;
1403}
1404
Andreas Huber881227d2016-08-02 14:20:21 -07001405status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001406 Formatter &out, const FQName &fqName) const {
1407 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001408
1409 out << klassName
1410 << "::"
1411 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001412 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001413
1414 out.indent();
1415 out.indent();
1416
1417 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001418 << "<"
1419 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001420 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001421 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001422 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001423 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001424 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001425 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001426
Andreas Huber881227d2016-08-02 14:20:21 -07001427 out.unindent();
1428 out.unindent();
1429 out << "}\n\n";
1430
Yifan Hong068c5522016-10-31 14:07:25 -07001431 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1432 return generateProxyMethodSource(out, klassName, method, superInterface);
1433 });
Andreas Huber881227d2016-08-02 14:20:21 -07001434
Yifan Hong068c5522016-10-31 14:07:25 -07001435 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001436}
1437
1438status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001439 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001440 const Interface *iface) const {
1441 const std::string interfaceName = iface->localName();
1442 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001443
Steven Moreland40786312016-08-16 10:29:40 -07001444 out << klassName
1445 << "::"
1446 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001447 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001448
1449 out.indent();
1450 out.indent();
1451
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001452 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001453 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001454 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001455 out << ": "
1456 << gIBaseFqName.getInterfaceStubFqName().cppName()
1457 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001458 }
1459
1460 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001461 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001462 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001463 << "\") { \n";
1464 out.indent();
1465 out << "_hidl_mImpl = _hidl_impl;\n";
1466 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001467
1468 out.unindent();
1469 out.unindent();
1470 out << "}\n\n";
1471
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001472 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001473 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001474 // class properly.
1475 out << klassName
1476 << "::"
1477 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001478 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1479 << " const std::string &HidlInstrumentor_package,"
1480 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001481
1482 out.indent();
1483 out.indent();
1484
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001485 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001486 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001487 out.indent();
1488 out << "_hidl_mImpl = _hidl_impl;\n";
1489 out.unindent();
1490
1491 out.unindent();
1492 out.unindent();
1493 out << "}\n\n";
1494 }
1495
Yifan Hongbcffce22017-02-01 15:52:06 -08001496 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1497 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1498 return OK;
1499 }
1500 method->generateCppSignature(out, iface->getStubName());
1501 out << " ";
1502 out.block([&] {
1503 method->cppImpl(IMPL_STUB_IMPL, out);
1504 }).endl();
1505 return OK;
1506 });
Steven Moreland60818632017-02-04 00:33:42 -08001507 if (err != OK) {
1508 return err;
1509 }
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001510
Andreas Huber881227d2016-08-02 14:20:21 -07001511 out << "::android::status_t " << klassName << "::onTransact(\n";
1512
1513 out.indent();
1514 out.indent();
1515
Iliyan Malchev549e2592016-08-10 08:59:12 -07001516 out << "uint32_t _hidl_code,\n"
1517 << "const ::android::hardware::Parcel &_hidl_data,\n"
1518 << "::android::hardware::Parcel *_hidl_reply,\n"
1519 << "uint32_t _hidl_flags,\n"
1520 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001521
1522 out.unindent();
1523
Iliyan Malchev549e2592016-08-10 08:59:12 -07001524 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001525 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001526 out.indent();
1527
Yifan Hong10fe0b52016-10-19 14:20:17 -07001528 for (const auto &tuple : iface->allMethodsFromRoot()) {
1529 const Method *method = tuple.method();
1530 const Interface *superInterface = tuple.interface();
1531 out << "case "
1532 << method->getSerialId()
1533 << " /* "
1534 << method->name()
1535 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001536
Yifan Hong10fe0b52016-10-19 14:20:17 -07001537 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001538
Yifan Hong10fe0b52016-10-19 14:20:17 -07001539 status_t err =
1540 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001541
Yifan Hong10fe0b52016-10-19 14:20:17 -07001542 if (err != OK) {
1543 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001544 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001545
1546 out.unindent();
1547 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001548 }
1549
1550 out << "default:\n{\n";
1551 out.indent();
1552
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001553 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001554
1555 out.indent();
1556 out.indent();
1557
Iliyan Malchev549e2592016-08-10 08:59:12 -07001558 out << "_hidl_code, _hidl_data, _hidl_reply, "
1559 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001560
1561 out.unindent();
1562 out.unindent();
1563
1564 out.unindent();
1565 out << "}\n";
1566
1567 out.unindent();
1568 out << "}\n\n";
1569
Yifan Honga018ed52016-12-13 16:35:08 -08001570 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1571 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1572 out.indent(2, [&] {
1573 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1574 out << "_hidl_reply);\n";
1575 });
1576 });
Andreas Huber881227d2016-08-02 14:20:21 -07001577
Iliyan Malchev549e2592016-08-10 08:59:12 -07001578 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001579
1580 out.unindent();
1581 out << "}\n\n";
1582
1583 return OK;
1584}
1585
1586status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001587 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001588 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1589 method->cppImpl(IMPL_STUB, out);
1590 out << "break;\n";
1591 return OK;
1592 }
1593
Yifan Hongeefe4f22017-01-04 15:32:42 -08001594 out << "if (!_hidl_data.enforceInterface("
1595 << iface->fullName()
1596 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001597
Andreas Huber881227d2016-08-02 14:20:21 -07001598 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001599 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001600 out << "break;\n";
1601 out.unindent();
1602 out << "}\n\n";
1603
Andreas Huber5e44a292016-09-27 14:52:39 -07001604 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001605
Yifan Hongbf459bc2016-08-23 16:50:37 -07001606 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001607 for (const auto &arg : method->args()) {
1608 emitCppReaderWriter(
1609 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001610 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001611 false /* parcelObjIsPointer */,
1612 arg,
1613 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001614 Type::ErrorMode_Break,
1615 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001616 }
1617
Yifan Hongbf459bc2016-08-23 16:50:37 -07001618 // Second DFS: resolve references
1619 for (const auto &arg : method->args()) {
1620 emitCppResolveReferences(
1621 out,
1622 "_hidl_data",
1623 false /* parcelObjIsPointer */,
1624 arg,
1625 true /* reader */,
1626 Type::ErrorMode_Break,
1627 false /* addPrefixToName */);
1628 }
1629
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001630 status_t status = generateCppInstrumentationCall(
1631 out,
1632 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001633 method);
1634 if (status != OK) {
1635 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001636 }
1637
Andreas Huber881227d2016-08-02 14:20:21 -07001638 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001639 const TypedVar *elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -08001640 const std::string callee =
1641 (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL))
1642 ? "this" : "_hidl_mImpl";
Andreas Huber881227d2016-08-02 14:20:21 -07001643
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001644 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001645 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001646 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001647 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001648 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001649 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001650 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001651
Yifan Hong932464e2017-03-30 15:40:22 -07001652 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001653 if (arg->type().resultNeedsDeref()) {
1654 out << "*";
1655 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001656 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001657 });
Andreas Huber881227d2016-08-02 14:20:21 -07001658
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001659 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001660 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1661 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001662
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001663 elidedReturn->type().emitReaderWriter(
1664 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001665 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001666 "_hidl_reply",
1667 true, /* parcelObjIsPointer */
1668 false, /* isReader */
1669 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001670
Yifan Hongbf459bc2016-08-23 16:50:37 -07001671 emitCppResolveReferences(
1672 out,
1673 "_hidl_reply",
1674 true /* parcelObjIsPointer */,
1675 elidedReturn,
1676 false /* reader */,
1677 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001678 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001679
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001680 status_t status = generateCppInstrumentationCall(
1681 out,
1682 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001683 method);
1684 if (status != OK) {
1685 return status;
1686 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001687
Iliyan Malchev549e2592016-08-10 08:59:12 -07001688 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001689 } else {
1690 if (returnsValue) {
1691 out << "bool _hidl_callbackCalled = false;\n\n";
1692 }
Andreas Huber881227d2016-08-02 14:20:21 -07001693
Yifan Hongcd2ae452017-01-31 14:33:40 -08001694 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001695
Yifan Hong932464e2017-03-30 15:40:22 -07001696 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001697 if (arg->type().resultNeedsDeref()) {
1698 out << "*";
1699 }
1700
1701 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001702 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001703
1704 if (returnsValue) {
Yifan Hong932464e2017-03-30 15:40:22 -07001705 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001706 out << ", ";
1707 }
1708
1709 out << "[&](";
1710
Yifan Hong932464e2017-03-30 15:40:22 -07001711 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001712 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001713 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001714
1715 out << ") {\n";
1716 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001717 out << "if (_hidl_callbackCalled) {\n";
1718 out.indent();
1719 out << "LOG_ALWAYS_FATAL(\""
1720 << method->name()
1721 << ": _hidl_cb called a second time, but must be called once.\");\n";
1722 out.unindent();
1723 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001724 out << "_hidl_callbackCalled = true;\n\n";
1725
Yifan Hong859e53f2016-11-14 19:08:24 -08001726 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1727 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001728
Yifan Hongbf459bc2016-08-23 16:50:37 -07001729 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001730 for (const auto &arg : method->results()) {
1731 emitCppReaderWriter(
1732 out,
1733 "_hidl_reply",
1734 true /* parcelObjIsPointer */,
1735 arg,
1736 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001737 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001738 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001739 }
1740
Yifan Hongbf459bc2016-08-23 16:50:37 -07001741 // Second DFS: resolve references
1742 for (const auto &arg : method->results()) {
1743 emitCppResolveReferences(
1744 out,
1745 "_hidl_reply",
1746 true /* parcelObjIsPointer */,
1747 arg,
1748 false /* reader */,
1749 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001750 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001751 }
1752
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001753 status_t status = generateCppInstrumentationCall(
1754 out,
1755 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001756 method);
1757 if (status != OK) {
1758 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001759 }
1760
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001761 out << "_hidl_cb(*_hidl_reply);\n";
1762
1763 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001764 out << "});\n\n";
1765 } else {
1766 out << ");\n\n";
1767 status_t status = generateCppInstrumentationCall(
1768 out,
1769 InstrumentationEvent::SERVER_API_EXIT,
1770 method);
1771 if (status != OK) {
1772 return status;
1773 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001774 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001775
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001776 if (returnsValue) {
1777 out << "if (!_hidl_callbackCalled) {\n";
1778 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001779 out << "LOG_ALWAYS_FATAL(\""
1780 << method->name()
1781 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001782 out.unindent();
1783 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001784 } else {
1785 out << "::android::hardware::writeToParcel("
1786 << "::android::hardware::Status::ok(), "
1787 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001788 }
Andreas Huber881227d2016-08-02 14:20:21 -07001789 }
1790
1791 out << "break;\n";
1792
1793 return OK;
1794}
1795
Steven Moreland69e7c702016-09-09 11:16:32 -07001796status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
Steven Moreland19f11b52017-05-12 18:22:21 -07001797 if (!AST::isInterface()) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001798 // types.hal does not get a stub header.
1799 return OK;
1800 }
1801
1802 const Interface *iface = mRootScope->getInterface();
Steven Moreland19f11b52017-05-12 18:22:21 -07001803 CHECK(iface != nullptr);
Steven Moreland69e7c702016-09-09 11:16:32 -07001804
Yifan Hongeefe4f22017-01-04 15:32:42 -08001805 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001806
1807 bool supportOneway = iface->hasOnewayMethods();
1808
1809 std::string path = outputPath;
1810 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1811 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1812 path.append(klassName);
1813 path.append(".h");
1814
1815 CHECK(Coordinator::MakeParentHierarchy(path));
1816 FILE *file = fopen(path.c_str(), "w");
1817
1818 if (file == NULL) {
1819 return -errno;
1820 }
1821
1822 Formatter out(file);
1823
1824 const std::string guard = makeHeaderGuard(klassName);
1825
1826 out << "#ifndef " << guard << "\n";
1827 out << "#define " << guard << "\n\n";
1828
1829 std::vector<std::string> packageComponents;
1830 getPackageAndVersionComponents(
1831 &packageComponents, false /* cpp_compatible */);
1832
Steven Moreland61d3f4b2017-04-28 17:30:38 -07001833 out << "#include <android-base/macros.h>\n";
Yifan Hongb0949432016-12-15 15:32:24 -08001834 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001835 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001836
Steven Moreland19f11b52017-05-12 18:22:21 -07001837 generateCppPackageInclude(out, mPackage, iface->localName());
Steven Morelandee88eed2016-10-31 17:49:00 -07001838 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001839
Yifan Hong7a118f52016-12-07 11:21:15 -08001840 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001841 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001842 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001843 }
1844
1845 enterLeaveNamespace(out, true /* enter */);
1846 out << "\n";
1847
1848 out << "struct "
1849 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -07001850 << " : " << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001851 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001852
1853 out.indent();
1854 out << "explicit "
1855 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001856 << "(const ::android::sp<"
Steven Moreland19f11b52017-05-12 18:22:21 -07001857 << iface->localName()
Steven Moreland69e7c702016-09-09 11:16:32 -07001858 << "> impl);\n";
1859
Yifan Hong068c5522016-10-31 14:07:25 -07001860 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1861 return generatePassthroughMethod(out, method);
1862 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001863
1864 if (err != OK) {
1865 return err;
1866 }
1867
1868 out.unindent();
1869 out << "private:\n";
1870 out.indent();
Steven Moreland19f11b52017-05-12 18:22:21 -07001871 out << "const ::android::sp<" << iface->localName() << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001872
1873 if (supportOneway) {
Yifan Hongef91d362017-03-20 17:18:13 -07001874 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001875
1876 out << "\n";
1877
1878 out << "::android::hardware::Return<void> addOnewayTask("
1879 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001880 }
1881
1882 out.unindent();
1883
1884 out << "};\n\n";
1885
1886 enterLeaveNamespace(out, false /* enter */);
1887
1888 out << "\n#endif // " << guard << "\n";
1889
1890 return OK;
1891}
1892
Yifan Hongfe95aa22016-10-19 17:26:45 -07001893status_t AST::generateInterfaceSource(Formatter &out) const {
1894 const Interface *iface = mRootScope->getInterface();
1895
Yifan Hong2d7126b2016-10-20 15:12:57 -07001896 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001897 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001898
Steven Morelandd4b068a2017-03-20 06:30:51 -07001899 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1900 bool reserved = method->isHidlReserved();
1901
1902 if (!reserved) {
1903 out << "// no default implementation for: ";
1904 }
1905 method->generateCppSignature(out, iface->localName());
1906 if (reserved) {
1907 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001908 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001909 }).endl();
1910 }
1911
1912 out << "\n";
1913
1914 return OK;
1915 });
1916 if (err != OK) {
1917 return err;
1918 }
1919
Yifan Hong3d746092016-12-07 14:26:33 -08001920 for (const Interface *superType : iface->typeChain()) {
Yifan Hong200209c2017-03-29 03:39:09 -07001921 out << "// static \n::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -08001922 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -07001923 << "> "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001924 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001925 << "::castFrom("
1926 << superType->getCppArgumentType()
Yifan Hong200209c2017-03-29 03:39:09 -07001927 << " parent, bool "
1928 << (iface == superType ? "/* emitError */" : "emitError")
1929 << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001930 out.indent();
1931 if (iface == superType) {
1932 out << "return parent;\n";
1933 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001934 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001935 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001936 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001937 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001938 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001939 << ">(\n";
1940 out.indent();
1941 out.indent();
1942 out << "parent, \""
1943 << iface->fqName().string()
Yifan Hong200209c2017-03-29 03:39:09 -07001944 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001945 out.unindent();
1946 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001947 }
Yifan Hong3d746092016-12-07 14:26:33 -08001948 out.unindent();
1949 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001950 }
1951
1952 return OK;
1953}
1954
Steven Moreland69e7c702016-09-09 11:16:32 -07001955status_t AST::generatePassthroughSource(Formatter &out) const {
1956 const Interface *iface = mRootScope->getInterface();
1957
Yifan Hongeefe4f22017-01-04 15:32:42 -08001958 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001959
1960 out << klassName
1961 << "::"
1962 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001963 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001964 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001965 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001966 << mPackage.string()
1967 << "\", \""
1968 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001969 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001970 if (iface->hasOnewayMethods()) {
1971 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001972 out.indent([&] {
Yifan Hongf01dad42017-03-20 19:03:11 -07001973 out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001974 });
1975 }
1976 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001977
1978 if (iface->hasOnewayMethods()) {
1979 out << "::android::hardware::Return<void> "
1980 << klassName
1981 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1982 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001983 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001984 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001985 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1986 out.indent();
1987 out.indent();
Steven Moreland610002f2017-06-16 13:02:49 -07001988 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
1989 << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
Steven Moreland67f67b42016-09-29 08:59:02 -07001990 out.unindent();
1991 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001992 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001993 out << "}\n";
1994
Steven Morelandd366c262016-10-11 15:29:10 -07001995 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001996
1997 out.unindent();
1998 out << "}\n\n";
1999
2000
2001 }
2002
2003 return OK;
2004}
2005
Martijn Coenen7b295242016-11-04 16:52:56 +01002006status_t AST::generateCppAtraceCall(Formatter &out,
2007 InstrumentationEvent event,
2008 const Method *method) const {
2009 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08002010 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01002011 switch (event) {
2012 case SERVER_API_ENTRY:
2013 {
2014 out << "atrace_begin(ATRACE_TAG_HAL, \""
2015 << baseString + "::server\");\n";
2016 break;
2017 }
2018 case CLIENT_API_ENTRY:
2019 {
2020 out << "atrace_begin(ATRACE_TAG_HAL, \""
2021 << baseString + "::client\");\n";
2022 break;
2023 }
2024 case PASSTHROUGH_ENTRY:
2025 {
2026 out << "atrace_begin(ATRACE_TAG_HAL, \""
2027 << baseString + "::passthrough\");\n";
2028 break;
2029 }
2030 case SERVER_API_EXIT:
2031 case CLIENT_API_EXIT:
2032 case PASSTHROUGH_EXIT:
2033 {
2034 out << "atrace_end(ATRACE_TAG_HAL);\n";
2035 break;
2036 }
2037 default:
2038 {
2039 LOG(ERROR) << "Unsupported instrumentation event: " << event;
2040 return UNKNOWN_ERROR;
2041 }
2042 }
2043
2044 return OK;
2045}
2046
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002047status_t AST::generateCppInstrumentationCall(
2048 Formatter &out,
2049 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07002050 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01002051 status_t err = generateCppAtraceCall(out, event, method);
2052 if (err != OK) {
2053 return err;
2054 }
2055
Steven Moreland30b76e92017-06-02 18:52:24 -07002056 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002057 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
2058 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002059 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002060 std::string event_str = "";
2061 switch (event) {
2062 case SERVER_API_ENTRY:
2063 {
2064 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
2065 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002066 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002067 << (arg->type().resultNeedsDeref() ? "" : "&")
2068 << arg->name()
2069 << ");\n";
2070 }
2071 break;
2072 }
2073 case SERVER_API_EXIT:
2074 {
2075 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07002076 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002077 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07002078 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002079 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002080 }
2081 break;
2082 }
2083 case CLIENT_API_ENTRY:
2084 {
2085 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2086 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002087 out << "_hidl_args.push_back((void *)&"
2088 << arg->name()
2089 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002090 }
2091 break;
2092 }
2093 case CLIENT_API_EXIT:
2094 {
2095 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2096 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002097 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002098 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002099 << "_hidl_out_"
2100 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002101 << ");\n";
2102 }
2103 break;
2104 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002105 case PASSTHROUGH_ENTRY:
2106 {
2107 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2108 for (const auto &arg : method->args()) {
2109 out << "_hidl_args.push_back((void *)&"
2110 << arg->name()
2111 << ");\n";
2112 }
2113 break;
2114 }
2115 case PASSTHROUGH_EXIT:
2116 {
2117 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002118 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002119 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002120 << arg->name()
2121 << ");\n";
2122 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002123 break;
2124 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002125 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002126 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002127 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002128 return UNKNOWN_ERROR;
2129 }
2130 }
2131
Steven Moreland031ccf12016-10-31 15:54:38 -07002132 const Interface *iface = mRootScope->getInterface();
2133
Steven Moreland1ab31442016-11-03 18:37:51 -07002134 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002135 out.indent();
2136 out << "callback("
2137 << event_str
2138 << ", \""
2139 << mPackage.package()
2140 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002141 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002142 << "\", \""
2143 << iface->localName()
2144 << "\", \""
2145 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002146 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002147 out.unindent();
2148 out << "}\n";
2149 out.unindent();
Steven Moreland30b76e92017-06-02 18:52:24 -07002150 out << "}\n";
2151 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002152
2153 return OK;
2154}
2155
Andreas Huber881227d2016-08-02 14:20:21 -07002156} // namespace android