blob: f801eeed4944ea9b0a629198096a34a5bb60e18b [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 Huber6755e9d2017-04-06 11:09:07 -070021#include "HidlTypeAssertion.h"
Timur Iskhakov7fa79f62017-08-09 11:04:54 -070022#include "Interface.h"
Andreas Huber881227d2016-08-02 14:20:21 -070023#include "Method.h"
Timur Iskhakov7fa79f62017-08-09 11:04:54 -070024#include "Reference.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070025#include "ScalarType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070026#include "Scope.h"
27
Andreas Huberdca261f2016-08-04 13:47:51 -070028#include <algorithm>
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070029#include <hidl-util/Formatter.h>
Steven Moreland5708edf2016-11-04 15:33:31 +000030#include <hidl-util/StringHelper.h>
Andreas Huber881227d2016-08-02 14:20:21 -070031#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070032#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070033#include <vector>
34
35namespace android {
36
Andreas Huberb82318c2016-08-02 14:45:54 -070037status_t AST::generateCpp(const std::string &outputPath) const {
Steven Moreland1cbf0362017-05-09 14:32:53 -070038 status_t err = generateCppHeaders(outputPath);
39
40 if (err == OK) {
41 err = generateCppSources(outputPath);
42 }
43
44 return err;
45}
46
47status_t AST::generateCppHeaders(const std::string &outputPath) const {
Andreas Huberb82318c2016-08-02 14:45:54 -070048 status_t err = generateInterfaceHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070049
50 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070051 err = generateStubHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070052 }
53
54 if (err == OK) {
Steven Moreland40786312016-08-16 10:29:40 -070055 err = generateHwBinderHeader(outputPath);
56 }
57
58 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070059 err = generateProxyHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070060 }
61
62 if (err == OK) {
Yifan Hong7a118f52016-12-07 11:21:15 -080063 err = generatePassthroughHeader(outputPath);
Steven Moreland69e7c702016-09-09 11:16:32 -070064 }
65
Andreas Huber881227d2016-08-02 14:20:21 -070066 return err;
67}
68
Andreas Huber737080b2016-08-02 15:38:04 -070069void AST::getPackageComponents(
70 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070071 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070072}
73
74void AST::getPackageAndVersionComponents(
75 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070076 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070077}
78
Steven Moreland5708edf2016-11-04 15:33:31 +000079std::string AST::makeHeaderGuard(const std::string &baseName,
80 bool indicateGenerated) const {
81 std::string guard;
Andreas Huber881227d2016-08-02 14:20:21 -070082
Steven Moreland5708edf2016-11-04 15:33:31 +000083 if (indicateGenerated) {
84 guard += "HIDL_GENERATED_";
85 }
86
87 guard += StringHelper::Uppercase(mPackage.tokenName());
Andreas Huber881227d2016-08-02 14:20:21 -070088 guard += "_";
Steven Moreland5708edf2016-11-04 15:33:31 +000089 guard += StringHelper::Uppercase(baseName);
90 guard += "_H";
Andreas Huber881227d2016-08-02 14:20:21 -070091
92 return guard;
93}
94
Steven Morelandee88eed2016-10-31 17:49:00 -070095void AST::generateCppPackageInclude(
96 Formatter &out,
97 const FQName &package,
98 const std::string &klass) {
99
100 out << "#include <";
101
102 std::vector<std::string> components;
103 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
104
105 for (const auto &component : components) {
106 out << component << "/";
107 }
108
109 out << klass
110 << ".h>\n";
111}
112
Andreas Huber881227d2016-08-02 14:20:21 -0700113void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
114 std::vector<std::string> packageComponents;
115 getPackageAndVersionComponents(
116 &packageComponents, true /* cpp_compatible */);
117
118 if (enter) {
119 for (const auto &component : packageComponents) {
120 out << "namespace " << component << " {\n";
121 }
Andreas Huber0e00de42016-08-03 09:56:02 -0700122
Andreas Huber2831d512016-08-15 09:33:47 -0700123 out.setNamespace(mPackage.cppNamespace() + "::");
Andreas Huber881227d2016-08-02 14:20:21 -0700124 } else {
Andreas Huber0e00de42016-08-03 09:56:02 -0700125 out.setNamespace(std::string());
126
Andreas Huber881227d2016-08-02 14:20:21 -0700127 for (auto it = packageComponents.rbegin();
128 it != packageComponents.rend();
129 ++it) {
130 out << "} // namespace " << *it << "\n";
131 }
132 }
133}
134
Steven Moreland038903b2017-03-30 12:11:24 -0700135static void declareGetService(Formatter &out, const std::string &interfaceName, bool isTry) {
136 const std::string functionName = isTry ? "tryGetService" : "getService";
137
138 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800139 << "const std::string &serviceName=\"default\", bool getStub=false);\n";
Steven Moreland038903b2017-03-30 12:11:24 -0700140 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800141 << "const char serviceName[], bool getStub=false)"
142 << " { std::string str(serviceName ? serviceName : \"\");"
Steven Moreland038903b2017-03-30 12:11:24 -0700143 << " return " << functionName << "(str, getStub); }\n";
144 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800145 << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
146 // without c_str the std::string constructor is ambiguous
147 << " { std::string str(serviceName.c_str());"
Steven Moreland038903b2017-03-30 12:11:24 -0700148 << " return " << functionName << "(str, getStub); }\n";
149 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
150 << "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
151}
152
153static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
154 declareGetService(out, interfaceName, true /* isTry */);
155 declareGetService(out, interfaceName, false /* isTry */);
156
Steven Moreland90831502017-03-27 12:08:40 -0700157 out << "__attribute__ ((warn_unused_result))"
158 << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800159 out << "static bool registerForNotifications(\n";
160 out.indent(2, [&] {
161 out << "const std::string &serviceName,\n"
162 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
163 << "&notification);\n";
164 });
165
166}
167
Steven Moreland038903b2017-03-30 12:11:24 -0700168static void implementGetService(Formatter &out,
169 const FQName &fqName,
170 bool isTry) {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800171
172 const std::string interfaceName = fqName.getInterfaceName();
Steven Moreland038903b2017-03-30 12:11:24 -0700173 const std::string functionName = isTry ? "tryGetService" : "getService";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800174
175 out << "// static\n"
Steven Moreland038903b2017-03-30 12:11:24 -0700176 << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
Yifan Hong31f07ff2017-03-21 18:56:35 +0000177 << "const std::string &serviceName, const bool getStub) ";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800178 out.block([&] {
Steven Morelandbcf51802017-04-06 09:17:44 -0700179 out << "using ::android::hardware::defaultServiceManager;\n";
180 out << "using ::android::hardware::details::waitForHwService;\n";
181 out << "using ::android::hardware::getPassthroughServiceManager;\n";
182 out << "using ::android::hardware::Return;\n";
183 out << "using ::android::sp;\n";
184 out << "using Transport = ::android::hidl::manager::V1_0::IServiceManager::Transport;\n\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000185
Steven Morelandbcf51802017-04-06 09:17:44 -0700186 out << "sp<" << interfaceName << "> iface = nullptr;\n";
187
188 out.endl();
189
190 out << "const sp<::android::hidl::manager::V1_0::IServiceManager> sm"
191 << " = defaultServiceManager();\n";
192
193 out.sIf("sm == nullptr", [&] {
194 // hwbinder is not available on this device, so future tries
195 // would also be null. I can only return nullptr.
196 out << "ALOGE(\"getService: defaultServiceManager() is null\");\n"
197 << "return nullptr;\n";
198 }).endl().endl();
199
200 out << "Return<Transport> transportRet = sm->getTransport("
201 << interfaceName << "::descriptor, serviceName);\n\n";
202
203 out.sIf("!transportRet.isOk()", [&] {
204 out << "ALOGE(\"getService: defaultServiceManager()->getTransport returns %s\", "
205 << "transportRet.description().c_str());\n";
206 out << "return nullptr;\n";
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700207 }).endl();
Steven Morelandbcf51802017-04-06 09:17:44 -0700208
209 out << "Transport transport = transportRet;\n";
210 out << "const bool vintfHwbinder = (transport == Transport::HWBINDER);\n"
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700211 << "const bool vintfPassthru = (transport == Transport::PASSTHROUGH);\n\n";
212
213 // This means that you must set TREBLE_TESTING_OVERRIDE when running a test such
214 // as hidl_test. Ideally these binaries set this value themselves. This allows
215 // test modules to dynamically add and unset services even though they are not
216 // declared in the device manifest. This prevents a problem where framework
217 // changes are accidentally made in a way that is not backwards compatible. For
218 // instance, consider the following situation for two devices developed in the
219 // same tree:
220 // A: serves @1.1::IFoo, declares @1.0::IFoo (incorrect)
221 // B: serves @1.0::IFoo, declares @1.0::IFoo (correct configuration)
222 // If development is done on device A, then framework code like: "V1_1::IFoo::
223 // getService()->doV1_0Api()" will work. However, this will unintentionally break
224 // the feature for devices like device B for which "V1_1::IFoo::getService()
225 // will return nullptr. In order to prevent problems like this, we only allow
226 // fetching an interface if it is declared in a VINTF manifest.
227 out << "#ifdef __ANDROID_TREBLE__\n\n"
228 << "#ifdef __ANDROID_DEBUGGABLE__\n"
229 << "const char* env = std::getenv(\"TREBLE_TESTING_OVERRIDE\");\n"
Steven Morelandd281ebc2017-06-20 16:27:35 -0700230 << "const bool trebleTestingOverride = env && !strcmp(env, \"true\");\n"
231 << "const bool vintfLegacy = (transport == Transport::EMPTY) && trebleTestingOverride;\n"
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700232 << "#else // __ANDROID_TREBLE__ but not __ANDROID_DEBUGGABLE__\n"
Steven Morelandd281ebc2017-06-20 16:27:35 -0700233 << "const bool trebleTestingOverride = false;\n"
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700234 << "const bool vintfLegacy = false;\n"
235 << "#endif // __ANDROID_DEBUGGABLE__\n\n"
236 << "#else // not __ANDROID_TREBLE__\n"
Steven Moreland82472102017-06-26 09:40:37 -0700237 << "const char* env = std::getenv(\"TREBLE_TESTING_OVERRIDE\");\n"
238 << "const bool trebleTestingOverride = env && !strcmp(env, \"true\");\n"
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700239 << "const bool vintfLegacy = (transport == Transport::EMPTY);\n\n"
240 << "#endif // __ANDROID_TREBLE__\n\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000241
242 // if (getStub) {
243 // getPassthroughServiceManager()->get only once.
244 // } else {
245 // if (vintfHwbinder) {
246 // while (no alive service) {
Steven Moreland369d0532017-06-09 12:42:10 -0700247 // if (have already tried to get service)
248 // waitForHwService
Yifan Hong31f07ff2017-03-21 18:56:35 +0000249 // defaultServiceManager()->get
250 // }
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700251 // } else if (vintfLegacy) {
Yifan Hong31f07ff2017-03-21 18:56:35 +0000252 // defaultServiceManager()->get only once.
253 // getPassthroughServiceManager()->get only once.
254 // } else if (vintfPassthru) {
255 // getPassthroughServiceManager()->get only once.
256 // }
257 // }
258
Steven Moreland369d0532017-06-09 12:42:10 -0700259 out.sFor("int tries = 0; !getStub && (vintfHwbinder || (vintfLegacy && tries == 0)); tries++", [&] {
Steven Moreland038903b2017-03-30 12:11:24 -0700260 if (!isTry) {
Steven Moreland369d0532017-06-09 12:42:10 -0700261 out.sIf("tries > 1", [&] {
262 // sleep only after the first time we've called waitForHwService.
263 out << "ALOGI(\"" << functionName << ": Will do try %d for %s/%s in 1s...\", tries, "
264 << interfaceName << "::descriptor, serviceName.c_str());\n"
265 << "sleep(1);\n";
266 }).endl();
267
268 out.sIf("vintfHwbinder && tries > 0", [&] {
Steven Morelandbcf51802017-04-06 09:17:44 -0700269 out << "waitForHwService("
270 << interfaceName << "::descriptor, serviceName);\n";
Steven Moreland038903b2017-03-30 12:11:24 -0700271 }).endl();
272 }
Yifan Hong31f07ff2017-03-21 18:56:35 +0000273
Steven Morelandbcf51802017-04-06 09:17:44 -0700274 out << "Return<sp<" << gIBaseFqName.cppName() << ">> ret = \n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000275 out.indent(2, [&] {
276 out << "sm->get(" << interfaceName << "::descriptor, serviceName);\n";
277 });
278
279 out.sIf("!ret.isOk()", [&] {
Steven Moreland42394ce2017-03-27 17:03:04 -0700280 // hwservicemanager fails, may be security issue
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700281 out << "ALOGE(\"" << interfaceName << ": defaultServiceManager()->get returns %s\", "
Yifan Hong31f07ff2017-03-21 18:56:35 +0000282 << "ret.description().c_str());\n"
Steven Moreland42394ce2017-03-27 17:03:04 -0700283 << "break;\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000284 }).endl();
285
Steven Morelandbcf51802017-04-06 09:17:44 -0700286 out << "sp<" << gIBaseFqName.cppName() << "> base = ret;\n";
Yifan Hong200209c2017-03-29 03:39:09 -0700287 out.sIf("base == nullptr", [&] {
Steven Moreland369d0532017-06-09 12:42:10 -0700288 // if tries > 0: race condition. hwservicemanager drops the service
Yifan Hong200209c2017-03-29 03:39:09 -0700289 // from waitForHwService to here
Steven Moreland369d0532017-06-09 12:42:10 -0700290 out.sIf("tries > 0", [&] {
291 out << "ALOGW(\"" << interfaceName << ": found null hwbinder interface\");\n";
292 });
293 out << (isTry ? "break" : "continue")
Yifan Hong9c74a5b2017-04-04 13:27:25 -0700294 << ";\n";
Yifan Hong31f07ff2017-03-21 18:56:35 +0000295 }).endl();
Steven Morelandbcf51802017-04-06 09:17:44 -0700296 out << "Return<sp<" << interfaceName
Yifan Hong200209c2017-03-29 03:39:09 -0700297 << ">> castRet = " << interfaceName << "::castFrom(base, true /* emitError */);\n";
298 out.sIf("!castRet.isOk()", [&] {
299 out.sIf("castRet.isDeadObject()", [&] {
300 // service is dead (castFrom cannot call interfaceChain)
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700301 out << "ALOGW(\"" << interfaceName << ": found dead hwbinder service\");\n"
Yifan Hong9c74a5b2017-04-04 13:27:25 -0700302 << (isTry ? "break" : "continue")
303 << ";\n";
Yifan Hong200209c2017-03-29 03:39:09 -0700304 }).sElse([&] {
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700305 out << "ALOGW(\"" << interfaceName << ": cannot call into hwbinder service: %s"
Yifan Hong200209c2017-03-29 03:39:09 -0700306 << "; No permission? Check for selinux denials.\", "
307 << "castRet.description().c_str());\n"
308 << "break;\n";
309 }).endl();
310 }).endl();
311 out << "iface = castRet;\n";
312 out.sIf("iface == nullptr", [&] {
313 // returned service isn't of correct type; this is a bug
314 // to hwservicemanager or to the service itself (interfaceChain
315 // is not consistent).
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700316 out << "ALOGW(\"" << interfaceName << ": received incompatible service; bug in hwservicemanager?\");\n"
Yifan Hong200209c2017-03-29 03:39:09 -0700317 << "break;\n";
318 }).endl();
Yifan Hong31f07ff2017-03-21 18:56:35 +0000319
320 out << "return iface;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800321 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800322
Steven Morelandf9cf33b2017-05-18 13:58:54 -0700323 out.sIf("getStub || vintfPassthru || vintfLegacy", [&] {
Steven Morelandbcf51802017-04-06 09:17:44 -0700324 out << "const sp<::android::hidl::manager::V1_0::IServiceManager> pm"
325 << " = getPassthroughServiceManager();\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000326
327 out.sIf("pm != nullptr", [&] () {
Steven Morelandbcf51802017-04-06 09:17:44 -0700328 out << "Return<sp<" << gIBaseFqName.cppName() << ">> ret = \n";
Steven Morelandf10af872017-01-25 16:01:56 +0000329 out.indent(2, [&] {
330 out << "pm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
Steven Moreland2c2dea82017-01-18 17:24:17 -0800331 });
Steven Morelandf10af872017-01-25 16:01:56 +0000332 out.sIf("ret.isOk()", [&] {
Steven Morelandbcf51802017-04-06 09:17:44 -0700333 out << "sp<" << gIBaseFqName.cppName()
Steven Morelandf10af872017-01-25 16:01:56 +0000334 << "> baseInterface = ret;\n";
335 out.sIf("baseInterface != nullptr", [&]() {
Steven Morelandd281ebc2017-06-20 16:27:35 -0700336 out << "iface = " << interfaceName << "::castFrom(baseInterface);\n";
337 out.sIf("!getStub || trebleTestingOverride", [&] () {
338 out << "iface = new " << fqName.getInterfacePassthroughName() << "(iface);\n";
339 }).endl();
Yifan Hong31f07ff2017-03-21 18:56:35 +0000340 }).endl();
Steven Morelandf10af872017-01-25 16:01:56 +0000341 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800342 }).endl();
343 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800344
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800345 out << "return iface;\n";
346 }).endl().endl();
Steven Moreland038903b2017-03-30 12:11:24 -0700347}
348
349static void implementServiceManagerInteractions(Formatter &out,
350 const FQName &fqName, const std::string &package) {
351
352 const std::string interfaceName = fqName.getInterfaceName();
353
354 implementGetService(out, fqName, true /* isTry */);
355 implementGetService(out, fqName, false /* isTry */);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800356
Yifan Hongeefe4f22017-01-04 15:32:42 -0800357 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800358 << "const std::string &serviceName) ";
359 out.block([&] {
Steven Moreland58b478b2017-04-09 10:54:50 -0700360 out << "::android::hardware::details::onRegistration(\""
361 << fqName.getPackageAndVersion().string() << "\", \""
362 << interfaceName
363 << "\", serviceName);\n\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800364 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
365 out.indent(2, [&] {
366 out << "= ::android::hardware::defaultServiceManager();\n";
367 });
368 out.sIf("sm == nullptr", [&] {
369 out << "return ::android::INVALID_OPERATION;\n";
370 }).endl();
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100371 out << "::android::hardware::Return<bool> ret = "
372 << "sm->add(serviceName.c_str(), this);\n"
373 << "return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800374 }).endl().endl();
375
Yifan Hongeefe4f22017-01-04 15:32:42 -0800376 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800377 out.indent(2, [&] {
378 out << "const std::string &serviceName,\n"
379 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
380 << "&notification) ";
381 });
382 out.block([&] {
383 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
384 out.indent(2, [&] {
385 out << "= ::android::hardware::defaultServiceManager();\n";
386 });
387 out.sIf("sm == nullptr", [&] {
388 out << "return false;\n";
389 }).endl();
390 out << "::android::hardware::Return<bool> success =\n";
391 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800392 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800393 out.indent(2, [&] {
394 out << "serviceName, notification);\n";
395 });
396 });
397 out << "return success.isOk() && success;\n";
398 }).endl().endl();
399}
400
Andreas Huberb82318c2016-08-02 14:45:54 -0700401status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700402 const Interface *iface = getInterface();
403 std::string ifaceName = iface ? iface->localName() : "types";
Andreas Huber881227d2016-08-02 14:20:21 -0700404
Andreas Huberb82318c2016-08-02 14:45:54 -0700405 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700406 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700407 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700408 path.append(ifaceName);
409 path.append(".h");
410
Andreas Huberd2943e12016-08-05 11:59:31 -0700411 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700412 FILE *file = fopen(path.c_str(), "w");
413
414 if (file == NULL) {
415 return -errno;
416 }
417
418 Formatter out(file);
419
420 const std::string guard = makeHeaderGuard(ifaceName);
421
422 out << "#ifndef " << guard << "\n";
423 out << "#define " << guard << "\n\n";
424
Andreas Huber737080b2016-08-02 15:38:04 -0700425 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700426 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700427 }
428
429 if (!mImportedNames.empty()) {
430 out << "\n";
431 }
432
Steven Moreland19f11b52017-05-12 18:22:21 -0700433 if (iface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800434 if (isIBase()) {
435 out << "// skipped #include IServiceNotification.h\n\n";
436 } else {
437 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
438 }
Steven Moreland0693f312016-11-09 15:06:14 -0800439 }
440
Yifan Hongc8934042016-11-17 17:10:52 -0800441 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700442 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700443
Steven Moreland19f11b52017-05-12 18:22:21 -0700444 if (iface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200445 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700446 }
447
Martijn Coenenaf712c02016-11-16 15:26:27 +0100448 out << "#include <utils/NativeHandle.h>\n";
449 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700450
451 enterLeaveNamespace(out, true /* enter */);
452 out << "\n";
453
Steven Moreland19f11b52017-05-12 18:22:21 -0700454 if (iface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700455 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700456 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700457
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700458 const Interface *superType = iface->superType();
459
Steven Moreland40786312016-08-16 10:29:40 -0700460 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800461 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700462 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000463 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700464 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700465 }
466
467 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700468
469 out.indent();
470
Steven Moreland1a52e822017-07-27 13:56:29 -0700471 generateCppTag(out, "android::hardware::details::i_tag");
Andreas Huber881227d2016-08-02 14:20:21 -0700472 }
473
474 status_t err = emitTypeDeclarations(out);
475
476 if (err != OK) {
477 return err;
478 }
479
Steven Moreland19f11b52017-05-12 18:22:21 -0700480 if (iface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800481 out << "virtual bool isRemote() const ";
482 if (!isIBase()) {
483 out << "override ";
484 }
485 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800486
Steven Morelandf7f2a9a2017-07-21 18:05:38 -0700487 for (const auto& tuple : iface->allMethodsFromRoot()) {
488 const Method* method = tuple.method();
489
Andreas Huber881227d2016-08-02 14:20:21 -0700490 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700491
Andreas Huber881227d2016-08-02 14:20:21 -0700492 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700493 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Morelandd732ea12016-11-08 17:12:06 -0800494
495 if (elidedReturn == nullptr && returnsValue) {
496 out << "using "
497 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700498 << "_cb = std::function<void(";
499 method->emitCppResultSignature(out, true /* specify namespaces */);
500 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800501 }
Andreas Huber881227d2016-08-02 14:20:21 -0700502
Andreas Huber3599d922016-08-09 10:42:57 -0700503 method->dumpAnnotations(out);
504
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700505 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700506 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700507 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700508 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700509 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700510 }
511
512 out << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700513 << "(";
514 method->emitCppArgSignature(out, true /* specify namespaces */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700515 out << ")";
516 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800517 if (!isIBase()) {
518 out << " override";
519 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700520 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700521 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700522 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700523 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700524 }
Steven Moreland40786312016-08-16 10:29:40 -0700525
Yifan Hong3d746092016-12-07 14:26:33 -0800526 out << "// cast static functions\n";
527 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700528
Yifan Hong3d746092016-12-07 14:26:33 -0800529 for (const Interface *superType : iface->typeChain()) {
Yifan Hong200209c2017-03-29 03:39:09 -0700530 out << "static ::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -0800531 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -0700532 << "> castFrom("
Yifan Hong3d746092016-12-07 14:26:33 -0800533 << superType->getCppArgumentType()
534 << " parent"
Yifan Hong200209c2017-03-29 03:39:09 -0700535 << ", bool emitError = false);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700536 }
537
Steven Morelandd39133b2016-11-11 12:30:08 -0800538 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700539
Yifan Hongc8934042016-11-17 17:10:52 -0800540 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800541 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800542 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800543 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800544 }
Andreas Huber881227d2016-08-02 14:20:21 -0700545 }
546
Steven Moreland19f11b52017-05-12 18:22:21 -0700547 if (iface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700548 out.unindent();
549
Andreas Hubere3f769a2016-10-10 10:54:44 -0700550 out << "};\n\n";
551 }
552
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700553 err = mRootScope.emitGlobalTypeDeclarations(out);
Andreas Hubere3f769a2016-10-10 10:54:44 -0700554
555 if (err != OK) {
556 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700557 }
558
559 out << "\n";
560 enterLeaveNamespace(out, false /* enter */);
561
562 out << "\n#endif // " << guard << "\n";
563
564 return OK;
565}
566
Steven Moreland40786312016-08-16 10:29:40 -0700567status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700568 const Interface *iface = getInterface();
569 std::string klassName = iface ? iface->getHwName() : "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700570
Steven Moreland40786312016-08-16 10:29:40 -0700571 std::string path = outputPath;
572 path.append(mCoordinator->convertPackageRootToPath(mPackage));
573 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
574 path.append(klassName + ".h");
575
Yifan Hong244e82d2016-11-11 11:13:57 -0800576 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700577
578 if (file == NULL) {
579 return -errno;
580 }
581
582 Formatter out(file);
583
584 const std::string guard = makeHeaderGuard(klassName);
585
586 out << "#ifndef " << guard << "\n";
587 out << "#define " << guard << "\n\n";
588
Steven Moreland19f11b52017-05-12 18:22:21 -0700589 generateCppPackageInclude(out, mPackage, iface ? iface->localName() : "types");
Steven Moreland40786312016-08-16 10:29:40 -0700590
Steven Morelandee88eed2016-10-31 17:49:00 -0700591 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700592
593 for (const auto &item : mImportedNames) {
594 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800595 generateCppPackageInclude(out, item, "hwtypes");
596 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800597 generateCppPackageInclude(out, item, item.getInterfaceStubName());
598 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700599 }
Steven Moreland40786312016-08-16 10:29:40 -0700600 }
601
602 out << "\n";
603
Martijn Coenen93915102016-09-01 01:35:52 +0200604 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700605 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100606 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700607
608 out << "\n";
609
610 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700611
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700612 status_t err = mRootScope.emitGlobalHwDeclarations(out);
Yifan Hong244e82d2016-11-11 11:13:57 -0800613 if (err != OK) {
614 return err;
615 }
Steven Moreland40786312016-08-16 10:29:40 -0700616
617 enterLeaveNamespace(out, false /* enter */);
618
619 out << "\n#endif // " << guard << "\n";
620
621 return OK;
622}
623
Andreas Huber881227d2016-08-02 14:20:21 -0700624status_t AST::emitTypeDeclarations(Formatter &out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700625 return mRootScope.emitTypeDeclarations(out);
Andreas Huber881227d2016-08-02 14:20:21 -0700626}
627
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700628static void wrapPassthroughArg(Formatter& out, const NamedReference<Type>* arg,
629 bool addPrefixToName, std::function<void(void)> handleError) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800630 if (!arg->type().isInterface()) {
631 return;
632 }
633 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
634 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
635 + arg->name();
636 const Interface &iface = static_cast<const Interface &>(arg->type());
637 out << iface.getCppStackType() << " " << wrappedName << ";\n";
638 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
639 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
640 out << wrappedName
641 << " = "
642 << iface.fqName().cppName()
Yifan Hong341112d2017-04-20 18:12:05 -0700643 << "::castFrom(::android::hardware::details::wrapPassthrough<"
644 << iface.fqName().cppName()
645 << ">("
Yifan Hong7a118f52016-12-07 11:21:15 -0800646 << name << "));\n";
647 out.sIf(wrappedName + " == nullptr", [&] {
648 // Fatal error. Happens when the BsFoo class is not found in the binary
649 // or any dynamic libraries.
650 handleError();
651 }).endl();
652 }).sElse([&] {
653 out << wrappedName << " = " << name << ";\n";
654 }).endl().endl();
655}
656
Steven Moreland69e7c702016-09-09 11:16:32 -0700657status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700658 const Method *method) const {
659 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700660
661 out << " {\n";
662 out.indent();
663
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800664 if (method->isHidlReserved()
665 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
666 method->cppImpl(IMPL_PASSTHROUGH, out);
667 out.unindent();
668 out << "}\n\n";
669 return OK;
670 }
671
Steven Moreland69e7c702016-09-09 11:16:32 -0700672 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700673 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland69e7c702016-09-09 11:16:32 -0700674
Steven Moreland67f67b42016-09-29 08:59:02 -0700675 if (returnsValue && elidedReturn == nullptr) {
676 generateCheckNonNull(out, "_hidl_cb");
677 }
678
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700679 generateCppInstrumentationCall(
680 out,
681 InstrumentationEvent::PASSTHROUGH_ENTRY,
682 method);
683
Yifan Hong7a118f52016-12-07 11:21:15 -0800684
685 for (const auto &arg : method->args()) {
686 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
687 out << "return ::android::hardware::Status::fromExceptionCode(\n";
688 out.indent(2, [&] {
689 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800690 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800691 });
692 });
693 }
694
695 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700696 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700697
698 if (method->isOneway()) {
Steven Moreland836cb312017-06-05 17:25:55 -0700699 out << "addOnewayTask([mImpl = this->mImpl\n"
700 << "#ifdef __ANDROID_DEBUGGABLE__\n"
701 ", mEnableInstrumentation = this->mEnableInstrumentation, "
702 "mInstrumentationCallbacks = this->mInstrumentationCallbacks\n"
703 << "#endif // __ANDROID_DEBUGGABLE__\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700704 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800705 out << ", "
706 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
707 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700708 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700709 out << "] {\n";
710 out.indent();
Steven Moreland69e7c702016-09-09 11:16:32 -0700711 }
712
713 out << "mImpl->"
714 << method->name()
715 << "(";
716
Yifan Hong932464e2017-03-30 15:40:22 -0700717 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800718 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700719 });
Steven Moreland69e7c702016-09-09 11:16:32 -0700720 if (returnsValue && elidedReturn == nullptr) {
Steven Moreland340c8822017-05-02 14:41:49 -0700721 // never true if oneway since oneway methods don't return values
722
Steven Moreland69e7c702016-09-09 11:16:32 -0700723 if (!method->args().empty()) {
724 out << ", ";
725 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800726 out << "[&](";
Yifan Hong932464e2017-03-30 15:40:22 -0700727 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800728 out << "const auto &_hidl_out_"
729 << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700730 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800731
732 out << ") {\n";
733 out.indent();
Steven Moreland92a08a72017-07-31 14:57:37 -0700734 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800735 out,
736 InstrumentationEvent::PASSTHROUGH_EXIT,
737 method);
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800738
Yifan Hong7a118f52016-12-07 11:21:15 -0800739 for (const auto &arg : method->results()) {
740 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
741 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
742 out.indent(2, [&] {
743 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800744 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800745 });
746 out << "return;\n";
747 });
748 }
749
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800750 out << "_hidl_cb(";
Yifan Hong932464e2017-03-30 15:40:22 -0700751 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800752 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
753 << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700754 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800755 out << ");\n";
756 out.unindent();
757 out << "});\n\n";
758 } else {
759 out << ");\n\n";
Steven Moreland30b76e92017-06-02 18:52:24 -0700760
761 // used by generateCppInstrumentationCall
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800762 if (elidedReturn != nullptr) {
Steven Moreland30b76e92017-06-02 18:52:24 -0700763 out << "#ifdef __ANDROID_DEBUGGABLE__\n"
764 << elidedReturn->type().getCppResultType() << " _hidl_out_" << elidedReturn->name()
765 << " = _hidl_return;\n"
766 << "#endif // __ANDROID_DEBUGGABLE__\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800767 }
Steven Moreland92a08a72017-07-31 14:57:37 -0700768 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800769 out,
770 InstrumentationEvent::PASSTHROUGH_EXIT,
771 method);
Steven Moreland69e7c702016-09-09 11:16:32 -0700772 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700773
774 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700775 out.unindent();
776 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700777 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700778
779 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700780
781 out.unindent();
782 out << "}\n";
783
784 return OK;
785}
786
Chih-Hung Hsieh8c90cc52017-08-03 14:51:13 -0700787status_t AST::generateMethods(Formatter& out,
788 const MethodGenerator& gen,
789 bool includeParent) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700790 const Interface* iface = mRootScope.getInterface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700791
Yifan Hong10fe0b52016-10-19 14:20:17 -0700792 const Interface *prevIterface = nullptr;
793 for (const auto &tuple : iface->allMethodsFromRoot()) {
794 const Method *method = tuple.method();
795 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700796
Steven Morelandf16c5c02017-07-31 16:50:06 -0700797 if (!includeParent && superInterface != iface) {
798 continue;
799 }
800
Yifan Hong10fe0b52016-10-19 14:20:17 -0700801 if(prevIterface != superInterface) {
802 if (prevIterface != nullptr) {
803 out << "\n";
804 }
805 out << "// Methods from "
806 << superInterface->fullName()
807 << " follow.\n";
808 prevIterface = superInterface;
809 }
Yifan Hong068c5522016-10-31 14:07:25 -0700810 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700811
Yifan Hong10fe0b52016-10-19 14:20:17 -0700812 if (err != OK) {
813 return err;
814 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700815 }
816
Yifan Hong10fe0b52016-10-19 14:20:17 -0700817 out << "\n";
818
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700819 return OK;
820}
821
Steven Moreland0b843772017-06-23 16:33:38 -0700822void AST::generateTemplatizationLink(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700823 out << "typedef " << mRootScope.getInterface()->localName() << " Pure;\n\n";
Steven Moreland0b843772017-06-23 16:33:38 -0700824}
825
Steven Moreland1a52e822017-07-27 13:56:29 -0700826void AST::generateCppTag(Formatter& out, const std::string& tag) const {
827 out << "typedef " << tag << " _hidl_tag;\n\n";
828}
829
Andreas Huberb82318c2016-08-02 14:45:54 -0700830status_t AST::generateStubHeader(const std::string &outputPath) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700831 if (!AST::isInterface()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700832 // types.hal does not get a stub header.
833 return OK;
834 }
835
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700836 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800837 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700838
Andreas Huberb82318c2016-08-02 14:45:54 -0700839 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700840 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700841 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700842 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700843 path.append(".h");
844
Andreas Huberd2943e12016-08-05 11:59:31 -0700845 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700846 FILE *file = fopen(path.c_str(), "w");
847
848 if (file == NULL) {
849 return -errno;
850 }
851
852 Formatter out(file);
853
Steven Moreland40786312016-08-16 10:29:40 -0700854 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700855
856 out << "#ifndef " << guard << "\n";
857 out << "#define " << guard << "\n\n";
858
Yifan Hongeefe4f22017-01-04 15:32:42 -0800859 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Moreland1a52e822017-07-27 13:56:29 -0700860
Steven Morelandee88eed2016-10-31 17:49:00 -0700861 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700862
863 enterLeaveNamespace(out, true /* enter */);
864 out << "\n";
865
866 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800867 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100868 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800869 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000870 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100871 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800872 out << " : public "
873 << gIBaseFqName.getInterfaceStubFqName().cppName()
874 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100875 }
Andreas Huber881227d2016-08-02 14:20:21 -0700876
877 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800878 out << "explicit "
879 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -0700880 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100881 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800882 out << "explicit "
883 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -0700884 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800885 << " const std::string& HidlInstrumentor_package,"
886 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700887 << "\n\n";
Steven Moreland57a89362017-07-21 19:29:54 +0000888 out << "virtual ~" << klassName << "();\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700889 out << "::android::status_t onTransact(\n";
890 out.indent();
891 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700892 out << "uint32_t _hidl_code,\n";
893 out << "const ::android::hardware::Parcel &_hidl_data,\n";
894 out << "::android::hardware::Parcel *_hidl_reply,\n";
895 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700896 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700897 out.unindent();
898 out.unindent();
899
Steven Moreland0b843772017-06-23 16:33:38 -0700900 out.endl();
901 generateTemplatizationLink(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700902 generateCppTag(out, "android::hardware::details::bnhw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700903
Steven Moreland19f11b52017-05-12 18:22:21 -0700904 out << "::android::sp<" << iface->localName() << "> getImpl() { return _hidl_mImpl; };\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700905
906 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
907 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
908 return OK;
909 }
910
911 out << "static ::android::status_t _hidl_" << method->name() << "(\n";
912
913 out.indent(2, [&] {
914 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
915 << "const ::android::hardware::Parcel &_hidl_data,\n"
916 << "::android::hardware::Parcel *_hidl_reply,\n"
917 << "TransactCallback _hidl_cb);\n";
918 }).endl().endl();
919
920 return OK;
921 }, false /* include parents */);
922
923 if (err != OK) {
924 return err;
925 }
926
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100927 out.unindent();
928 out << "private:\n";
929 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800930
Steven Morelandf16c5c02017-07-31 16:50:06 -0700931
932 err = generateMethods(out, [&](const Method *method, const Interface *iface) {
Yifan Hongcd2ae452017-01-31 14:33:40 -0800933 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
934 return OK;
935 }
936 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700937 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800938
939 if (elidedReturn == nullptr && returnsValue) {
940 out << "using " << method->name() << "_cb = "
941 << iface->fqName().cppName()
942 << "::" << method->name() << "_cb;\n";
943 }
944 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800945 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800946 return OK;
947 });
948 if (err != OK) {
949 return err;
950 }
951
Steven Moreland19f11b52017-05-12 18:22:21 -0700952 out << "::android::sp<" << iface->localName() << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700953 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700954 out << "};\n\n";
955
956 enterLeaveNamespace(out, false /* enter */);
957
958 out << "\n#endif // " << guard << "\n";
959
960 return OK;
961}
962
Andreas Huberb82318c2016-08-02 14:45:54 -0700963status_t AST::generateProxyHeader(const std::string &outputPath) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700964 if (!AST::isInterface()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700965 // types.hal does not get a proxy header.
966 return OK;
967 }
968
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700969 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800970 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700971
Andreas Huberb82318c2016-08-02 14:45:54 -0700972 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700973 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700974 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800975 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700976 path.append(".h");
977
Andreas Huberd2943e12016-08-05 11:59:31 -0700978 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700979 FILE *file = fopen(path.c_str(), "w");
980
981 if (file == NULL) {
982 return -errno;
983 }
984
985 Formatter out(file);
986
Yifan Hongeefe4f22017-01-04 15:32:42 -0800987 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700988
989 out << "#ifndef " << guard << "\n";
990 out << "#define " << guard << "\n\n";
991
Martijn Coenen115d4282016-12-19 05:14:04 +0100992 out << "#include <hidl/HidlTransportSupport.h>\n\n";
993
Andreas Huber881227d2016-08-02 14:20:21 -0700994 std::vector<std::string> packageComponents;
995 getPackageAndVersionComponents(
996 &packageComponents, false /* cpp_compatible */);
997
Yifan Hongeefe4f22017-01-04 15:32:42 -0800998 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700999 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001000
1001 enterLeaveNamespace(out, true /* enter */);
1002 out << "\n";
1003
1004 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001005 << proxyName
1006 << " : public ::android::hardware::BpInterface<"
1007 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001008 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001009
1010 out.indent();
1011
Yifan Hongeefe4f22017-01-04 15:32:42 -08001012 out << "explicit "
1013 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001014 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -07001015 << "\n\n";
1016
Steven Moreland0b843772017-06-23 16:33:38 -07001017 generateTemplatizationLink(out);
Steven Moreland1a52e822017-07-27 13:56:29 -07001018 generateCppTag(out, "android::hardware::details::bphw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -07001019
Yifan Hong10fe0b52016-10-19 14:20:17 -07001020 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -07001021
Yifan Hong068c5522016-10-31 14:07:25 -07001022 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001023 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1024 return OK;
1025 }
1026
1027 out << "static ";
1028 method->generateCppReturnType(out);
1029 out << " _hidl_"
1030 << method->name()
1031 << "("
1032 << "::android::hardware::IInterface* _hidl_this, "
1033 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
1034
1035 if (!method->hasEmptyCppArgSignature()) {
1036 out << ", ";
1037 }
1038 method->emitCppArgSignature(out);
1039 out << ");\n";
1040 return OK;
1041 }, false /* include parents */);
1042
1043 if (err != OK) {
1044 return err;
1045 }
1046
1047 err = generateMethods(out, [&](const Method *method, const Interface *) {
Yifan Hong068c5522016-10-31 14:07:25 -07001048 method->generateCppSignature(out);
1049 out << " override;\n";
1050 return OK;
1051 });
Steven Moreland9c387612016-09-07 09:54:26 -07001052
1053 if (err != OK) {
1054 return err;
1055 }
Andreas Huber881227d2016-08-02 14:20:21 -07001056
1057 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +01001058 out << "private:\n";
1059 out.indent();
1060 out << "std::mutex _hidl_mMutex;\n"
1061 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
1062 << " _hidl_mDeathRecipients;\n";
1063 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -07001064 out << "};\n\n";
1065
1066 enterLeaveNamespace(out, false /* enter */);
1067
1068 out << "\n#endif // " << guard << "\n";
1069
1070 return OK;
1071}
1072
Steven Moreland1cbf0362017-05-09 14:32:53 -07001073status_t AST::generateCppSources(const std::string &outputPath) const {
Steven Moreland19f11b52017-05-12 18:22:21 -07001074 std::string baseName = getBaseName();
1075 const Interface *iface = getInterface();
Andreas Huber881227d2016-08-02 14:20:21 -07001076
Andreas Huberb82318c2016-08-02 14:45:54 -07001077 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -07001078 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -07001079 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -07001080 path.append(baseName);
1081
1082 if (baseName != "types") {
1083 path.append("All");
1084 }
1085
1086 path.append(".cpp");
1087
Andreas Huberd2943e12016-08-05 11:59:31 -07001088 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -07001089 FILE *file = fopen(path.c_str(), "w");
1090
1091 if (file == NULL) {
1092 return -errno;
1093 }
1094
1095 Formatter out(file);
1096
Steven Moreland623c0042017-01-13 14:42:29 -08001097 out << "#define LOG_TAG \""
1098 << mPackage.string() << "::" << baseName
1099 << "\"\n\n";
1100
Steven Moreland05cd4232016-11-21 16:01:12 -08001101 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001102 out << "#include <cutils/trace.h>\n";
1103 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Steven Moreland19f11b52017-05-12 18:22:21 -07001104 if (iface) {
Steven Moreland19d5c172016-10-20 19:20:25 -07001105 // This is a no-op for IServiceManager itself.
1106 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
1107
Yifan Hongeefe4f22017-01-04 15:32:42 -08001108 generateCppPackageInclude(out, mPackage, iface->getProxyName());
1109 generateCppPackageInclude(out, mPackage, iface->getStubName());
1110 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001111
1112 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -07001113 generateCppPackageInclude(out,
1114 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -08001115 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001116 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -08001117
1118 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001119 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -07001120 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -08001121 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -07001122 }
1123
1124 out << "\n";
1125
1126 enterLeaveNamespace(out, true /* enter */);
1127 out << "\n";
1128
Steven Moreland19f11b52017-05-12 18:22:21 -07001129 status_t err = generateTypeSource(out, iface ? iface->localName() : "");
Andreas Huber881227d2016-08-02 14:20:21 -07001130
Steven Moreland19f11b52017-05-12 18:22:21 -07001131 if (err == OK && iface) {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001132 const Interface* iface = mRootScope.getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001133
1134 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -08001135 out << "const char* "
1136 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -07001137 << "::descriptor(\""
1138 << iface->fqName().string()
1139 << "\");\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +01001140 out << "__attribute__((constructor))";
1141 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001142 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001143 out << "::android::hardware::details::gBnConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001144 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001145 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001146 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001147 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001148 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001149 out << "return new "
1150 << iface->getStubName()
Yifan Hong341112d2017-04-20 18:12:05 -07001151 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001152 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001153 << " *>(iIntf));\n";
1154 });
Yifan Hongb04de382017-02-06 15:31:52 -08001155 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001156 });
Yifan Honga159f3b2017-03-16 14:53:51 -07001157 out << "::android::hardware::details::gBsConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001158 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001159 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001160 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001161 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -08001162 << gIBaseFqName.cppName()
1163 << "> {\n";
1164 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001165 out << "return new "
1166 << iface->getPassthroughName()
Yifan Hong341112d2017-04-20 18:12:05 -07001167 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001168 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001169 << " *>(iIntf));\n";
1170 });
Yifan Hongb04de382017-02-06 15:31:52 -08001171 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001172 });
Yifan Hong158655a2016-11-08 12:34:07 -08001173 });
Martijn Coenen8adcb652017-02-03 17:37:36 +01001174 out << "};\n\n";
1175 out << "__attribute__((destructor))";
1176 out << "static void static_destructor() {\n";
1177 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001178 out << "::android::hardware::details::gBnConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001179 << iface->localName()
1180 << "::descriptor);\n";
Yifan Honga159f3b2017-03-16 14:53:51 -07001181 out << "::android::hardware::details::gBsConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001182 << iface->localName()
1183 << "::descriptor);\n";
1184 });
1185 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001186
Yifan Hongfe95aa22016-10-19 17:26:45 -07001187 err = generateInterfaceSource(out);
1188 }
1189
Steven Moreland19f11b52017-05-12 18:22:21 -07001190 if (err == OK && iface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001191 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001192 }
1193
Steven Moreland19f11b52017-05-12 18:22:21 -07001194 if (err == OK && iface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001195 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001196 }
1197
Steven Moreland19f11b52017-05-12 18:22:21 -07001198 if (err == OK && iface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001199 err = generatePassthroughSource(out);
1200 }
1201
Steven Moreland19f11b52017-05-12 18:22:21 -07001202 if (err == OK && iface) {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001203 const Interface* iface = mRootScope.getInterface();
Steven Moreland9c387612016-09-07 09:54:26 -07001204
Yifan Hongc8934042016-11-17 17:10:52 -08001205 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001206 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001207 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001208 std::string package = iface->fqName().package()
1209 + iface->fqName().atVersion();
1210
Yifan Hongeefe4f22017-01-04 15:32:42 -08001211 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001212 }
Steven Moreland40786312016-08-16 10:29:40 -07001213 }
1214
Andreas Huber6755e9d2017-04-06 11:09:07 -07001215 HidlTypeAssertion::EmitAll(out);
1216 out << "\n";
1217
Andreas Huber881227d2016-08-02 14:20:21 -07001218 enterLeaveNamespace(out, false /* enter */);
1219
1220 return err;
1221}
1222
Steven Moreland67f67b42016-09-29 08:59:02 -07001223void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001224 out.sIf(nonNull + " == nullptr", [&] {
1225 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1226 out.indent(2, [&] {
Steven Moreland610002f2017-06-16 13:02:49 -07001227 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT,\n"
1228 << "\"Null synchronous callback passed.\");\n";
Yifan Honga018ed52016-12-13 16:35:08 -08001229 });
1230 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001231}
1232
Andreas Huber881227d2016-08-02 14:20:21 -07001233status_t AST::generateTypeSource(
1234 Formatter &out, const std::string &ifaceName) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001235 return mRootScope.emitTypeDefinitions(out, ifaceName);
Andreas Huber881227d2016-08-02 14:20:21 -07001236}
1237
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001238void AST::declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& args,
1239 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001240 if (args.empty()) {
1241 return;
1242 }
1243
1244 for (const auto &arg : args) {
1245 const Type &type = arg->type();
1246
Yifan Hong3b320f82016-11-01 15:15:54 -07001247 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001248 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001249 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001250 << ";\n";
1251 }
1252
1253 out << "\n";
1254}
1255
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001256void AST::emitCppReaderWriter(Formatter& out, const std::string& parcelObj, bool parcelObjIsPointer,
1257 const NamedReference<Type>* arg, bool isReader, Type::ErrorMode mode,
1258 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001259 const Type &type = arg->type();
1260
Andreas Huber881227d2016-08-02 14:20:21 -07001261 type.emitReaderWriter(
1262 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001263 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001264 parcelObj,
1265 parcelObjIsPointer,
1266 isReader,
1267 mode);
1268}
1269
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001270void AST::emitCppResolveReferences(Formatter& out, const std::string& parcelObj,
1271 bool parcelObjIsPointer, const NamedReference<Type>* arg,
1272 bool isReader, Type::ErrorMode mode,
1273 bool addPrefixToName) const {
Yifan Hongbf459bc2016-08-23 16:50:37 -07001274 const Type &type = arg->type();
1275 if(type.needsResolveReferences()) {
1276 type.emitResolveReferences(
1277 out,
1278 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1279 isReader, // nameIsPointer
1280 parcelObj,
1281 parcelObjIsPointer,
1282 isReader,
1283 mode);
1284 }
1285}
1286
Yifan Hong068c5522016-10-31 14:07:25 -07001287status_t AST::generateProxyMethodSource(Formatter &out,
1288 const std::string &klassName,
1289 const Method *method,
1290 const Interface *superInterface) const {
Yifan Hong068c5522016-10-31 14:07:25 -07001291 method->generateCppSignature(out,
1292 klassName,
1293 true /* specify namespaces */);
1294
Martijn Coenen115d4282016-12-19 05:14:04 +01001295 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001296 out.block([&] {
1297 method->cppImpl(IMPL_PROXY, out);
1298 }).endl().endl();
Martijn Coenen115d4282016-12-19 05:14:04 +01001299 return OK;
1300 }
1301
Steven Morelandf16c5c02017-07-31 16:50:06 -07001302 status_t err = OK;
1303
1304 out.block([&] {
1305 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001306 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001307
1308 method->generateCppReturnType(out);
1309
1310 out << " _hidl_out = "
1311 << superInterface->fqName().cppNamespace()
1312 << "::"
1313 << superInterface->getProxyName()
1314 << "::_hidl_"
1315 << method->name()
1316 << "(this, this";
1317
1318 if (!method->hasEmptyCppArgSignature()) {
1319 out << ", ";
1320 }
1321
1322 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
1323 out << arg->name();
1324 });
1325
1326 if (returnsValue && elidedReturn == nullptr) {
1327 if (!method->args().empty()) {
1328 out << ", ";
1329 }
1330 out << "_hidl_cb";
1331 }
1332
1333 out << ");\n\n";
1334
1335 out << "return _hidl_out;\n";
1336 }).endl().endl();
1337
1338 return err;
1339}
1340
1341status_t AST::generateStaticProxyMethodSource(Formatter &out,
1342 const std::string &klassName,
1343 const Method *method) const {
1344 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1345 return OK;
1346 }
1347
1348 method->generateCppReturnType(out);
1349
1350 out << klassName
1351 << "::_hidl_"
1352 << method->name()
1353 << "("
1354 << "::android::hardware::IInterface *_hidl_this, "
1355 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
1356
1357 if (!method->hasEmptyCppArgSignature()) {
1358 out << ", ";
1359 }
1360
1361 method->emitCppArgSignature(out);
1362 out << ") {\n";
1363
1364 out.indent();
1365
1366 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1367 out << "bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();\n";
1368 out << "const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();\n";
1369 out << "#else\n";
1370 out << "(void) _hidl_this_instrumentor;\n";
1371 out << "#endif // __ANDROID_DEBUGGABLE__\n";
1372
1373 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001374 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Yifan Hong068c5522016-10-31 14:07:25 -07001375 if (returnsValue && elidedReturn == nullptr) {
1376 generateCheckNonNull(out, "_hidl_cb");
1377 }
1378
Steven Moreland92a08a72017-07-31 14:57:37 -07001379 generateCppInstrumentationCall(
Yifan Hong068c5522016-10-31 14:07:25 -07001380 out,
1381 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001382 method);
Yifan Hong068c5522016-10-31 14:07:25 -07001383
1384 out << "::android::hardware::Parcel _hidl_data;\n";
1385 out << "::android::hardware::Parcel _hidl_reply;\n";
1386 out << "::android::status_t _hidl_err;\n";
1387 out << "::android::hardware::Status _hidl_status;\n\n";
1388
1389 declareCppReaderLocals(
1390 out, method->results(), true /* forResults */);
1391
1392 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001393 out << klassName;
Yifan Hong068c5522016-10-31 14:07:25 -07001394 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001395 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1396
Martijn Coenenfff73352017-01-04 16:36:31 +01001397 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001398 // First DFS: write all buffers and resolve pointers for parent
1399 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001400 if (arg->type().isInterface()) {
1401 hasInterfaceArgument = true;
1402 }
Yifan Hong068c5522016-10-31 14:07:25 -07001403 emitCppReaderWriter(
1404 out,
1405 "_hidl_data",
1406 false /* parcelObjIsPointer */,
1407 arg,
1408 false /* reader */,
1409 Type::ErrorMode_Goto,
1410 false /* addPrefixToName */);
1411 }
1412
1413 // Second DFS: resolve references.
1414 for (const auto &arg : method->args()) {
1415 emitCppResolveReferences(
1416 out,
1417 "_hidl_data",
1418 false /* parcelObjIsPointer */,
1419 arg,
1420 false /* reader */,
1421 Type::ErrorMode_Goto,
1422 false /* addPrefixToName */);
1423 }
1424
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001425 if (hasInterfaceArgument) {
1426 // Start binder threadpool to handle incoming transactions
1427 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1428 }
Steven Morelandf16c5c02017-07-31 16:50:06 -07001429 out << "_hidl_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact("
Yifan Hong068c5522016-10-31 14:07:25 -07001430 << method->getSerialId()
1431 << " /* "
1432 << method->name()
1433 << " */, _hidl_data, &_hidl_reply";
1434
1435 if (method->isOneway()) {
1436 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1437 }
1438 out << ");\n";
1439
1440 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1441
1442 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001443 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001444 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1445 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1446
1447
1448 // First DFS: write all buffers and resolve pointers for parent
1449 for (const auto &arg : method->results()) {
1450 emitCppReaderWriter(
1451 out,
1452 "_hidl_reply",
1453 false /* parcelObjIsPointer */,
1454 arg,
1455 true /* reader */,
1456 Type::ErrorMode_Goto,
1457 true /* addPrefixToName */);
1458 }
1459
1460 // Second DFS: resolve references.
1461 for (const auto &arg : method->results()) {
1462 emitCppResolveReferences(
1463 out,
1464 "_hidl_reply",
1465 false /* parcelObjIsPointer */,
1466 arg,
1467 true /* reader */,
1468 Type::ErrorMode_Goto,
1469 true /* addPrefixToName */);
1470 }
1471
1472 if (returnsValue && elidedReturn == nullptr) {
1473 out << "_hidl_cb(";
1474
Yifan Hong932464e2017-03-30 15:40:22 -07001475 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001476 if (arg->type().resultNeedsDeref()) {
1477 out << "*";
1478 }
1479 out << "_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001480 });
Yifan Hong068c5522016-10-31 14:07:25 -07001481
1482 out << ");\n\n";
1483 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001484 }
Steven Morelandf16c5c02017-07-31 16:50:06 -07001485
Steven Moreland92a08a72017-07-31 14:57:37 -07001486 generateCppInstrumentationCall(
Martijn Coenen7b295242016-11-04 16:52:56 +01001487 out,
1488 InstrumentationEvent::CLIENT_API_EXIT,
1489 method);
Yifan Hong068c5522016-10-31 14:07:25 -07001490
1491 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001492 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1493 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001494 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001495 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1496 } else {
1497 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1498 out << "return ::android::hardware::Return<void>();\n\n";
1499 }
1500
1501 out.unindent();
1502 out << "_hidl_error:\n";
1503 out.indent();
1504 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1505 out << "return ::android::hardware::Return<";
1506 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001507 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001508 } else {
1509 out << "void";
1510 }
1511 out << ">(_hidl_status);\n";
1512
1513 out.unindent();
1514 out << "}\n\n";
1515 return OK;
1516}
1517
Andreas Huber881227d2016-08-02 14:20:21 -07001518status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001519 Formatter &out, const FQName &fqName) const {
1520 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001521
1522 out << klassName
1523 << "::"
1524 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001525 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001526
1527 out.indent();
1528 out.indent();
1529
1530 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001531 << "<"
1532 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001533 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001534 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001535 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001536 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001537 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001538 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001539
Andreas Huber881227d2016-08-02 14:20:21 -07001540 out.unindent();
1541 out.unindent();
1542 out << "}\n\n";
1543
Steven Morelandf16c5c02017-07-31 16:50:06 -07001544 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1545 return generateStaticProxyMethodSource(out, klassName, method);
1546 }, false /* include parents */);
1547
1548 if (err != OK) {
1549 return err;
1550 }
1551
1552 err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
Yifan Hong068c5522016-10-31 14:07:25 -07001553 return generateProxyMethodSource(out, klassName, method, superInterface);
1554 });
Andreas Huber881227d2016-08-02 14:20:21 -07001555
Yifan Hong068c5522016-10-31 14:07:25 -07001556 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001557}
1558
1559status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001560 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001561 const Interface *iface) const {
1562 const std::string interfaceName = iface->localName();
1563 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001564
Steven Moreland40786312016-08-16 10:29:40 -07001565 out << klassName
1566 << "::"
1567 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001568 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001569
1570 out.indent();
1571 out.indent();
1572
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001573 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001574 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001575 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001576 out << ": "
1577 << gIBaseFqName.getInterfaceStubFqName().cppName()
1578 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001579 }
1580
1581 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001582 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001583 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001584 << "\") { \n";
1585 out.indent();
1586 out << "_hidl_mImpl = _hidl_impl;\n";
Martijn Coenenb4d77952017-05-03 13:44:29 -07001587 out << "auto prio = ::android::hardware::details::gServicePrioMap.get("
1588 << "_hidl_impl, {SCHED_NORMAL, 0});\n";
1589 out << "mSchedPolicy = prio.sched_policy;\n";
1590 out << "mSchedPriority = prio.prio;\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001591 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001592
1593 out.unindent();
1594 out.unindent();
1595 out << "}\n\n";
1596
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001597 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001598 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001599 // class properly.
1600 out << klassName
1601 << "::"
1602 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001603 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1604 << " const std::string &HidlInstrumentor_package,"
1605 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001606
1607 out.indent();
1608 out.indent();
1609
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001610 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001611 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001612 out.indent();
1613 out << "_hidl_mImpl = _hidl_impl;\n";
1614 out.unindent();
1615
1616 out.unindent();
1617 out.unindent();
1618 out << "}\n\n";
1619 }
1620
Steven Moreland57a89362017-07-21 19:29:54 +00001621 out << klassName << "::~" << klassName << "() ";
1622 out.block([&]() {
Martijn Coenence6fd192017-07-27 13:24:34 +02001623 out << "::android::hardware::details::gBnMap.eraseIfEqual(_hidl_mImpl.get(), this);\n";
Steven Moreland57a89362017-07-21 19:29:54 +00001624 }).endl().endl();
1625
Yifan Hongbcffce22017-02-01 15:52:06 -08001626 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001627 return generateStaticStubMethodSource(out, klassName, method);
1628 }, false /* include parents */);
1629
1630 err = generateMethods(out, [&](const Method *method, const Interface *) {
Yifan Hongbcffce22017-02-01 15:52:06 -08001631 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1632 return OK;
1633 }
1634 method->generateCppSignature(out, iface->getStubName());
1635 out << " ";
1636 out.block([&] {
1637 method->cppImpl(IMPL_STUB_IMPL, out);
1638 }).endl();
1639 return OK;
1640 });
Steven Moreland60818632017-02-04 00:33:42 -08001641 if (err != OK) {
1642 return err;
1643 }
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001644
Andreas Huber881227d2016-08-02 14:20:21 -07001645 out << "::android::status_t " << klassName << "::onTransact(\n";
1646
1647 out.indent();
1648 out.indent();
1649
Iliyan Malchev549e2592016-08-10 08:59:12 -07001650 out << "uint32_t _hidl_code,\n"
1651 << "const ::android::hardware::Parcel &_hidl_data,\n"
1652 << "::android::hardware::Parcel *_hidl_reply,\n"
1653 << "uint32_t _hidl_flags,\n"
1654 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001655
1656 out.unindent();
1657
Iliyan Malchev549e2592016-08-10 08:59:12 -07001658 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001659 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001660 out.indent();
1661
Yifan Hong10fe0b52016-10-19 14:20:17 -07001662 for (const auto &tuple : iface->allMethodsFromRoot()) {
1663 const Method *method = tuple.method();
1664 const Interface *superInterface = tuple.interface();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001665
Yifan Hong10fe0b52016-10-19 14:20:17 -07001666 out << "case "
1667 << method->getSerialId()
1668 << " /* "
1669 << method->name()
1670 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001671
Yifan Hong10fe0b52016-10-19 14:20:17 -07001672 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001673
Steven Morelandf16c5c02017-07-31 16:50:06 -07001674 status_t err = generateStubSourceForMethod(out, method, superInterface);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001675
Yifan Hong10fe0b52016-10-19 14:20:17 -07001676 if (err != OK) {
1677 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001678 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001679
1680 out.unindent();
1681 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001682 }
1683
1684 out << "default:\n{\n";
1685 out.indent();
1686
Martijn Coenen225bc922017-06-27 14:39:46 -07001687 if (iface->isIBase()) {
1688 out << "(void)_hidl_flags;\n";
1689 out << "return ::android::UNKNOWN_TRANSACTION;\n";
1690 } else {
1691 out << "return ";
1692 out << gIBaseFqName.getInterfaceStubFqName().cppName();
1693 out << "::onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001694
Martijn Coenen225bc922017-06-27 14:39:46 -07001695 out.indent();
1696 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001697
Martijn Coenen225bc922017-06-27 14:39:46 -07001698 out << "_hidl_code, _hidl_data, _hidl_reply, "
1699 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001700
Martijn Coenen225bc922017-06-27 14:39:46 -07001701 out.unindent();
1702 out.unindent();
1703 }
Andreas Huber881227d2016-08-02 14:20:21 -07001704
1705 out.unindent();
1706 out << "}\n";
1707
1708 out.unindent();
1709 out << "}\n\n";
1710
Yifan Honga018ed52016-12-13 16:35:08 -08001711 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1712 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1713 out.indent(2, [&] {
1714 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1715 out << "_hidl_reply);\n";
1716 });
1717 });
Andreas Huber881227d2016-08-02 14:20:21 -07001718
Iliyan Malchev549e2592016-08-10 08:59:12 -07001719 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001720
1721 out.unindent();
1722 out << "}\n\n";
1723
1724 return OK;
1725}
1726
1727status_t AST::generateStubSourceForMethod(
Steven Morelandf16c5c02017-07-31 16:50:06 -07001728 Formatter &out,
1729 const Method *method,
1730 const Interface* superInterface) const {
1731
Martijn Coenen115d4282016-12-19 05:14:04 +01001732 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1733 method->cppImpl(IMPL_STUB, out);
1734 out << "break;\n";
1735 return OK;
1736 }
1737
Steven Morelandf16c5c02017-07-31 16:50:06 -07001738 out << "_hidl_err = "
1739 << superInterface->fqName().cppNamespace()
1740 << "::"
1741 << superInterface->getStubName()
1742 << "::_hidl_"
1743 << method->name()
1744 << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
1745 out << "break;\n";
1746
1747 return OK;
1748}
1749
1750status_t AST::generateStaticStubMethodSource(Formatter &out,
1751 const std::string &klassName,
1752 const Method *method) const {
1753 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1754 return OK;
1755 }
1756
1757 out << "::android::status_t " << klassName << "::_hidl_" << method->name() << "(\n";
1758
1759 out.indent();
1760 out.indent();
1761
1762 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
1763 << "const ::android::hardware::Parcel &_hidl_data,\n"
1764 << "::android::hardware::Parcel *_hidl_reply,\n"
1765 << "TransactCallback _hidl_cb) {\n";
1766
1767 out.unindent();
1768
1769 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1770 out << "bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();\n";
1771 out << "const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();\n";
1772 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1773
1774 out << "::android::status_t _hidl_err = ::android::OK;\n";
1775
Yifan Hongeefe4f22017-01-04 15:32:42 -08001776 out << "if (!_hidl_data.enforceInterface("
Steven Morelandf16c5c02017-07-31 16:50:06 -07001777 << klassName
1778 << "::Pure::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001779
Andreas Huber881227d2016-08-02 14:20:21 -07001780 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001781 out << "_hidl_err = ::android::BAD_TYPE;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001782 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001783 out.unindent();
1784 out << "}\n\n";
1785
Andreas Huber5e44a292016-09-27 14:52:39 -07001786 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001787
Yifan Hongbf459bc2016-08-23 16:50:37 -07001788 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001789 for (const auto &arg : method->args()) {
1790 emitCppReaderWriter(
1791 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001792 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001793 false /* parcelObjIsPointer */,
1794 arg,
1795 true /* reader */,
Steven Morelandf16c5c02017-07-31 16:50:06 -07001796 Type::ErrorMode_Return,
Andreas Huber5e44a292016-09-27 14:52:39 -07001797 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001798 }
1799
Yifan Hongbf459bc2016-08-23 16:50:37 -07001800 // Second DFS: resolve references
1801 for (const auto &arg : method->args()) {
1802 emitCppResolveReferences(
1803 out,
1804 "_hidl_data",
1805 false /* parcelObjIsPointer */,
1806 arg,
1807 true /* reader */,
Steven Morelandf16c5c02017-07-31 16:50:06 -07001808 Type::ErrorMode_Return,
Yifan Hongbf459bc2016-08-23 16:50:37 -07001809 false /* addPrefixToName */);
1810 }
1811
Steven Moreland92a08a72017-07-31 14:57:37 -07001812 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001813 out,
1814 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001815 method);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001816
Andreas Huber881227d2016-08-02 14:20:21 -07001817 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001818 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland3e787002017-08-16 14:59:54 -07001819
1820 std::string callee;
1821
1822 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL)) {
1823 callee = "_hidl_this";
1824 } else {
1825 callee = "static_cast<" + klassName + "*>(_hidl_this)->_hidl_mImpl";
1826 }
Andreas Huber881227d2016-08-02 14:20:21 -07001827
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001828 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001829 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001830 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001831 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001832 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001833 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001834 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001835
Yifan Hong932464e2017-03-30 15:40:22 -07001836 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001837 if (arg->type().resultNeedsDeref()) {
1838 out << "*";
1839 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001840 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001841 });
Andreas Huber881227d2016-08-02 14:20:21 -07001842
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001843 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001844 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1845 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001846
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001847 elidedReturn->type().emitReaderWriter(
1848 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001849 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001850 "_hidl_reply",
1851 true, /* parcelObjIsPointer */
1852 false, /* isReader */
1853 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001854
Yifan Hongbf459bc2016-08-23 16:50:37 -07001855 emitCppResolveReferences(
1856 out,
1857 "_hidl_reply",
1858 true /* parcelObjIsPointer */,
1859 elidedReturn,
1860 false /* reader */,
1861 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001862 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001863
Steven Moreland92a08a72017-07-31 14:57:37 -07001864 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001865 out,
1866 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001867 method);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001868
Iliyan Malchev549e2592016-08-10 08:59:12 -07001869 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001870 } else {
1871 if (returnsValue) {
1872 out << "bool _hidl_callbackCalled = false;\n\n";
1873 }
Andreas Huber881227d2016-08-02 14:20:21 -07001874
Yifan Hongcd2ae452017-01-31 14:33:40 -08001875 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001876
Yifan Hong932464e2017-03-30 15:40:22 -07001877 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001878 if (arg->type().resultNeedsDeref()) {
1879 out << "*";
1880 }
1881
1882 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001883 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001884
1885 if (returnsValue) {
Yifan Hong932464e2017-03-30 15:40:22 -07001886 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001887 out << ", ";
1888 }
1889
1890 out << "[&](";
1891
Yifan Hong932464e2017-03-30 15:40:22 -07001892 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001893 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001894 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001895
1896 out << ") {\n";
1897 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001898 out << "if (_hidl_callbackCalled) {\n";
1899 out.indent();
1900 out << "LOG_ALWAYS_FATAL(\""
1901 << method->name()
1902 << ": _hidl_cb called a second time, but must be called once.\");\n";
1903 out.unindent();
1904 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001905 out << "_hidl_callbackCalled = true;\n\n";
1906
Yifan Hong859e53f2016-11-14 19:08:24 -08001907 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1908 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001909
Yifan Hongbf459bc2016-08-23 16:50:37 -07001910 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001911 for (const auto &arg : method->results()) {
1912 emitCppReaderWriter(
1913 out,
1914 "_hidl_reply",
1915 true /* parcelObjIsPointer */,
1916 arg,
1917 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001918 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001919 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001920 }
1921
Yifan Hongbf459bc2016-08-23 16:50:37 -07001922 // Second DFS: resolve references
1923 for (const auto &arg : method->results()) {
1924 emitCppResolveReferences(
1925 out,
1926 "_hidl_reply",
1927 true /* parcelObjIsPointer */,
1928 arg,
1929 false /* reader */,
1930 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001931 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001932 }
1933
Steven Moreland92a08a72017-07-31 14:57:37 -07001934 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001935 out,
1936 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001937 method);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001938
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001939 out << "_hidl_cb(*_hidl_reply);\n";
1940
1941 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001942 out << "});\n\n";
1943 } else {
1944 out << ");\n\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001945 out << "(void) _hidl_cb;\n\n";
Steven Moreland92a08a72017-07-31 14:57:37 -07001946 generateCppInstrumentationCall(
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001947 out,
1948 InstrumentationEvent::SERVER_API_EXIT,
1949 method);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001950 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001951
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001952 if (returnsValue) {
1953 out << "if (!_hidl_callbackCalled) {\n";
1954 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001955 out << "LOG_ALWAYS_FATAL(\""
1956 << method->name()
1957 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001958 out.unindent();
1959 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001960 } else {
1961 out << "::android::hardware::writeToParcel("
1962 << "::android::hardware::Status::ok(), "
1963 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001964 }
Andreas Huber881227d2016-08-02 14:20:21 -07001965 }
1966
Steven Morelandf16c5c02017-07-31 16:50:06 -07001967 out << "return _hidl_err;\n";
1968 out.unindent();
1969 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001970
1971 return OK;
1972}
1973
Steven Moreland69e7c702016-09-09 11:16:32 -07001974status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
Steven Moreland19f11b52017-05-12 18:22:21 -07001975 if (!AST::isInterface()) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001976 // types.hal does not get a stub header.
1977 return OK;
1978 }
1979
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001980 const Interface* iface = mRootScope.getInterface();
Steven Moreland19f11b52017-05-12 18:22:21 -07001981 CHECK(iface != nullptr);
Steven Moreland69e7c702016-09-09 11:16:32 -07001982
Yifan Hongeefe4f22017-01-04 15:32:42 -08001983 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001984
1985 bool supportOneway = iface->hasOnewayMethods();
1986
1987 std::string path = outputPath;
1988 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1989 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1990 path.append(klassName);
1991 path.append(".h");
1992
1993 CHECK(Coordinator::MakeParentHierarchy(path));
1994 FILE *file = fopen(path.c_str(), "w");
1995
1996 if (file == NULL) {
1997 return -errno;
1998 }
1999
2000 Formatter out(file);
2001
2002 const std::string guard = makeHeaderGuard(klassName);
2003
2004 out << "#ifndef " << guard << "\n";
2005 out << "#define " << guard << "\n\n";
2006
2007 std::vector<std::string> packageComponents;
2008 getPackageAndVersionComponents(
2009 &packageComponents, false /* cpp_compatible */);
2010
Steven Moreland61d3f4b2017-04-28 17:30:38 -07002011 out << "#include <android-base/macros.h>\n";
Yifan Hongb0949432016-12-15 15:32:24 -08002012 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07002013 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07002014
Steven Moreland19f11b52017-05-12 18:22:21 -07002015 generateCppPackageInclude(out, mPackage, iface->localName());
Steven Morelandee88eed2016-10-31 17:49:00 -07002016 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07002017
Yifan Hong7a118f52016-12-07 11:21:15 -08002018 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07002019 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07002020 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07002021 }
2022
2023 enterLeaveNamespace(out, true /* enter */);
2024 out << "\n";
2025
2026 out << "struct "
2027 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -07002028 << " : " << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00002029 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07002030
2031 out.indent();
2032 out << "explicit "
2033 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07002034 << "(const ::android::sp<"
Steven Moreland19f11b52017-05-12 18:22:21 -07002035 << iface->localName()
Steven Moreland69e7c702016-09-09 11:16:32 -07002036 << "> impl);\n";
2037
Steven Moreland0b843772017-06-23 16:33:38 -07002038 out.endl();
2039 generateTemplatizationLink(out);
Steven Moreland1a52e822017-07-27 13:56:29 -07002040 generateCppTag(out, "android::hardware::details::bs_tag");
Steven Moreland0b843772017-06-23 16:33:38 -07002041
Yifan Hong068c5522016-10-31 14:07:25 -07002042 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
2043 return generatePassthroughMethod(out, method);
2044 });
Steven Moreland69e7c702016-09-09 11:16:32 -07002045
2046 if (err != OK) {
2047 return err;
2048 }
2049
2050 out.unindent();
2051 out << "private:\n";
2052 out.indent();
Steven Moreland19f11b52017-05-12 18:22:21 -07002053 out << "const ::android::sp<" << iface->localName() << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07002054
2055 if (supportOneway) {
Yifan Hongef91d362017-03-20 17:18:13 -07002056 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07002057
2058 out << "\n";
2059
2060 out << "::android::hardware::Return<void> addOnewayTask("
2061 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07002062 }
2063
2064 out.unindent();
2065
2066 out << "};\n\n";
2067
2068 enterLeaveNamespace(out, false /* enter */);
2069
2070 out << "\n#endif // " << guard << "\n";
2071
2072 return OK;
2073}
2074
Yifan Hongfe95aa22016-10-19 17:26:45 -07002075status_t AST::generateInterfaceSource(Formatter &out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07002076 const Interface* iface = mRootScope.getInterface();
Yifan Hongfe95aa22016-10-19 17:26:45 -07002077
Yifan Hong2d7126b2016-10-20 15:12:57 -07002078 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08002079 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07002080
Steven Morelandd4b068a2017-03-20 06:30:51 -07002081 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
2082 bool reserved = method->isHidlReserved();
2083
2084 if (!reserved) {
2085 out << "// no default implementation for: ";
2086 }
2087 method->generateCppSignature(out, iface->localName());
2088 if (reserved) {
2089 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07002090 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07002091 }).endl();
2092 }
2093
2094 out << "\n";
2095
2096 return OK;
2097 });
2098 if (err != OK) {
2099 return err;
2100 }
2101
Yifan Hong3d746092016-12-07 14:26:33 -08002102 for (const Interface *superType : iface->typeChain()) {
Yifan Hong200209c2017-03-29 03:39:09 -07002103 out << "// static \n::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -08002104 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -07002105 << "> "
Yifan Hongeefe4f22017-01-04 15:32:42 -08002106 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08002107 << "::castFrom("
2108 << superType->getCppArgumentType()
Yifan Hong200209c2017-03-29 03:39:09 -07002109 << " parent, bool "
2110 << (iface == superType ? "/* emitError */" : "emitError")
2111 << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08002112 out.indent();
2113 if (iface == superType) {
2114 out << "return parent;\n";
2115 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07002116 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08002117 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07002118 << superType->fqName().cppName() << ", "
Steven Moreland57a89362017-07-21 19:29:54 +00002119 << iface->getProxyName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07002120 << ">(\n";
2121 out.indent();
2122 out.indent();
2123 out << "parent, \""
2124 << iface->fqName().string()
Yifan Hong200209c2017-03-29 03:39:09 -07002125 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07002126 out.unindent();
2127 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07002128 }
Yifan Hong3d746092016-12-07 14:26:33 -08002129 out.unindent();
2130 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07002131 }
2132
2133 return OK;
2134}
2135
Steven Moreland69e7c702016-09-09 11:16:32 -07002136status_t AST::generatePassthroughSource(Formatter &out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07002137 const Interface* iface = mRootScope.getInterface();
Steven Moreland69e7c702016-09-09 11:16:32 -07002138
Yifan Hongeefe4f22017-01-04 15:32:42 -08002139 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07002140
2141 out << klassName
2142 << "::"
2143 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07002144 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07002145 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00002146 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08002147 << mPackage.string()
2148 << "\", \""
2149 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002150 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07002151 if (iface->hasOnewayMethods()) {
2152 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08002153 out.indent([&] {
Yifan Hongf01dad42017-03-20 19:03:11 -07002154 out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
Yifan Hong2cbc1472016-10-25 19:02:40 -07002155 });
2156 }
2157 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07002158
2159 if (iface->hasOnewayMethods()) {
2160 out << "::android::hardware::Return<void> "
2161 << klassName
2162 << "::addOnewayTask(std::function<void(void)> fun) {\n";
2163 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07002164 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07002165 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07002166 out << "return ::android::hardware::Status::fromExceptionCode(\n";
2167 out.indent();
2168 out.indent();
Steven Moreland610002f2017-06-16 13:02:49 -07002169 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
2170 << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
Steven Moreland67f67b42016-09-29 08:59:02 -07002171 out.unindent();
2172 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07002173 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07002174 out << "}\n";
2175
Steven Morelandd366c262016-10-11 15:29:10 -07002176 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07002177
2178 out.unindent();
2179 out << "}\n\n";
2180
2181
2182 }
2183
2184 return OK;
2185}
2186
Steven Moreland92a08a72017-07-31 14:57:37 -07002187void AST::generateCppAtraceCall(Formatter &out,
Martijn Coenen7b295242016-11-04 16:52:56 +01002188 InstrumentationEvent event,
2189 const Method *method) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07002190 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08002191 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01002192 switch (event) {
2193 case SERVER_API_ENTRY:
2194 {
2195 out << "atrace_begin(ATRACE_TAG_HAL, \""
2196 << baseString + "::server\");\n";
2197 break;
2198 }
2199 case CLIENT_API_ENTRY:
2200 {
2201 out << "atrace_begin(ATRACE_TAG_HAL, \""
2202 << baseString + "::client\");\n";
2203 break;
2204 }
2205 case PASSTHROUGH_ENTRY:
2206 {
2207 out << "atrace_begin(ATRACE_TAG_HAL, \""
2208 << baseString + "::passthrough\");\n";
2209 break;
2210 }
2211 case SERVER_API_EXIT:
2212 case CLIENT_API_EXIT:
2213 case PASSTHROUGH_EXIT:
2214 {
2215 out << "atrace_end(ATRACE_TAG_HAL);\n";
2216 break;
2217 }
2218 default:
2219 {
Steven Moreland92a08a72017-07-31 14:57:37 -07002220 LOG(FATAL) << "Unsupported instrumentation event: " << event;
Martijn Coenen7b295242016-11-04 16:52:56 +01002221 }
2222 }
Martijn Coenen7b295242016-11-04 16:52:56 +01002223}
2224
Steven Moreland92a08a72017-07-31 14:57:37 -07002225void AST::generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002226 Formatter &out,
2227 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07002228 const Method *method) const {
Steven Moreland92a08a72017-07-31 14:57:37 -07002229 generateCppAtraceCall(out, event, method);
Martijn Coenen7b295242016-11-04 16:52:56 +01002230
Steven Moreland30b76e92017-06-02 18:52:24 -07002231 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002232 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
2233 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002234 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002235 std::string event_str = "";
2236 switch (event) {
2237 case SERVER_API_ENTRY:
2238 {
2239 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
2240 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002241 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002242 << (arg->type().resultNeedsDeref() ? "" : "&")
2243 << arg->name()
2244 << ");\n";
2245 }
2246 break;
2247 }
2248 case SERVER_API_EXIT:
2249 {
2250 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07002251 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002252 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07002253 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002254 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002255 }
2256 break;
2257 }
2258 case CLIENT_API_ENTRY:
2259 {
2260 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2261 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002262 out << "_hidl_args.push_back((void *)&"
2263 << arg->name()
2264 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002265 }
2266 break;
2267 }
2268 case CLIENT_API_EXIT:
2269 {
2270 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2271 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002272 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002273 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002274 << "_hidl_out_"
2275 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002276 << ");\n";
2277 }
2278 break;
2279 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002280 case PASSTHROUGH_ENTRY:
2281 {
2282 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2283 for (const auto &arg : method->args()) {
2284 out << "_hidl_args.push_back((void *)&"
2285 << arg->name()
2286 << ");\n";
2287 }
2288 break;
2289 }
2290 case PASSTHROUGH_EXIT:
2291 {
2292 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002293 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002294 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002295 << arg->name()
2296 << ");\n";
2297 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002298 break;
2299 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002300 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002301 {
Steven Moreland92a08a72017-07-31 14:57:37 -07002302 LOG(FATAL) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002303 }
2304 }
2305
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07002306 const Interface* iface = mRootScope.getInterface();
Steven Moreland031ccf12016-10-31 15:54:38 -07002307
Steven Moreland1ab31442016-11-03 18:37:51 -07002308 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002309 out.indent();
2310 out << "callback("
2311 << event_str
2312 << ", \""
2313 << mPackage.package()
2314 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002315 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002316 << "\", \""
2317 << iface->localName()
2318 << "\", \""
2319 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002320 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002321 out.unindent();
2322 out << "}\n";
2323 out.unindent();
Steven Moreland30b76e92017-06-02 18:52:24 -07002324 out << "}\n";
2325 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002326}
2327
Andreas Huber881227d2016-08-02 14:20:21 -07002328} // namespace android