blob: 44e8017ea7b589b1cff3d8b3b8289ba7f1577ad8 [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"
Steven Morelandd281ebc2017-06-20 16:27:35 -0700229 << "const bool trebleTestingOverride = env && !strcmp(env, \"true\");\n"
230 << "const bool vintfLegacy = (transport == Transport::EMPTY) && trebleTestingOverride;\n"
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700231 << "#else // __ANDROID_TREBLE__ but not __ANDROID_DEBUGGABLE__\n"
Steven Morelandd281ebc2017-06-20 16:27:35 -0700232 << "const bool trebleTestingOverride = false;\n"
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700233 << "const bool vintfLegacy = false;\n"
234 << "#endif // __ANDROID_DEBUGGABLE__\n\n"
235 << "#else // not __ANDROID_TREBLE__\n"
Steven Moreland82472102017-06-26 09:40:37 -0700236 << "const char* env = std::getenv(\"TREBLE_TESTING_OVERRIDE\");\n"
237 << "const bool trebleTestingOverride = env && !strcmp(env, \"true\");\n"
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700238 << "const bool vintfLegacy = (transport == Transport::EMPTY);\n\n"
239 << "#endif // __ANDROID_TREBLE__\n\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000240
241 // if (getStub) {
242 // getPassthroughServiceManager()->get only once.
243 // } else {
244 // if (vintfHwbinder) {
245 // while (no alive service) {
Steven Moreland369d0532017-06-09 12:42:10 -0700246 // if (have already tried to get service)
247 // waitForHwService
Yifan Hong31f07ff2017-03-21 18:56:35 +0000248 // defaultServiceManager()->get
249 // }
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700250 // } else if (vintfLegacy) {
Yifan Hong31f07ff2017-03-21 18:56:35 +0000251 // defaultServiceManager()->get only once.
252 // getPassthroughServiceManager()->get only once.
253 // } else if (vintfPassthru) {
254 // getPassthroughServiceManager()->get only once.
255 // }
256 // }
257
Steven Moreland369d0532017-06-09 12:42:10 -0700258 out.sFor("int tries = 0; !getStub && (vintfHwbinder || (vintfLegacy && tries == 0)); tries++", [&] {
Steven Moreland038903b2017-03-30 12:11:24 -0700259 if (!isTry) {
Steven Moreland369d0532017-06-09 12:42:10 -0700260 out.sIf("tries > 1", [&] {
261 // sleep only after the first time we've called waitForHwService.
262 out << "ALOGI(\"" << functionName << ": Will do try %d for %s/%s in 1s...\", tries, "
263 << interfaceName << "::descriptor, serviceName.c_str());\n"
264 << "sleep(1);\n";
265 }).endl();
266
267 out.sIf("vintfHwbinder && tries > 0", [&] {
Steven Morelandbcf51802017-04-06 09:17:44 -0700268 out << "waitForHwService("
269 << interfaceName << "::descriptor, serviceName);\n";
Steven Moreland038903b2017-03-30 12:11:24 -0700270 }).endl();
271 }
Yifan Hong31f07ff2017-03-21 18:56:35 +0000272
Steven Morelandbcf51802017-04-06 09:17:44 -0700273 out << "Return<sp<" << gIBaseFqName.cppName() << ">> ret = \n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000274 out.indent(2, [&] {
275 out << "sm->get(" << interfaceName << "::descriptor, serviceName);\n";
276 });
277
278 out.sIf("!ret.isOk()", [&] {
Steven Moreland42394ce2017-03-27 17:03:04 -0700279 // hwservicemanager fails, may be security issue
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700280 out << "ALOGE(\"" << interfaceName << ": defaultServiceManager()->get returns %s\", "
Yifan Hong31f07ff2017-03-21 18:56:35 +0000281 << "ret.description().c_str());\n"
Steven Moreland42394ce2017-03-27 17:03:04 -0700282 << "break;\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000283 }).endl();
284
Steven Morelandbcf51802017-04-06 09:17:44 -0700285 out << "sp<" << gIBaseFqName.cppName() << "> base = ret;\n";
Yifan Hong200209c2017-03-29 03:39:09 -0700286 out.sIf("base == nullptr", [&] {
Steven Moreland369d0532017-06-09 12:42:10 -0700287 // if tries > 0: race condition. hwservicemanager drops the service
Yifan Hong200209c2017-03-29 03:39:09 -0700288 // from waitForHwService to here
Steven Moreland369d0532017-06-09 12:42:10 -0700289 out.sIf("tries > 0", [&] {
290 out << "ALOGW(\"" << interfaceName << ": found null hwbinder interface\");\n";
291 });
292 out << (isTry ? "break" : "continue")
Yifan Hong9c74a5b2017-04-04 13:27:25 -0700293 << ";\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000294 }).endl();
Steven Morelandbcf51802017-04-06 09:17:44 -0700295 out << "Return<sp<" << interfaceName
Yifan Hong200209c2017-03-29 03:39:09 -0700296 << ">> castRet = " << interfaceName << "::castFrom(base, true /* emitError */);\n";
297 out.sIf("!castRet.isOk()", [&] {
298 out.sIf("castRet.isDeadObject()", [&] {
299 // service is dead (castFrom cannot call interfaceChain)
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700300 out << "ALOGW(\"" << interfaceName << ": found dead hwbinder service\");\n"
Yifan Hong9c74a5b2017-04-04 13:27:25 -0700301 << (isTry ? "break" : "continue")
302 << ";\n";
Yifan Hong200209c2017-03-29 03:39:09 -0700303 }).sElse([&] {
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700304 out << "ALOGW(\"" << interfaceName << ": cannot call into hwbinder service: %s"
Yifan Hong200209c2017-03-29 03:39:09 -0700305 << "; No permission? Check for selinux denials.\", "
306 << "castRet.description().c_str());\n"
307 << "break;\n";
308 }).endl();
309 }).endl();
310 out << "iface = castRet;\n";
311 out.sIf("iface == nullptr", [&] {
312 // returned service isn't of correct type; this is a bug
313 // to hwservicemanager or to the service itself (interfaceChain
314 // is not consistent).
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700315 out << "ALOGW(\"" << interfaceName << ": received incompatible service; bug in hwservicemanager?\");\n"
Yifan Hong200209c2017-03-29 03:39:09 -0700316 << "break;\n";
317 }).endl();
Yifan Hong31f07ff2017-03-21 18:56:35 +0000318
319 out << "return iface;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800320 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800321
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700322 out.sIf("getStub || vintfPassthru || vintfLegacy", [&] {
Steven Morelandbcf51802017-04-06 09:17:44 -0700323 out << "const sp<::android::hidl::manager::V1_0::IServiceManager> pm"
324 << " = getPassthroughServiceManager();\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000325
326 out.sIf("pm != nullptr", [&] () {
Steven Morelandbcf51802017-04-06 09:17:44 -0700327 out << "Return<sp<" << gIBaseFqName.cppName() << ">> ret = \n";
Steven Morelandf10af872017-01-25 16:01:56 +0000328 out.indent(2, [&] {
329 out << "pm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
Steven Moreland2c2dea82017-01-18 17:24:17 -0800330 });
Steven Morelandf10af872017-01-25 16:01:56 +0000331 out.sIf("ret.isOk()", [&] {
Steven Morelandbcf51802017-04-06 09:17:44 -0700332 out << "sp<" << gIBaseFqName.cppName()
Steven Morelandf10af872017-01-25 16:01:56 +0000333 << "> baseInterface = ret;\n";
334 out.sIf("baseInterface != nullptr", [&]() {
Steven Morelandd281ebc2017-06-20 16:27:35 -0700335 out << "iface = " << interfaceName << "::castFrom(baseInterface);\n";
336 out.sIf("!getStub || trebleTestingOverride", [&] () {
337 out << "iface = new " << fqName.getInterfacePassthroughName() << "(iface);\n";
338 }).endl();
Yifan Hong31f07ff2017-03-21 18:56:35 +0000339 }).endl();
Steven Morelandf10af872017-01-25 16:01:56 +0000340 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800341 }).endl();
342 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800343
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800344 out << "return iface;\n";
345 }).endl().endl();
Steven Moreland038903b2017-03-30 12:11:24 -0700346}
347
348static void implementServiceManagerInteractions(Formatter &out,
349 const FQName &fqName, const std::string &package) {
350
351 const std::string interfaceName = fqName.getInterfaceName();
352
353 implementGetService(out, fqName, true /* isTry */);
354 implementGetService(out, fqName, false /* isTry */);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800355
Yifan Hongeefe4f22017-01-04 15:32:42 -0800356 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800357 << "const std::string &serviceName) ";
358 out.block([&] {
Steven Moreland58b478b2017-04-09 10:54:50 -0700359 out << "::android::hardware::details::onRegistration(\""
360 << fqName.getPackageAndVersion().string() << "\", \""
361 << interfaceName
362 << "\", serviceName);\n\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800363 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
364 out.indent(2, [&] {
365 out << "= ::android::hardware::defaultServiceManager();\n";
366 });
367 out.sIf("sm == nullptr", [&] {
368 out << "return ::android::INVALID_OPERATION;\n";
369 }).endl();
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100370 out << "::android::hardware::Return<bool> ret = "
371 << "sm->add(serviceName.c_str(), this);\n"
372 << "return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800373 }).endl().endl();
374
Yifan Hongeefe4f22017-01-04 15:32:42 -0800375 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800376 out.indent(2, [&] {
377 out << "const std::string &serviceName,\n"
378 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
379 << "&notification) ";
380 });
381 out.block([&] {
382 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
383 out.indent(2, [&] {
384 out << "= ::android::hardware::defaultServiceManager();\n";
385 });
386 out.sIf("sm == nullptr", [&] {
387 out << "return false;\n";
388 }).endl();
389 out << "::android::hardware::Return<bool> success =\n";
390 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800391 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800392 out.indent(2, [&] {
393 out << "serviceName, notification);\n";
394 });
395 });
396 out << "return success.isOk() && success;\n";
397 }).endl().endl();
398}
399
Andreas Huberb82318c2016-08-02 14:45:54 -0700400status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700401 const Interface *iface = getInterface();
402 std::string ifaceName = iface ? iface->localName() : "types";
Andreas Huber881227d2016-08-02 14:20:21 -0700403
Andreas Huberb82318c2016-08-02 14:45:54 -0700404 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700405 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700406 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700407 path.append(ifaceName);
408 path.append(".h");
409
Andreas Huberd2943e12016-08-05 11:59:31 -0700410 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700411 FILE *file = fopen(path.c_str(), "w");
412
413 if (file == NULL) {
414 return -errno;
415 }
416
417 Formatter out(file);
418
419 const std::string guard = makeHeaderGuard(ifaceName);
420
421 out << "#ifndef " << guard << "\n";
422 out << "#define " << guard << "\n\n";
423
Andreas Huber737080b2016-08-02 15:38:04 -0700424 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700425 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700426 }
427
428 if (!mImportedNames.empty()) {
429 out << "\n";
430 }
431
Steven Moreland19f11b52017-05-12 18:22:21 -0700432 if (iface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800433 if (isIBase()) {
434 out << "// skipped #include IServiceNotification.h\n\n";
435 } else {
436 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
437 }
Steven Moreland0693f312016-11-09 15:06:14 -0800438 }
439
Yifan Hongc8934042016-11-17 17:10:52 -0800440 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700441 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700442
Steven Moreland19f11b52017-05-12 18:22:21 -0700443 if (iface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200444 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700445 }
446
Martijn Coenenaf712c02016-11-16 15:26:27 +0100447 out << "#include <utils/NativeHandle.h>\n";
448 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700449
450 enterLeaveNamespace(out, true /* enter */);
451 out << "\n";
452
Steven Moreland19f11b52017-05-12 18:22:21 -0700453 if (iface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700454 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700455 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700456
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700457 const Interface *superType = iface->superType();
458
Steven Moreland40786312016-08-16 10:29:40 -0700459 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800460 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700461 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000462 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700463 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700464 }
465
466 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700467
468 out.indent();
469
Steven Moreland1a52e822017-07-27 13:56:29 -0700470 generateCppTag(out, "android::hardware::details::i_tag");
Andreas Huber881227d2016-08-02 14:20:21 -0700471 }
472
473 status_t err = emitTypeDeclarations(out);
474
475 if (err != OK) {
476 return err;
477 }
478
Steven Moreland19f11b52017-05-12 18:22:21 -0700479 if (iface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800480 out << "virtual bool isRemote() const ";
481 if (!isIBase()) {
482 out << "override ";
483 }
484 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800485
Steven Morelandf7f2a9a2017-07-21 18:05:38 -0700486 for (const auto& tuple : iface->allMethodsFromRoot()) {
487 const Method* method = tuple.method();
488
Andreas Huber881227d2016-08-02 14:20:21 -0700489 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700490
Andreas Huber881227d2016-08-02 14:20:21 -0700491 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800492 const TypedVar *elidedReturn = method->canElideCallback();
493
494 if (elidedReturn == nullptr && returnsValue) {
495 out << "using "
496 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700497 << "_cb = std::function<void(";
498 method->emitCppResultSignature(out, true /* specify namespaces */);
499 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800500 }
Andreas Huber881227d2016-08-02 14:20:21 -0700501
Andreas Huber3599d922016-08-09 10:42:57 -0700502 method->dumpAnnotations(out);
503
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700504 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700505 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700506 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700507 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700508 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700509 }
510
511 out << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700512 << "(";
513 method->emitCppArgSignature(out, true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700514
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700515 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700516 if (!method->args().empty()) {
517 out << ", ";
518 }
519
Steven Moreland67f67b42016-09-29 08:59:02 -0700520 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700521 }
522
Yifan Hong10fe0b52016-10-19 14:20:17 -0700523 out << ")";
524 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800525 if (!isIBase()) {
526 out << " override";
527 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700528 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700529 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700530 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700531 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700532 }
Steven Moreland40786312016-08-16 10:29:40 -0700533
Yifan Hong3d746092016-12-07 14:26:33 -0800534 out << "// cast static functions\n";
535 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700536
Yifan Hong3d746092016-12-07 14:26:33 -0800537 for (const Interface *superType : iface->typeChain()) {
Yifan Hong200209c2017-03-29 03:39:09 -0700538 out << "static ::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -0800539 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -0700540 << "> castFrom("
Yifan Hong3d746092016-12-07 14:26:33 -0800541 << superType->getCppArgumentType()
542 << " parent"
Yifan Hong200209c2017-03-29 03:39:09 -0700543 << ", bool emitError = false);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700544 }
545
Steven Morelandd39133b2016-11-11 12:30:08 -0800546 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700547
Yifan Hongc8934042016-11-17 17:10:52 -0800548 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800549 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800550 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800551 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800552 }
Andreas Huber881227d2016-08-02 14:20:21 -0700553 }
554
Steven Moreland19f11b52017-05-12 18:22:21 -0700555 if (iface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700556 out.unindent();
557
Andreas Hubere3f769a2016-10-10 10:54:44 -0700558 out << "};\n\n";
559 }
560
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700561 err = mRootScope.emitGlobalTypeDeclarations(out);
Andreas Hubere3f769a2016-10-10 10:54:44 -0700562
563 if (err != OK) {
564 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700565 }
566
567 out << "\n";
568 enterLeaveNamespace(out, false /* enter */);
569
570 out << "\n#endif // " << guard << "\n";
571
572 return OK;
573}
574
Steven Moreland40786312016-08-16 10:29:40 -0700575status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700576 const Interface *iface = getInterface();
577 std::string klassName = iface ? iface->getHwName() : "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700578
Steven Moreland40786312016-08-16 10:29:40 -0700579 std::string path = outputPath;
580 path.append(mCoordinator->convertPackageRootToPath(mPackage));
581 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
582 path.append(klassName + ".h");
583
Yifan Hong244e82d2016-11-11 11:13:57 -0800584 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700585
586 if (file == NULL) {
587 return -errno;
588 }
589
590 Formatter out(file);
591
592 const std::string guard = makeHeaderGuard(klassName);
593
594 out << "#ifndef " << guard << "\n";
595 out << "#define " << guard << "\n\n";
596
Steven Moreland19f11b52017-05-12 18:22:21 -0700597 generateCppPackageInclude(out, mPackage, iface ? iface->localName() : "types");
Steven Moreland40786312016-08-16 10:29:40 -0700598
Steven Morelandee88eed2016-10-31 17:49:00 -0700599 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700600
601 for (const auto &item : mImportedNames) {
602 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800603 generateCppPackageInclude(out, item, "hwtypes");
604 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800605 generateCppPackageInclude(out, item, item.getInterfaceStubName());
606 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700607 }
Steven Moreland40786312016-08-16 10:29:40 -0700608 }
609
610 out << "\n";
611
Martijn Coenen93915102016-09-01 01:35:52 +0200612 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700613 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100614 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700615
616 out << "\n";
617
618 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700619
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700620 status_t err = mRootScope.emitGlobalHwDeclarations(out);
Yifan Hong244e82d2016-11-11 11:13:57 -0800621 if (err != OK) {
622 return err;
623 }
Steven Moreland40786312016-08-16 10:29:40 -0700624
625 enterLeaveNamespace(out, false /* enter */);
626
627 out << "\n#endif // " << guard << "\n";
628
629 return OK;
630}
631
Andreas Huber881227d2016-08-02 14:20:21 -0700632status_t AST::emitTypeDeclarations(Formatter &out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700633 return mRootScope.emitTypeDeclarations(out);
Andreas Huber881227d2016-08-02 14:20:21 -0700634}
635
Yifan Hong7a118f52016-12-07 11:21:15 -0800636static void wrapPassthroughArg(Formatter &out,
637 const TypedVar *arg, bool addPrefixToName,
638 std::function<void(void)> handleError) {
639 if (!arg->type().isInterface()) {
640 return;
641 }
642 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
643 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
644 + arg->name();
645 const Interface &iface = static_cast<const Interface &>(arg->type());
646 out << iface.getCppStackType() << " " << wrappedName << ";\n";
647 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
648 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
649 out << wrappedName
650 << " = "
651 << iface.fqName().cppName()
Yifan Hong341112d2017-04-20 18:12:05 -0700652 << "::castFrom(::android::hardware::details::wrapPassthrough<"
653 << iface.fqName().cppName()
654 << ">("
Yifan Hong7a118f52016-12-07 11:21:15 -0800655 << name << "));\n";
656 out.sIf(wrappedName + " == nullptr", [&] {
657 // Fatal error. Happens when the BsFoo class is not found in the binary
658 // or any dynamic libraries.
659 handleError();
660 }).endl();
661 }).sElse([&] {
662 out << wrappedName << " = " << name << ";\n";
663 }).endl().endl();
664}
665
Steven Moreland69e7c702016-09-09 11:16:32 -0700666status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700667 const Method *method) const {
668 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700669
670 out << " {\n";
671 out.indent();
672
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800673 if (method->isHidlReserved()
674 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
675 method->cppImpl(IMPL_PASSTHROUGH, out);
676 out.unindent();
677 out << "}\n\n";
678 return OK;
679 }
680
Steven Moreland69e7c702016-09-09 11:16:32 -0700681 const bool returnsValue = !method->results().empty();
682 const TypedVar *elidedReturn = method->canElideCallback();
683
Steven Moreland67f67b42016-09-29 08:59:02 -0700684 if (returnsValue && elidedReturn == nullptr) {
685 generateCheckNonNull(out, "_hidl_cb");
686 }
687
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700688 generateCppInstrumentationCall(
689 out,
690 InstrumentationEvent::PASSTHROUGH_ENTRY,
691 method);
692
Yifan Hong7a118f52016-12-07 11:21:15 -0800693
694 for (const auto &arg : method->args()) {
695 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
696 out << "return ::android::hardware::Status::fromExceptionCode(\n";
697 out.indent(2, [&] {
698 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800699 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800700 });
701 });
702 }
703
704 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700705 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700706
707 if (method->isOneway()) {
Steven Moreland836cb312017-06-05 17:25:55 -0700708 out << "addOnewayTask([mImpl = this->mImpl\n"
709 << "#ifdef __ANDROID_DEBUGGABLE__\n"
710 ", mEnableInstrumentation = this->mEnableInstrumentation, "
711 "mInstrumentationCallbacks = this->mInstrumentationCallbacks\n"
712 << "#endif // __ANDROID_DEBUGGABLE__\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700713 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800714 out << ", "
715 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
716 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700717 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700718 out << "] {\n";
719 out.indent();
Steven Moreland69e7c702016-09-09 11:16:32 -0700720 }
721
722 out << "mImpl->"
723 << method->name()
724 << "(";
725
Yifan Hong932464e2017-03-30 15:40:22 -0700726 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800727 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700728 });
Steven Moreland69e7c702016-09-09 11:16:32 -0700729 if (returnsValue && elidedReturn == nullptr) {
Steven Moreland340c8822017-05-02 14:41:49 -0700730 // never true if oneway since oneway methods don't return values
731
Steven Moreland69e7c702016-09-09 11:16:32 -0700732 if (!method->args().empty()) {
733 out << ", ";
734 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800735 out << "[&](";
Yifan Hong932464e2017-03-30 15:40:22 -0700736 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800737 out << "const auto &_hidl_out_"
738 << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700739 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800740
741 out << ") {\n";
742 out.indent();
Steven Moreland92a08a72017-07-31 14:57:37 -0700743 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800744 out,
745 InstrumentationEvent::PASSTHROUGH_EXIT,
746 method);
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800747
Yifan Hong7a118f52016-12-07 11:21:15 -0800748 for (const auto &arg : method->results()) {
749 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
750 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
751 out.indent(2, [&] {
752 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800753 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800754 });
755 out << "return;\n";
756 });
757 }
758
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800759 out << "_hidl_cb(";
Yifan Hong932464e2017-03-30 15:40:22 -0700760 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800761 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
762 << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700763 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800764 out << ");\n";
765 out.unindent();
766 out << "});\n\n";
767 } else {
768 out << ");\n\n";
Steven Moreland30b76e92017-06-02 18:52:24 -0700769
770 // used by generateCppInstrumentationCall
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800771 if (elidedReturn != nullptr) {
Steven Moreland30b76e92017-06-02 18:52:24 -0700772 out << "#ifdef __ANDROID_DEBUGGABLE__\n"
773 << elidedReturn->type().getCppResultType() << " _hidl_out_" << elidedReturn->name()
774 << " = _hidl_return;\n"
775 << "#endif // __ANDROID_DEBUGGABLE__\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800776 }
Steven Moreland92a08a72017-07-31 14:57:37 -0700777 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800778 out,
779 InstrumentationEvent::PASSTHROUGH_EXIT,
780 method);
Steven Moreland69e7c702016-09-09 11:16:32 -0700781 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700782
783 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700784 out.unindent();
785 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700786 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700787
788 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700789
790 out.unindent();
791 out << "}\n";
792
793 return OK;
794}
795
Yifan Hong068c5522016-10-31 14:07:25 -0700796status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700797 const Interface* iface = mRootScope.getInterface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700798
Yifan Hong10fe0b52016-10-19 14:20:17 -0700799 const Interface *prevIterface = nullptr;
800 for (const auto &tuple : iface->allMethodsFromRoot()) {
801 const Method *method = tuple.method();
802 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700803
Yifan Hong10fe0b52016-10-19 14:20:17 -0700804 if(prevIterface != superInterface) {
805 if (prevIterface != nullptr) {
806 out << "\n";
807 }
808 out << "// Methods from "
809 << superInterface->fullName()
810 << " follow.\n";
811 prevIterface = superInterface;
812 }
Yifan Hong068c5522016-10-31 14:07:25 -0700813 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700814
Yifan Hong10fe0b52016-10-19 14:20:17 -0700815 if (err != OK) {
816 return err;
817 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700818 }
819
Yifan Hong10fe0b52016-10-19 14:20:17 -0700820 out << "\n";
821
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700822 return OK;
823}
824
Steven Moreland0b843772017-06-23 16:33:38 -0700825void AST::generateTemplatizationLink(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700826 out << "typedef " << mRootScope.getInterface()->localName() << " Pure;\n\n";
Steven Moreland0b843772017-06-23 16:33:38 -0700827}
828
Steven Moreland1a52e822017-07-27 13:56:29 -0700829void AST::generateCppTag(Formatter& out, const std::string& tag) const {
830 out << "typedef " << tag << " _hidl_tag;\n\n";
831}
832
Andreas Huberb82318c2016-08-02 14:45:54 -0700833status_t AST::generateStubHeader(const std::string &outputPath) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700834 if (!AST::isInterface()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700835 // types.hal does not get a stub header.
836 return OK;
837 }
838
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700839 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800840 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700841
Andreas Huberb82318c2016-08-02 14:45:54 -0700842 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700843 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700844 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700845 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700846 path.append(".h");
847
Andreas Huberd2943e12016-08-05 11:59:31 -0700848 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700849 FILE *file = fopen(path.c_str(), "w");
850
851 if (file == NULL) {
852 return -errno;
853 }
854
855 Formatter out(file);
856
Steven Moreland40786312016-08-16 10:29:40 -0700857 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700858
859 out << "#ifndef " << guard << "\n";
860 out << "#define " << guard << "\n\n";
861
Yifan Hongeefe4f22017-01-04 15:32:42 -0800862 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Moreland1a52e822017-07-27 13:56:29 -0700863
Steven Morelandee88eed2016-10-31 17:49:00 -0700864 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700865
866 enterLeaveNamespace(out, true /* enter */);
867 out << "\n";
868
869 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800870 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100871 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800872 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000873 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100874 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800875 out << " : public "
876 << gIBaseFqName.getInterfaceStubFqName().cppName()
877 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100878 }
Andreas Huber881227d2016-08-02 14:20:21 -0700879
880 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800881 out << "explicit "
882 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -0700883 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100884 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800885 out << "explicit "
886 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -0700887 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800888 << " const std::string& HidlInstrumentor_package,"
889 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700890 << "\n\n";
Steven Moreland57a89362017-07-21 19:29:54 +0000891 out << "virtual ~" << klassName << "();\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700892 out << "::android::status_t onTransact(\n";
893 out.indent();
894 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700895 out << "uint32_t _hidl_code,\n";
896 out << "const ::android::hardware::Parcel &_hidl_data,\n";
897 out << "::android::hardware::Parcel *_hidl_reply,\n";
898 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700899 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700900 out.unindent();
901 out.unindent();
902
Steven Moreland0b843772017-06-23 16:33:38 -0700903 out.endl();
904 generateTemplatizationLink(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700905 generateCppTag(out, "android::hardware::details::bnhw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700906
Steven Moreland19f11b52017-05-12 18:22:21 -0700907 out << "::android::sp<" << iface->localName() << "> getImpl() { return _hidl_mImpl; };\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100908 out.unindent();
909 out << "private:\n";
910 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800911
912 status_t err = generateMethods(out, [&](const Method *method, const Interface *iface) {
913 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
914 return OK;
915 }
916 const bool returnsValue = !method->results().empty();
917 const TypedVar *elidedReturn = method->canElideCallback();
918
919 if (elidedReturn == nullptr && returnsValue) {
920 out << "using " << method->name() << "_cb = "
921 << iface->fqName().cppName()
922 << "::" << method->name() << "_cb;\n";
923 }
924 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800925 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800926 return OK;
927 });
928 if (err != OK) {
929 return err;
930 }
931
Steven Moreland19f11b52017-05-12 18:22:21 -0700932 out << "::android::sp<" << iface->localName() << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700933 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700934 out << "};\n\n";
935
936 enterLeaveNamespace(out, false /* enter */);
937
938 out << "\n#endif // " << guard << "\n";
939
940 return OK;
941}
942
Andreas Huberb82318c2016-08-02 14:45:54 -0700943status_t AST::generateProxyHeader(const std::string &outputPath) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700944 if (!AST::isInterface()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700945 // types.hal does not get a proxy header.
946 return OK;
947 }
948
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700949 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800950 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700951
Andreas Huberb82318c2016-08-02 14:45:54 -0700952 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700953 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700954 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800955 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700956 path.append(".h");
957
Andreas Huberd2943e12016-08-05 11:59:31 -0700958 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700959 FILE *file = fopen(path.c_str(), "w");
960
961 if (file == NULL) {
962 return -errno;
963 }
964
965 Formatter out(file);
966
Yifan Hongeefe4f22017-01-04 15:32:42 -0800967 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700968
969 out << "#ifndef " << guard << "\n";
970 out << "#define " << guard << "\n\n";
971
Martijn Coenen115d4282016-12-19 05:14:04 +0100972 out << "#include <hidl/HidlTransportSupport.h>\n\n";
973
Andreas Huber881227d2016-08-02 14:20:21 -0700974 std::vector<std::string> packageComponents;
975 getPackageAndVersionComponents(
976 &packageComponents, false /* cpp_compatible */);
977
Yifan Hongeefe4f22017-01-04 15:32:42 -0800978 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700979 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700980
981 enterLeaveNamespace(out, true /* enter */);
982 out << "\n";
983
984 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800985 << proxyName
986 << " : public ::android::hardware::BpInterface<"
987 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000988 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700989
990 out.indent();
991
Yifan Hongeefe4f22017-01-04 15:32:42 -0800992 out << "explicit "
993 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700994 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700995 << "\n\n";
996
Steven Moreland0b843772017-06-23 16:33:38 -0700997 generateTemplatizationLink(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700998 generateCppTag(out, "android::hardware::details::bphw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700999
Yifan Hong10fe0b52016-10-19 14:20:17 -07001000 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -07001001
Yifan Hong068c5522016-10-31 14:07:25 -07001002 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1003 method->generateCppSignature(out);
1004 out << " override;\n";
1005 return OK;
1006 });
Steven Moreland9c387612016-09-07 09:54:26 -07001007
1008 if (err != OK) {
1009 return err;
1010 }
Andreas Huber881227d2016-08-02 14:20:21 -07001011
1012 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +01001013 out << "private:\n";
1014 out.indent();
1015 out << "std::mutex _hidl_mMutex;\n"
1016 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
1017 << " _hidl_mDeathRecipients;\n";
1018 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -07001019 out << "};\n\n";
1020
1021 enterLeaveNamespace(out, false /* enter */);
1022
1023 out << "\n#endif // " << guard << "\n";
1024
1025 return OK;
1026}
1027
Steven Moreland1cbf0362017-05-09 14:32:53 -07001028status_t AST::generateCppSources(const std::string &outputPath) const {
Steven Moreland19f11b52017-05-12 18:22:21 -07001029 std::string baseName = getBaseName();
1030 const Interface *iface = getInterface();
Andreas Huber881227d2016-08-02 14:20:21 -07001031
Andreas Huberb82318c2016-08-02 14:45:54 -07001032 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -07001033 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -07001034 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -07001035 path.append(baseName);
1036
1037 if (baseName != "types") {
1038 path.append("All");
1039 }
1040
1041 path.append(".cpp");
1042
Andreas Huberd2943e12016-08-05 11:59:31 -07001043 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -07001044 FILE *file = fopen(path.c_str(), "w");
1045
1046 if (file == NULL) {
1047 return -errno;
1048 }
1049
1050 Formatter out(file);
1051
Steven Moreland623c0042017-01-13 14:42:29 -08001052 out << "#define LOG_TAG \""
1053 << mPackage.string() << "::" << baseName
1054 << "\"\n\n";
1055
Steven Moreland05cd4232016-11-21 16:01:12 -08001056 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001057 out << "#include <cutils/trace.h>\n";
1058 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Steven Moreland19f11b52017-05-12 18:22:21 -07001059 if (iface) {
Steven Moreland19d5c172016-10-20 19:20:25 -07001060 // This is a no-op for IServiceManager itself.
1061 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
1062
Yifan Hongeefe4f22017-01-04 15:32:42 -08001063 generateCppPackageInclude(out, mPackage, iface->getProxyName());
1064 generateCppPackageInclude(out, mPackage, iface->getStubName());
1065 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001066
1067 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -07001068 generateCppPackageInclude(out,
1069 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -08001070 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001071 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -08001072
1073 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001074 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -07001075 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -08001076 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -07001077 }
1078
1079 out << "\n";
1080
1081 enterLeaveNamespace(out, true /* enter */);
1082 out << "\n";
1083
Steven Moreland19f11b52017-05-12 18:22:21 -07001084 status_t err = generateTypeSource(out, iface ? iface->localName() : "");
Andreas Huber881227d2016-08-02 14:20:21 -07001085
Steven Moreland19f11b52017-05-12 18:22:21 -07001086 if (err == OK && iface) {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001087 const Interface* iface = mRootScope.getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001088
1089 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -08001090 out << "const char* "
1091 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -07001092 << "::descriptor(\""
1093 << iface->fqName().string()
1094 << "\");\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +01001095 out << "__attribute__((constructor))";
1096 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001097 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001098 out << "::android::hardware::details::gBnConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001099 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001100 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001101 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001102 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001103 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001104 out << "return new "
1105 << iface->getStubName()
Yifan Hong341112d2017-04-20 18:12:05 -07001106 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001107 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001108 << " *>(iIntf));\n";
1109 });
Yifan Hongb04de382017-02-06 15:31:52 -08001110 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001111 });
Yifan Honga159f3b2017-03-16 14:53:51 -07001112 out << "::android::hardware::details::gBsConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001113 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001114 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001115 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001116 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -08001117 << gIBaseFqName.cppName()
1118 << "> {\n";
1119 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001120 out << "return new "
1121 << iface->getPassthroughName()
Yifan Hong341112d2017-04-20 18:12:05 -07001122 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001123 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001124 << " *>(iIntf));\n";
1125 });
Yifan Hongb04de382017-02-06 15:31:52 -08001126 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001127 });
Yifan Hong158655a2016-11-08 12:34:07 -08001128 });
Martijn Coenen8adcb652017-02-03 17:37:36 +01001129 out << "};\n\n";
1130 out << "__attribute__((destructor))";
1131 out << "static void static_destructor() {\n";
1132 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001133 out << "::android::hardware::details::gBnConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001134 << iface->localName()
1135 << "::descriptor);\n";
Yifan Honga159f3b2017-03-16 14:53:51 -07001136 out << "::android::hardware::details::gBsConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001137 << iface->localName()
1138 << "::descriptor);\n";
1139 });
1140 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001141
Yifan Hongfe95aa22016-10-19 17:26:45 -07001142 err = generateInterfaceSource(out);
1143 }
1144
Steven Moreland19f11b52017-05-12 18:22:21 -07001145 if (err == OK && iface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001146 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001147 }
1148
Steven Moreland19f11b52017-05-12 18:22:21 -07001149 if (err == OK && iface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001150 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001151 }
1152
Steven Moreland19f11b52017-05-12 18:22:21 -07001153 if (err == OK && iface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001154 err = generatePassthroughSource(out);
1155 }
1156
Steven Moreland19f11b52017-05-12 18:22:21 -07001157 if (err == OK && iface) {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001158 const Interface* iface = mRootScope.getInterface();
Steven Moreland9c387612016-09-07 09:54:26 -07001159
Yifan Hongc8934042016-11-17 17:10:52 -08001160 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001161 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001162 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001163 std::string package = iface->fqName().package()
1164 + iface->fqName().atVersion();
1165
Yifan Hongeefe4f22017-01-04 15:32:42 -08001166 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001167 }
Steven Moreland40786312016-08-16 10:29:40 -07001168 }
1169
Andreas Huber6755e9d2017-04-06 11:09:07 -07001170 HidlTypeAssertion::EmitAll(out);
1171 out << "\n";
1172
Andreas Huber881227d2016-08-02 14:20:21 -07001173 enterLeaveNamespace(out, false /* enter */);
1174
1175 return err;
1176}
1177
Steven Moreland67f67b42016-09-29 08:59:02 -07001178void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001179 out.sIf(nonNull + " == nullptr", [&] {
1180 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1181 out.indent(2, [&] {
Steven Moreland610002f2017-06-16 13:02:49 -07001182 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT,\n"
1183 << "\"Null synchronous callback passed.\");\n";
Yifan Honga018ed52016-12-13 16:35:08 -08001184 });
1185 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001186}
1187
Andreas Huber881227d2016-08-02 14:20:21 -07001188status_t AST::generateTypeSource(
1189 Formatter &out, const std::string &ifaceName) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001190 return mRootScope.emitTypeDefinitions(out, ifaceName);
Andreas Huber881227d2016-08-02 14:20:21 -07001191}
1192
Andreas Hubere7ff2282016-08-16 13:50:03 -07001193void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001194 Formatter &out,
1195 const std::vector<TypedVar *> &args,
1196 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001197 if (args.empty()) {
1198 return;
1199 }
1200
1201 for (const auto &arg : args) {
1202 const Type &type = arg->type();
1203
Yifan Hong3b320f82016-11-01 15:15:54 -07001204 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001205 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001206 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001207 << ";\n";
1208 }
1209
1210 out << "\n";
1211}
1212
Andreas Huber881227d2016-08-02 14:20:21 -07001213void AST::emitCppReaderWriter(
1214 Formatter &out,
1215 const std::string &parcelObj,
1216 bool parcelObjIsPointer,
1217 const TypedVar *arg,
1218 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001219 Type::ErrorMode mode,
1220 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001221 const Type &type = arg->type();
1222
Andreas Huber881227d2016-08-02 14:20:21 -07001223 type.emitReaderWriter(
1224 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001225 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001226 parcelObj,
1227 parcelObjIsPointer,
1228 isReader,
1229 mode);
1230}
1231
Yifan Hongbf459bc2016-08-23 16:50:37 -07001232void AST::emitCppResolveReferences(
1233 Formatter &out,
1234 const std::string &parcelObj,
1235 bool parcelObjIsPointer,
1236 const TypedVar *arg,
1237 bool isReader,
1238 Type::ErrorMode mode,
1239 bool addPrefixToName) const {
1240 const Type &type = arg->type();
1241 if(type.needsResolveReferences()) {
1242 type.emitResolveReferences(
1243 out,
1244 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1245 isReader, // nameIsPointer
1246 parcelObj,
1247 parcelObjIsPointer,
1248 isReader,
1249 mode);
1250 }
1251}
1252
Yifan Hong068c5522016-10-31 14:07:25 -07001253status_t AST::generateProxyMethodSource(Formatter &out,
1254 const std::string &klassName,
1255 const Method *method,
1256 const Interface *superInterface) const {
1257
1258 method->generateCppSignature(out,
1259 klassName,
1260 true /* specify namespaces */);
1261
1262 const bool returnsValue = !method->results().empty();
1263 const TypedVar *elidedReturn = method->canElideCallback();
1264
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001265 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001266
1267 out.indent();
1268
Martijn Coenen115d4282016-12-19 05:14:04 +01001269 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1270 method->cppImpl(IMPL_PROXY, out);
1271 out.unindent();
1272 out << "}\n\n";
1273 return OK;
1274 }
1275
Yifan Hong068c5522016-10-31 14:07:25 -07001276 if (returnsValue && elidedReturn == nullptr) {
1277 generateCheckNonNull(out, "_hidl_cb");
1278 }
1279
Steven Moreland92a08a72017-07-31 14:57:37 -07001280 generateCppInstrumentationCall(
Yifan Hong068c5522016-10-31 14:07:25 -07001281 out,
1282 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001283 method);
Yifan Hong068c5522016-10-31 14:07:25 -07001284
1285 out << "::android::hardware::Parcel _hidl_data;\n";
1286 out << "::android::hardware::Parcel _hidl_reply;\n";
1287 out << "::android::status_t _hidl_err;\n";
1288 out << "::android::hardware::Status _hidl_status;\n\n";
1289
1290 declareCppReaderLocals(
1291 out, method->results(), true /* forResults */);
1292
1293 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001294 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001295 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001296 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1297
Martijn Coenenfff73352017-01-04 16:36:31 +01001298 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001299 // First DFS: write all buffers and resolve pointers for parent
1300 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001301 if (arg->type().isInterface()) {
1302 hasInterfaceArgument = true;
1303 }
Yifan Hong068c5522016-10-31 14:07:25 -07001304 emitCppReaderWriter(
1305 out,
1306 "_hidl_data",
1307 false /* parcelObjIsPointer */,
1308 arg,
1309 false /* reader */,
1310 Type::ErrorMode_Goto,
1311 false /* addPrefixToName */);
1312 }
1313
1314 // Second DFS: resolve references.
1315 for (const auto &arg : method->args()) {
1316 emitCppResolveReferences(
1317 out,
1318 "_hidl_data",
1319 false /* parcelObjIsPointer */,
1320 arg,
1321 false /* reader */,
1322 Type::ErrorMode_Goto,
1323 false /* addPrefixToName */);
1324 }
1325
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001326 if (hasInterfaceArgument) {
1327 // Start binder threadpool to handle incoming transactions
1328 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1329 }
Yifan Hong068c5522016-10-31 14:07:25 -07001330 out << "_hidl_err = remote()->transact("
1331 << method->getSerialId()
1332 << " /* "
1333 << method->name()
1334 << " */, _hidl_data, &_hidl_reply";
1335
1336 if (method->isOneway()) {
1337 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1338 }
1339 out << ");\n";
1340
1341 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1342
1343 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001344 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001345 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1346 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1347
1348
1349 // First DFS: write all buffers and resolve pointers for parent
1350 for (const auto &arg : method->results()) {
1351 emitCppReaderWriter(
1352 out,
1353 "_hidl_reply",
1354 false /* parcelObjIsPointer */,
1355 arg,
1356 true /* reader */,
1357 Type::ErrorMode_Goto,
1358 true /* addPrefixToName */);
1359 }
1360
1361 // Second DFS: resolve references.
1362 for (const auto &arg : method->results()) {
1363 emitCppResolveReferences(
1364 out,
1365 "_hidl_reply",
1366 false /* parcelObjIsPointer */,
1367 arg,
1368 true /* reader */,
1369 Type::ErrorMode_Goto,
1370 true /* addPrefixToName */);
1371 }
1372
1373 if (returnsValue && elidedReturn == nullptr) {
1374 out << "_hidl_cb(";
1375
Yifan Hong932464e2017-03-30 15:40:22 -07001376 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001377 if (arg->type().resultNeedsDeref()) {
1378 out << "*";
1379 }
1380 out << "_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001381 });
Yifan Hong068c5522016-10-31 14:07:25 -07001382
1383 out << ");\n\n";
1384 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001385 }
Steven Moreland92a08a72017-07-31 14:57:37 -07001386 generateCppInstrumentationCall(
Martijn Coenen7b295242016-11-04 16:52:56 +01001387 out,
1388 InstrumentationEvent::CLIENT_API_EXIT,
1389 method);
Yifan Hong068c5522016-10-31 14:07:25 -07001390
1391 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001392 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1393 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001394 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001395 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1396 } else {
1397 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1398 out << "return ::android::hardware::Return<void>();\n\n";
1399 }
1400
1401 out.unindent();
1402 out << "_hidl_error:\n";
1403 out.indent();
1404 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1405 out << "return ::android::hardware::Return<";
1406 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001407 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001408 } else {
1409 out << "void";
1410 }
1411 out << ">(_hidl_status);\n";
1412
1413 out.unindent();
1414 out << "}\n\n";
1415 return OK;
1416}
1417
Andreas Huber881227d2016-08-02 14:20:21 -07001418status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001419 Formatter &out, const FQName &fqName) const {
1420 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001421
1422 out << klassName
1423 << "::"
1424 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001425 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001426
1427 out.indent();
1428 out.indent();
1429
1430 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001431 << "<"
1432 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001433 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001434 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001435 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001436 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001437 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001438 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001439
Andreas Huber881227d2016-08-02 14:20:21 -07001440 out.unindent();
1441 out.unindent();
1442 out << "}\n\n";
1443
Yifan Hong068c5522016-10-31 14:07:25 -07001444 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1445 return generateProxyMethodSource(out, klassName, method, superInterface);
1446 });
Andreas Huber881227d2016-08-02 14:20:21 -07001447
Yifan Hong068c5522016-10-31 14:07:25 -07001448 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001449}
1450
1451status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001452 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001453 const Interface *iface) const {
1454 const std::string interfaceName = iface->localName();
1455 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001456
Steven Moreland40786312016-08-16 10:29:40 -07001457 out << klassName
1458 << "::"
1459 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001460 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001461
1462 out.indent();
1463 out.indent();
1464
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001465 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001466 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001467 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001468 out << ": "
1469 << gIBaseFqName.getInterfaceStubFqName().cppName()
1470 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001471 }
1472
1473 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001474 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001475 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001476 << "\") { \n";
1477 out.indent();
1478 out << "_hidl_mImpl = _hidl_impl;\n";
Martijn Coenenb4d77952017-05-03 13:44:29 -07001479 out << "auto prio = ::android::hardware::details::gServicePrioMap.get("
1480 << "_hidl_impl, {SCHED_NORMAL, 0});\n";
1481 out << "mSchedPolicy = prio.sched_policy;\n";
1482 out << "mSchedPriority = prio.prio;\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001483 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001484
1485 out.unindent();
1486 out.unindent();
1487 out << "}\n\n";
1488
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001489 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001490 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001491 // class properly.
1492 out << klassName
1493 << "::"
1494 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001495 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1496 << " const std::string &HidlInstrumentor_package,"
1497 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001498
1499 out.indent();
1500 out.indent();
1501
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001502 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001503 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001504 out.indent();
1505 out << "_hidl_mImpl = _hidl_impl;\n";
1506 out.unindent();
1507
1508 out.unindent();
1509 out.unindent();
1510 out << "}\n\n";
1511 }
1512
Steven Moreland57a89362017-07-21 19:29:54 +00001513 out << klassName << "::~" << klassName << "() ";
1514 out.block([&]() {
Martijn Coenence6fd192017-07-27 13:24:34 +02001515 out << "::android::hardware::details::gBnMap.eraseIfEqual(_hidl_mImpl.get(), this);\n";
Steven Moreland57a89362017-07-21 19:29:54 +00001516 }).endl().endl();
1517
Yifan Hongbcffce22017-02-01 15:52:06 -08001518 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1519 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1520 return OK;
1521 }
1522 method->generateCppSignature(out, iface->getStubName());
1523 out << " ";
1524 out.block([&] {
1525 method->cppImpl(IMPL_STUB_IMPL, out);
1526 }).endl();
1527 return OK;
1528 });
Steven Moreland60818632017-02-04 00:33:42 -08001529 if (err != OK) {
1530 return err;
1531 }
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001532
Andreas Huber881227d2016-08-02 14:20:21 -07001533 out << "::android::status_t " << klassName << "::onTransact(\n";
1534
1535 out.indent();
1536 out.indent();
1537
Iliyan Malchev549e2592016-08-10 08:59:12 -07001538 out << "uint32_t _hidl_code,\n"
1539 << "const ::android::hardware::Parcel &_hidl_data,\n"
1540 << "::android::hardware::Parcel *_hidl_reply,\n"
1541 << "uint32_t _hidl_flags,\n"
1542 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001543
1544 out.unindent();
1545
Iliyan Malchev549e2592016-08-10 08:59:12 -07001546 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001547 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001548 out.indent();
1549
Yifan Hong10fe0b52016-10-19 14:20:17 -07001550 for (const auto &tuple : iface->allMethodsFromRoot()) {
1551 const Method *method = tuple.method();
1552 const Interface *superInterface = tuple.interface();
1553 out << "case "
1554 << method->getSerialId()
1555 << " /* "
1556 << method->name()
1557 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001558
Yifan Hong10fe0b52016-10-19 14:20:17 -07001559 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001560
Yifan Hong10fe0b52016-10-19 14:20:17 -07001561 status_t err =
1562 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001563
Yifan Hong10fe0b52016-10-19 14:20:17 -07001564 if (err != OK) {
1565 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001566 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001567
1568 out.unindent();
1569 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001570 }
1571
1572 out << "default:\n{\n";
1573 out.indent();
1574
Martijn Coenen225bc922017-06-27 14:39:46 -07001575 if (iface->isIBase()) {
1576 out << "(void)_hidl_flags;\n";
1577 out << "return ::android::UNKNOWN_TRANSACTION;\n";
1578 } else {
1579 out << "return ";
1580 out << gIBaseFqName.getInterfaceStubFqName().cppName();
1581 out << "::onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001582
Martijn Coenen225bc922017-06-27 14:39:46 -07001583 out.indent();
1584 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001585
Martijn Coenen225bc922017-06-27 14:39:46 -07001586 out << "_hidl_code, _hidl_data, _hidl_reply, "
1587 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001588
Martijn Coenen225bc922017-06-27 14:39:46 -07001589 out.unindent();
1590 out.unindent();
1591 }
Andreas Huber881227d2016-08-02 14:20:21 -07001592
1593 out.unindent();
1594 out << "}\n";
1595
1596 out.unindent();
1597 out << "}\n\n";
1598
Yifan Honga018ed52016-12-13 16:35:08 -08001599 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1600 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1601 out.indent(2, [&] {
1602 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1603 out << "_hidl_reply);\n";
1604 });
1605 });
Andreas Huber881227d2016-08-02 14:20:21 -07001606
Iliyan Malchev549e2592016-08-10 08:59:12 -07001607 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001608
1609 out.unindent();
1610 out << "}\n\n";
1611
1612 return OK;
1613}
1614
1615status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001616 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001617 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1618 method->cppImpl(IMPL_STUB, out);
1619 out << "break;\n";
1620 return OK;
1621 }
1622
Yifan Hongeefe4f22017-01-04 15:32:42 -08001623 out << "if (!_hidl_data.enforceInterface("
1624 << iface->fullName()
1625 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001626
Andreas Huber881227d2016-08-02 14:20:21 -07001627 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001628 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001629 out << "break;\n";
1630 out.unindent();
1631 out << "}\n\n";
1632
Andreas Huber5e44a292016-09-27 14:52:39 -07001633 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001634
Yifan Hongbf459bc2016-08-23 16:50:37 -07001635 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001636 for (const auto &arg : method->args()) {
1637 emitCppReaderWriter(
1638 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001639 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001640 false /* parcelObjIsPointer */,
1641 arg,
1642 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001643 Type::ErrorMode_Break,
1644 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001645 }
1646
Yifan Hongbf459bc2016-08-23 16:50:37 -07001647 // Second DFS: resolve references
1648 for (const auto &arg : method->args()) {
1649 emitCppResolveReferences(
1650 out,
1651 "_hidl_data",
1652 false /* parcelObjIsPointer */,
1653 arg,
1654 true /* reader */,
1655 Type::ErrorMode_Break,
1656 false /* addPrefixToName */);
1657 }
1658
Steven Moreland92a08a72017-07-31 14:57:37 -07001659 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001660 out,
1661 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001662 method);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001663
Andreas Huber881227d2016-08-02 14:20:21 -07001664 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001665 const TypedVar *elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -08001666 const std::string callee =
1667 (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL))
1668 ? "this" : "_hidl_mImpl";
Andreas Huber881227d2016-08-02 14:20:21 -07001669
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001670 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001671 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001672 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001673 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001674 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001675 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001676 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001677
Yifan Hong932464e2017-03-30 15:40:22 -07001678 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001679 if (arg->type().resultNeedsDeref()) {
1680 out << "*";
1681 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001682 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001683 });
Andreas Huber881227d2016-08-02 14:20:21 -07001684
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001685 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001686 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1687 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001688
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001689 elidedReturn->type().emitReaderWriter(
1690 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001691 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001692 "_hidl_reply",
1693 true, /* parcelObjIsPointer */
1694 false, /* isReader */
1695 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001696
Yifan Hongbf459bc2016-08-23 16:50:37 -07001697 emitCppResolveReferences(
1698 out,
1699 "_hidl_reply",
1700 true /* parcelObjIsPointer */,
1701 elidedReturn,
1702 false /* reader */,
1703 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001704 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001705
Steven Moreland92a08a72017-07-31 14:57:37 -07001706 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001707 out,
1708 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001709 method);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001710
Iliyan Malchev549e2592016-08-10 08:59:12 -07001711 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001712 } else {
1713 if (returnsValue) {
1714 out << "bool _hidl_callbackCalled = false;\n\n";
1715 }
Andreas Huber881227d2016-08-02 14:20:21 -07001716
Yifan Hongcd2ae452017-01-31 14:33:40 -08001717 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001718
Yifan Hong932464e2017-03-30 15:40:22 -07001719 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001720 if (arg->type().resultNeedsDeref()) {
1721 out << "*";
1722 }
1723
1724 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001725 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001726
1727 if (returnsValue) {
Yifan Hong932464e2017-03-30 15:40:22 -07001728 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001729 out << ", ";
1730 }
1731
1732 out << "[&](";
1733
Yifan Hong932464e2017-03-30 15:40:22 -07001734 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001735 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001736 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001737
1738 out << ") {\n";
1739 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001740 out << "if (_hidl_callbackCalled) {\n";
1741 out.indent();
1742 out << "LOG_ALWAYS_FATAL(\""
1743 << method->name()
1744 << ": _hidl_cb called a second time, but must be called once.\");\n";
1745 out.unindent();
1746 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001747 out << "_hidl_callbackCalled = true;\n\n";
1748
Yifan Hong859e53f2016-11-14 19:08:24 -08001749 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1750 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001751
Yifan Hongbf459bc2016-08-23 16:50:37 -07001752 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001753 for (const auto &arg : method->results()) {
1754 emitCppReaderWriter(
1755 out,
1756 "_hidl_reply",
1757 true /* parcelObjIsPointer */,
1758 arg,
1759 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001760 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001761 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001762 }
1763
Yifan Hongbf459bc2016-08-23 16:50:37 -07001764 // Second DFS: resolve references
1765 for (const auto &arg : method->results()) {
1766 emitCppResolveReferences(
1767 out,
1768 "_hidl_reply",
1769 true /* parcelObjIsPointer */,
1770 arg,
1771 false /* reader */,
1772 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001773 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001774 }
1775
Steven Moreland92a08a72017-07-31 14:57:37 -07001776 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001777 out,
1778 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001779 method);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001780
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001781 out << "_hidl_cb(*_hidl_reply);\n";
1782
1783 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001784 out << "});\n\n";
1785 } else {
1786 out << ");\n\n";
Steven Moreland92a08a72017-07-31 14:57:37 -07001787 generateCppInstrumentationCall(
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001788 out,
1789 InstrumentationEvent::SERVER_API_EXIT,
1790 method);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001791 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001792
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001793 if (returnsValue) {
1794 out << "if (!_hidl_callbackCalled) {\n";
1795 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001796 out << "LOG_ALWAYS_FATAL(\""
1797 << method->name()
1798 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001799 out.unindent();
1800 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001801 } else {
1802 out << "::android::hardware::writeToParcel("
1803 << "::android::hardware::Status::ok(), "
1804 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001805 }
Andreas Huber881227d2016-08-02 14:20:21 -07001806 }
1807
1808 out << "break;\n";
1809
1810 return OK;
1811}
1812
Steven Moreland69e7c702016-09-09 11:16:32 -07001813status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
Steven Moreland19f11b52017-05-12 18:22:21 -07001814 if (!AST::isInterface()) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001815 // types.hal does not get a stub header.
1816 return OK;
1817 }
1818
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001819 const Interface* iface = mRootScope.getInterface();
Steven Moreland19f11b52017-05-12 18:22:21 -07001820 CHECK(iface != nullptr);
Steven Moreland69e7c702016-09-09 11:16:32 -07001821
Yifan Hongeefe4f22017-01-04 15:32:42 -08001822 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001823
1824 bool supportOneway = iface->hasOnewayMethods();
1825
1826 std::string path = outputPath;
1827 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1828 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1829 path.append(klassName);
1830 path.append(".h");
1831
1832 CHECK(Coordinator::MakeParentHierarchy(path));
1833 FILE *file = fopen(path.c_str(), "w");
1834
1835 if (file == NULL) {
1836 return -errno;
1837 }
1838
1839 Formatter out(file);
1840
1841 const std::string guard = makeHeaderGuard(klassName);
1842
1843 out << "#ifndef " << guard << "\n";
1844 out << "#define " << guard << "\n\n";
1845
1846 std::vector<std::string> packageComponents;
1847 getPackageAndVersionComponents(
1848 &packageComponents, false /* cpp_compatible */);
1849
Steven Moreland61d3f4b2017-04-28 17:30:38 -07001850 out << "#include <android-base/macros.h>\n";
Yifan Hongb0949432016-12-15 15:32:24 -08001851 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001852 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001853
Steven Moreland19f11b52017-05-12 18:22:21 -07001854 generateCppPackageInclude(out, mPackage, iface->localName());
Steven Morelandee88eed2016-10-31 17:49:00 -07001855 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001856
Yifan Hong7a118f52016-12-07 11:21:15 -08001857 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001858 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001859 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001860 }
1861
1862 enterLeaveNamespace(out, true /* enter */);
1863 out << "\n";
1864
1865 out << "struct "
1866 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -07001867 << " : " << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001868 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001869
1870 out.indent();
1871 out << "explicit "
1872 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001873 << "(const ::android::sp<"
Steven Moreland19f11b52017-05-12 18:22:21 -07001874 << iface->localName()
Steven Moreland69e7c702016-09-09 11:16:32 -07001875 << "> impl);\n";
1876
Steven Moreland0b843772017-06-23 16:33:38 -07001877 out.endl();
1878 generateTemplatizationLink(out);
Steven Moreland1a52e822017-07-27 13:56:29 -07001879 generateCppTag(out, "android::hardware::details::bs_tag");
Steven Moreland0b843772017-06-23 16:33:38 -07001880
Yifan Hong068c5522016-10-31 14:07:25 -07001881 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1882 return generatePassthroughMethod(out, method);
1883 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001884
1885 if (err != OK) {
1886 return err;
1887 }
1888
1889 out.unindent();
1890 out << "private:\n";
1891 out.indent();
Steven Moreland19f11b52017-05-12 18:22:21 -07001892 out << "const ::android::sp<" << iface->localName() << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001893
1894 if (supportOneway) {
Yifan Hongef91d362017-03-20 17:18:13 -07001895 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001896
1897 out << "\n";
1898
1899 out << "::android::hardware::Return<void> addOnewayTask("
1900 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001901 }
1902
1903 out.unindent();
1904
1905 out << "};\n\n";
1906
1907 enterLeaveNamespace(out, false /* enter */);
1908
1909 out << "\n#endif // " << guard << "\n";
1910
1911 return OK;
1912}
1913
Yifan Hongfe95aa22016-10-19 17:26:45 -07001914status_t AST::generateInterfaceSource(Formatter &out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001915 const Interface* iface = mRootScope.getInterface();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001916
Yifan Hong2d7126b2016-10-20 15:12:57 -07001917 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001918 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001919
Steven Morelandd4b068a2017-03-20 06:30:51 -07001920 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1921 bool reserved = method->isHidlReserved();
1922
1923 if (!reserved) {
1924 out << "// no default implementation for: ";
1925 }
1926 method->generateCppSignature(out, iface->localName());
1927 if (reserved) {
1928 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001929 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001930 }).endl();
1931 }
1932
1933 out << "\n";
1934
1935 return OK;
1936 });
1937 if (err != OK) {
1938 return err;
1939 }
1940
Yifan Hong3d746092016-12-07 14:26:33 -08001941 for (const Interface *superType : iface->typeChain()) {
Yifan Hong200209c2017-03-29 03:39:09 -07001942 out << "// static \n::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -08001943 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -07001944 << "> "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001945 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001946 << "::castFrom("
1947 << superType->getCppArgumentType()
Yifan Hong200209c2017-03-29 03:39:09 -07001948 << " parent, bool "
1949 << (iface == superType ? "/* emitError */" : "emitError")
1950 << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001951 out.indent();
1952 if (iface == superType) {
1953 out << "return parent;\n";
1954 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001955 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001956 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001957 << superType->fqName().cppName() << ", "
Steven Moreland57a89362017-07-21 19:29:54 +00001958 << iface->getProxyName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001959 << ">(\n";
1960 out.indent();
1961 out.indent();
1962 out << "parent, \""
1963 << iface->fqName().string()
Yifan Hong200209c2017-03-29 03:39:09 -07001964 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001965 out.unindent();
1966 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001967 }
Yifan Hong3d746092016-12-07 14:26:33 -08001968 out.unindent();
1969 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001970 }
1971
1972 return OK;
1973}
1974
Steven Moreland69e7c702016-09-09 11:16:32 -07001975status_t AST::generatePassthroughSource(Formatter &out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001976 const Interface* iface = mRootScope.getInterface();
Steven Moreland69e7c702016-09-09 11:16:32 -07001977
Yifan Hongeefe4f22017-01-04 15:32:42 -08001978 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001979
1980 out << klassName
1981 << "::"
1982 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001983 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001984 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001985 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001986 << mPackage.string()
1987 << "\", \""
1988 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001989 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001990 if (iface->hasOnewayMethods()) {
1991 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001992 out.indent([&] {
Yifan Hongf01dad42017-03-20 19:03:11 -07001993 out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001994 });
1995 }
1996 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001997
1998 if (iface->hasOnewayMethods()) {
1999 out << "::android::hardware::Return<void> "
2000 << klassName
2001 << "::addOnewayTask(std::function<void(void)> fun) {\n";
2002 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07002003 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07002004 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07002005 out << "return ::android::hardware::Status::fromExceptionCode(\n";
2006 out.indent();
2007 out.indent();
Steven Moreland610002f2017-06-16 13:02:49 -07002008 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
2009 << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
Steven Moreland67f67b42016-09-29 08:59:02 -07002010 out.unindent();
2011 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07002012 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07002013 out << "}\n";
2014
Steven Morelandd366c262016-10-11 15:29:10 -07002015 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07002016
2017 out.unindent();
2018 out << "}\n\n";
2019
2020
2021 }
2022
2023 return OK;
2024}
2025
Steven Moreland92a08a72017-07-31 14:57:37 -07002026void AST::generateCppAtraceCall(Formatter &out,
Martijn Coenen7b295242016-11-04 16:52:56 +01002027 InstrumentationEvent event,
2028 const Method *method) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07002029 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08002030 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01002031 switch (event) {
2032 case SERVER_API_ENTRY:
2033 {
2034 out << "atrace_begin(ATRACE_TAG_HAL, \""
2035 << baseString + "::server\");\n";
2036 break;
2037 }
2038 case CLIENT_API_ENTRY:
2039 {
2040 out << "atrace_begin(ATRACE_TAG_HAL, \""
2041 << baseString + "::client\");\n";
2042 break;
2043 }
2044 case PASSTHROUGH_ENTRY:
2045 {
2046 out << "atrace_begin(ATRACE_TAG_HAL, \""
2047 << baseString + "::passthrough\");\n";
2048 break;
2049 }
2050 case SERVER_API_EXIT:
2051 case CLIENT_API_EXIT:
2052 case PASSTHROUGH_EXIT:
2053 {
2054 out << "atrace_end(ATRACE_TAG_HAL);\n";
2055 break;
2056 }
2057 default:
2058 {
Steven Moreland92a08a72017-07-31 14:57:37 -07002059 LOG(FATAL) << "Unsupported instrumentation event: " << event;
Martijn Coenen7b295242016-11-04 16:52:56 +01002060 }
2061 }
Martijn Coenen7b295242016-11-04 16:52:56 +01002062}
2063
Steven Moreland92a08a72017-07-31 14:57:37 -07002064void AST::generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002065 Formatter &out,
2066 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07002067 const Method *method) const {
Steven Moreland92a08a72017-07-31 14:57:37 -07002068 generateCppAtraceCall(out, event, method);
Martijn Coenen7b295242016-11-04 16:52:56 +01002069
Steven Moreland30b76e92017-06-02 18:52:24 -07002070 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002071 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
2072 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002073 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002074 std::string event_str = "";
2075 switch (event) {
2076 case SERVER_API_ENTRY:
2077 {
2078 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
2079 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002080 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002081 << (arg->type().resultNeedsDeref() ? "" : "&")
2082 << arg->name()
2083 << ");\n";
2084 }
2085 break;
2086 }
2087 case SERVER_API_EXIT:
2088 {
2089 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07002090 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002091 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07002092 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002093 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002094 }
2095 break;
2096 }
2097 case CLIENT_API_ENTRY:
2098 {
2099 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2100 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002101 out << "_hidl_args.push_back((void *)&"
2102 << arg->name()
2103 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002104 }
2105 break;
2106 }
2107 case CLIENT_API_EXIT:
2108 {
2109 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2110 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002111 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002112 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002113 << "_hidl_out_"
2114 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002115 << ");\n";
2116 }
2117 break;
2118 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002119 case PASSTHROUGH_ENTRY:
2120 {
2121 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2122 for (const auto &arg : method->args()) {
2123 out << "_hidl_args.push_back((void *)&"
2124 << arg->name()
2125 << ");\n";
2126 }
2127 break;
2128 }
2129 case PASSTHROUGH_EXIT:
2130 {
2131 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002132 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002133 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002134 << arg->name()
2135 << ");\n";
2136 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002137 break;
2138 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002139 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002140 {
Steven Moreland92a08a72017-07-31 14:57:37 -07002141 LOG(FATAL) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002142 }
2143 }
2144
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07002145 const Interface* iface = mRootScope.getInterface();
Steven Moreland031ccf12016-10-31 15:54:38 -07002146
Steven Moreland1ab31442016-11-03 18:37:51 -07002147 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002148 out.indent();
2149 out << "callback("
2150 << event_str
2151 << ", \""
2152 << mPackage.package()
2153 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002154 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002155 << "\", \""
2156 << iface->localName()
2157 << "\", \""
2158 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002159 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002160 out.unindent();
2161 out << "}\n";
2162 out.unindent();
Steven Moreland30b76e92017-06-02 18:52:24 -07002163 out << "}\n";
2164 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002165}
2166
Andreas Huber881227d2016-08-02 14:20:21 -07002167} // namespace android