blob: a3c9a78c3b45ba689038dc3c030daf8d35b4b573 [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Huber881227d2016-08-02 14:20:21 -070017#include "AST.h"
18
19#include "Coordinator.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070020#include "EnumType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070021#include "Interface.h"
22#include "Method.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070023#include "ScalarType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070024#include "Scope.h"
25
Andreas Huberdca261f2016-08-04 13:47:51 -070026#include <algorithm>
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070027#include <hidl-util/Formatter.h>
Steven Moreland5708edf2016-11-04 15:33:31 +000028#include <hidl-util/StringHelper.h>
Andreas Huber881227d2016-08-02 14:20:21 -070029#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070030#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070031#include <vector>
32
33namespace android {
34
Andreas Huberb82318c2016-08-02 14:45:54 -070035status_t AST::generateCpp(const std::string &outputPath) const {
36 status_t err = generateInterfaceHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070037
38 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070039 err = generateStubHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070040 }
41
42 if (err == OK) {
Steven Moreland40786312016-08-16 10:29:40 -070043 err = generateHwBinderHeader(outputPath);
44 }
45
46 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070047 err = generateProxyHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070048 }
49
50 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070051 err = generateAllSource(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070052 }
53
Steven Moreland69e7c702016-09-09 11:16:32 -070054 if (err == OK) {
Yifan Hong7a118f52016-12-07 11:21:15 -080055 err = generatePassthroughHeader(outputPath);
Steven Moreland69e7c702016-09-09 11:16:32 -070056 }
57
Andreas Huber881227d2016-08-02 14:20:21 -070058 return err;
59}
60
Andreas Huber737080b2016-08-02 15:38:04 -070061void AST::getPackageComponents(
62 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070063 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070064}
65
66void AST::getPackageAndVersionComponents(
67 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070068 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070069}
70
Steven Moreland5708edf2016-11-04 15:33:31 +000071std::string AST::makeHeaderGuard(const std::string &baseName,
72 bool indicateGenerated) const {
73 std::string guard;
Andreas Huber881227d2016-08-02 14:20:21 -070074
Steven Moreland5708edf2016-11-04 15:33:31 +000075 if (indicateGenerated) {
76 guard += "HIDL_GENERATED_";
77 }
78
79 guard += StringHelper::Uppercase(mPackage.tokenName());
Andreas Huber881227d2016-08-02 14:20:21 -070080 guard += "_";
Steven Moreland5708edf2016-11-04 15:33:31 +000081 guard += StringHelper::Uppercase(baseName);
82 guard += "_H";
Andreas Huber881227d2016-08-02 14:20:21 -070083
84 return guard;
85}
86
Steven Morelandee88eed2016-10-31 17:49:00 -070087// static
88void AST::generateCppPackageInclude(
89 Formatter &out,
90 const FQName &package,
91 const std::string &klass) {
92
93 out << "#include <";
94
95 std::vector<std::string> components;
96 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
97
98 for (const auto &component : components) {
99 out << component << "/";
100 }
101
102 out << klass
103 << ".h>\n";
104}
105
Andreas Huber881227d2016-08-02 14:20:21 -0700106void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
107 std::vector<std::string> packageComponents;
108 getPackageAndVersionComponents(
109 &packageComponents, true /* cpp_compatible */);
110
111 if (enter) {
112 for (const auto &component : packageComponents) {
113 out << "namespace " << component << " {\n";
114 }
Andreas Huber0e00de42016-08-03 09:56:02 -0700115
Andreas Huber2831d512016-08-15 09:33:47 -0700116 out.setNamespace(mPackage.cppNamespace() + "::");
Andreas Huber881227d2016-08-02 14:20:21 -0700117 } else {
Andreas Huber0e00de42016-08-03 09:56:02 -0700118 out.setNamespace(std::string());
119
Andreas Huber881227d2016-08-02 14:20:21 -0700120 for (auto it = packageComponents.rbegin();
121 it != packageComponents.rend();
122 ++it) {
123 out << "} // namespace " << *it << "\n";
124 }
125 }
126}
127
Yifan Hongeefe4f22017-01-04 15:32:42 -0800128static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
129 out << "static ::android::sp<" << interfaceName << "> getService("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800130 << "const std::string &serviceName=\"default\", bool getStub=false);\n";
131 out << "static ::android::sp<" << interfaceName << "> getService("
132 << "const char serviceName[], bool getStub=false)"
133 << " { std::string str(serviceName ? serviceName : \"\");"
134 << " return getService(str, getStub); }\n";
135 out << "static ::android::sp<" << interfaceName << "> getService("
136 << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
137 // without c_str the std::string constructor is ambiguous
138 << " { std::string str(serviceName.c_str());"
139 << " return getService(str, getStub); }\n";
140 out << "static ::android::sp<" << interfaceName << "> getService("
141 << "bool getStub) { return getService(\"default\", getStub); }\n";
142 out << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800143 out << "static bool registerForNotifications(\n";
144 out.indent(2, [&] {
145 out << "const std::string &serviceName,\n"
146 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
147 << "&notification);\n";
148 });
149
150}
151
152static void implementServiceManagerInteractions(Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -0800153 const FQName &fqName, const std::string &package) {
154
155 const std::string interfaceName = fqName.getInterfaceName();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800156
157 out << "// static\n"
Yifan Hongeefe4f22017-01-04 15:32:42 -0800158 << "::android::sp<" << interfaceName << "> " << interfaceName << "::getService("
Yifan Hong64ba3d72017-03-15 11:00:28 -0700159 << "const std::string &serviceName, const bool getStub) ";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800160 out.block([&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000161 out << "::android::sp<" << interfaceName << "> iface = nullptr;\n";
Yifan Hongd3b58ed2017-01-30 14:13:10 -0800162 out << "::android::vintf::Transport transport = ::android::hardware::getTransport("
Yifan Hong152866b2017-02-28 15:34:27 -0800163 << interfaceName << "::descriptor, serviceName);\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000164
Yifan Hong64ba3d72017-03-15 11:00:28 -0700165 // TODO(b/34274385) remove sysprop check
166 out << "const bool vintfHwbinder = (transport == ::android::vintf::Transport::HWBINDER) ||\n"
167 << " (transport == ::android::vintf::Transport::TOGGLED &&\n"
168 << " ::android::hardware::details::blockingHalBinderizationEnabled());\n"
169 << "const bool vintfPassthru = (transport == ::android::vintf::Transport::PASSTHROUGH) ||\n"
170 << " (transport == ::android::vintf::Transport::TOGGLED &&\n"
171 << " !::android::hardware::details::blockingHalBinderizationEnabled());\n"
172 << "const bool vintfEmpty = (transport == ::android::vintf::Transport::EMPTY);\n\n";
173
174 // if (getStub) {
175 // getPassthroughServiceManager()->get only once.
176 // } else {
177 // if (vintfHwbinder) {
178 // while (no alive service) {
179 // waitForHwService
180 // defaultServiceManager()->get
181 // }
182 // } else if (vintfEmpty) {
183 // defaultServiceManager()->get only once.
184 // getPassthroughServiceManager()->get only once.
185 // } else if (vintfPassthru) {
186 // getPassthroughServiceManager()->get only once.
187 // }
188 // }
189
190 out.sFor("bool tried = false; "
191 "!getStub && (vintfHwbinder || (vintfEmpty && !tried)); "
192 "tried = true", [&] {
193
194 // Because this is a for loop, a "continue" statement means
195 // setting tried, and hence "break" for vintfEmpty and
196 // "retry" for vintfHwBinder
197
198 out.sIf("tried", [&] {
199 // sleep only after the first trial.
200 out << "ALOGI(\"getService: retrying in 1s...\");\n"
201 << "sleep(1);\n";
202 }).endl();
203
Steven Morelandf10af872017-01-25 16:01:56 +0000204 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800205 out.indent(2, [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000206 out << "= ::android::hardware::defaultServiceManager();\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800207 });
Yifan Hong64ba3d72017-03-15 11:00:28 -0700208 out.sIf("sm == nullptr", [&] {
209 // hwbinder is not available on this device, so future tries
210 // would also be null. I can only "break" here and
211 // (vintfEmpty) try passthrough or (vintfHwbinder) return nullptr.
212 out << "ALOGE(\"getService: defaultServiceManager() is null\");\n"
213 << "break;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800214 }).endl();
Yifan Hong64ba3d72017-03-15 11:00:28 -0700215
216 out.sIf("vintfHwbinder", [&] {
217 out << "::android::hardware::details::waitForHwService("
218 << interfaceName << "::descriptor" << ", serviceName);\n";
219 }).endl();
220
221 out << "::android::hardware::Return<::android::sp<"
222 << gIBaseFqName.cppName() << ">> ret = \n";
223 out.indent(2, [&] {
224 out << "sm->get(" << interfaceName << "::descriptor, serviceName);\n";
225 });
226
227 out.sIf("!ret.isOk()", [&] {
228 // hwservicemanager fails
229 out << "ALOGE(\"getService: defaultServiceManager()->get returns %s\", "
230 << "ret.description().c_str());\n"
231 << "continue;\n";
232 }).endl();
233
234 out << "iface = " << interfaceName << "::castFrom(ret);\n";
235 out.sIf("iface == nullptr", [&] {
236 // 1. race condition. hwservicemanager drops the service
237 // from waitForHwService to here
238 // 2. service is dead (castFrom cannot call interfaceChain)
239 // 3. returned service isn't of correct type; this is a bug
240 // to hwservicemanager or to the service itself (interfaceChain
241 // is not consistent)
242 // In all cases, try again.
243 out << "ALOGW(\"getService: found null interface\");\n"
244 << "continue;\n";
245 }).endl();
246
247 out << "return iface;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800248 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800249
Yifan Hong64ba3d72017-03-15 11:00:28 -0700250 out.sIf("getStub || vintfPassthru || vintfEmpty", [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000251 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> pm\n";
Steven Morelande3fa5da2017-01-25 07:07:53 +0000252 out.indent(2, [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000253 out << "= ::android::hardware::getPassthroughServiceManager();\n";
Steven Morelande3fa5da2017-01-25 07:07:53 +0000254 });
Steven Morelandf10af872017-01-25 16:01:56 +0000255
256 out.sIf("pm != nullptr", [&] () {
257 out << "::android::hardware::Return<::android::sp<" << gIBaseFqName.cppName() << ">> ret = \n";
258 out.indent(2, [&] {
259 out << "pm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
Steven Moreland2c2dea82017-01-18 17:24:17 -0800260 });
Steven Morelandf10af872017-01-25 16:01:56 +0000261 out.sIf("ret.isOk()", [&] {
262 out << "::android::sp<" << gIBaseFqName.cppName()
263 << "> baseInterface = ret;\n";
264 out.sIf("baseInterface != nullptr", [&]() {
265 out << "iface = new " << fqName.getInterfacePassthroughName()
266 << "(" << interfaceName << "::castFrom(baseInterface));\n";
Yifan Hong64ba3d72017-03-15 11:00:28 -0700267 }).endl();
Steven Morelandf10af872017-01-25 16:01:56 +0000268 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800269 }).endl();
270 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800271
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800272 out << "return iface;\n";
273 }).endl().endl();
274
Yifan Hongeefe4f22017-01-04 15:32:42 -0800275 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800276 << "const std::string &serviceName) ";
277 out.block([&] {
278 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
279 out.indent(2, [&] {
280 out << "= ::android::hardware::defaultServiceManager();\n";
281 });
282 out.sIf("sm == nullptr", [&] {
283 out << "return ::android::INVALID_OPERATION;\n";
284 }).endl();
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100285 out << "::android::hardware::Return<bool> ret = "
286 << "sm->add(serviceName.c_str(), this);\n"
287 << "return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800288 }).endl().endl();
289
Yifan Hongeefe4f22017-01-04 15:32:42 -0800290 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800291 out.indent(2, [&] {
292 out << "const std::string &serviceName,\n"
293 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
294 << "&notification) ";
295 });
296 out.block([&] {
297 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
298 out.indent(2, [&] {
299 out << "= ::android::hardware::defaultServiceManager();\n";
300 });
301 out.sIf("sm == nullptr", [&] {
302 out << "return false;\n";
303 }).endl();
304 out << "::android::hardware::Return<bool> success =\n";
305 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800306 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800307 out.indent(2, [&] {
308 out << "serviceName, notification);\n";
309 });
310 });
311 out << "return success.isOk() && success;\n";
312 }).endl().endl();
313}
314
Andreas Huberb82318c2016-08-02 14:45:54 -0700315status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700316
Andreas Huberb82318c2016-08-02 14:45:54 -0700317 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700318 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700319 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700320
321 std::string ifaceName;
322 bool isInterface = true;
323 if (!AST::isInterface(&ifaceName)) {
324 ifaceName = "types";
325 isInterface = false;
326 }
327 path.append(ifaceName);
328 path.append(".h");
329
Andreas Huberd2943e12016-08-05 11:59:31 -0700330 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700331 FILE *file = fopen(path.c_str(), "w");
332
333 if (file == NULL) {
334 return -errno;
335 }
336
337 Formatter out(file);
338
339 const std::string guard = makeHeaderGuard(ifaceName);
340
341 out << "#ifndef " << guard << "\n";
342 out << "#define " << guard << "\n\n";
343
Andreas Huber737080b2016-08-02 15:38:04 -0700344 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700345 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700346 }
347
348 if (!mImportedNames.empty()) {
349 out << "\n";
350 }
351
Steven Moreland0693f312016-11-09 15:06:14 -0800352 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800353 if (isIBase()) {
354 out << "// skipped #include IServiceNotification.h\n\n";
355 } else {
356 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
357 }
Steven Moreland0693f312016-11-09 15:06:14 -0800358 }
359
Yifan Hongc8934042016-11-17 17:10:52 -0800360 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700361 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700362
363 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200364 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700365 }
366
Martijn Coenenaf712c02016-11-16 15:26:27 +0100367 out << "#include <utils/NativeHandle.h>\n";
368 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700369
370 enterLeaveNamespace(out, true /* enter */);
371 out << "\n";
372
373 if (isInterface) {
374 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700375 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700376
377 const Interface *iface = mRootScope->getInterface();
378 const Interface *superType = iface->superType();
379
Steven Moreland40786312016-08-16 10:29:40 -0700380 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800381 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700382 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000383 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700384 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700385 }
386
387 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700388
389 out.indent();
390
Andreas Huber881227d2016-08-02 14:20:21 -0700391 }
392
393 status_t err = emitTypeDeclarations(out);
394
395 if (err != OK) {
396 return err;
397 }
398
399 if (isInterface) {
400 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800401
Yifan Hongc8934042016-11-17 17:10:52 -0800402 out << "virtual bool isRemote() const ";
403 if (!isIBase()) {
404 out << "override ";
405 }
406 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800407
Andreas Huber881227d2016-08-02 14:20:21 -0700408 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700409 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700410
Andreas Huber881227d2016-08-02 14:20:21 -0700411 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800412 const TypedVar *elidedReturn = method->canElideCallback();
413
414 if (elidedReturn == nullptr && returnsValue) {
415 out << "using "
416 << method->name()
417 << "_cb = std::function<void("
418 << Method::GetArgSignature(method->results(),
419 true /* specify namespaces */)
420 << ")>;\n";
421 }
Andreas Huber881227d2016-08-02 14:20:21 -0700422
Andreas Huber3599d922016-08-09 10:42:57 -0700423 method->dumpAnnotations(out);
424
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700425 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700426 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700427 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700428 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700429 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700430 }
431
432 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700433 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700434 << Method::GetArgSignature(method->args(),
435 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700436
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700437 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700438 if (!method->args().empty()) {
439 out << ", ";
440 }
441
Steven Moreland67f67b42016-09-29 08:59:02 -0700442 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700443 }
444
Yifan Hong10fe0b52016-10-19 14:20:17 -0700445 out << ")";
446 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800447 if (!isIBase()) {
448 out << " override";
449 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700450 out << " {\n";
451 out.indent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100452 method->cppImpl(IMPL_HEADER, out);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700453 out.unindent();
454 out << "\n}\n";
455 } else {
456 out << " = 0;\n";
457 }
Andreas Huber881227d2016-08-02 14:20:21 -0700458 }
Steven Moreland40786312016-08-16 10:29:40 -0700459
Yifan Hong3d746092016-12-07 14:26:33 -0800460 out << "// cast static functions\n";
461 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700462
Yifan Hong3d746092016-12-07 14:26:33 -0800463 for (const Interface *superType : iface->typeChain()) {
464 out << "static "
465 << childTypeResult
466 << " castFrom("
467 << superType->getCppArgumentType()
468 << " parent"
469 << ");\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700470 }
471
Steven Morelandd39133b2016-11-11 12:30:08 -0800472 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700473
Yifan Hongc8934042016-11-17 17:10:52 -0800474 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800475 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800476 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800477 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800478 }
Andreas Huber881227d2016-08-02 14:20:21 -0700479 }
480
481 if (isInterface) {
482 out.unindent();
483
Andreas Hubere3f769a2016-10-10 10:54:44 -0700484 out << "};\n\n";
485 }
486
487 err = mRootScope->emitGlobalTypeDeclarations(out);
488
489 if (err != OK) {
490 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700491 }
492
493 out << "\n";
494 enterLeaveNamespace(out, false /* enter */);
495
496 out << "\n#endif // " << guard << "\n";
497
498 return OK;
499}
500
Steven Moreland40786312016-08-16 10:29:40 -0700501status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
502 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800503 bool isInterface = AST::isInterface(&ifaceName);
504 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800505 std::string klassName{};
506
507 if(isInterface) {
508 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800509 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800510 } else {
511 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700512 }
513
Steven Moreland40786312016-08-16 10:29:40 -0700514 std::string path = outputPath;
515 path.append(mCoordinator->convertPackageRootToPath(mPackage));
516 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
517 path.append(klassName + ".h");
518
Yifan Hong244e82d2016-11-11 11:13:57 -0800519 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700520
521 if (file == NULL) {
522 return -errno;
523 }
524
525 Formatter out(file);
526
527 const std::string guard = makeHeaderGuard(klassName);
528
529 out << "#ifndef " << guard << "\n";
530 out << "#define " << guard << "\n\n";
531
Yifan Hong244e82d2016-11-11 11:13:57 -0800532 if (isInterface) {
533 generateCppPackageInclude(out, mPackage, ifaceName);
534 } else {
535 generateCppPackageInclude(out, mPackage, "types");
536 }
Steven Moreland40786312016-08-16 10:29:40 -0700537
Steven Morelandee88eed2016-10-31 17:49:00 -0700538 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700539
540 for (const auto &item : mImportedNames) {
541 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800542 generateCppPackageInclude(out, item, "hwtypes");
543 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800544 generateCppPackageInclude(out, item, item.getInterfaceStubName());
545 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700546 }
Steven Moreland40786312016-08-16 10:29:40 -0700547 }
548
549 out << "\n";
550
Martijn Coenen93915102016-09-01 01:35:52 +0200551 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700552 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100553 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700554
555 out << "\n";
556
557 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700558
Yifan Hong244e82d2016-11-11 11:13:57 -0800559 status_t err = mRootScope->emitGlobalHwDeclarations(out);
560 if (err != OK) {
561 return err;
562 }
Steven Moreland40786312016-08-16 10:29:40 -0700563
564 enterLeaveNamespace(out, false /* enter */);
565
566 out << "\n#endif // " << guard << "\n";
567
568 return OK;
569}
570
Andreas Huber881227d2016-08-02 14:20:21 -0700571status_t AST::emitTypeDeclarations(Formatter &out) const {
572 return mRootScope->emitTypeDeclarations(out);
573}
574
Yifan Hong7a118f52016-12-07 11:21:15 -0800575static void wrapPassthroughArg(Formatter &out,
576 const TypedVar *arg, bool addPrefixToName,
577 std::function<void(void)> handleError) {
578 if (!arg->type().isInterface()) {
579 return;
580 }
581 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
582 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
583 + arg->name();
584 const Interface &iface = static_cast<const Interface &>(arg->type());
585 out << iface.getCppStackType() << " " << wrappedName << ";\n";
586 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
587 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
588 out << wrappedName
589 << " = "
590 << iface.fqName().cppName()
Yifan Hong052425a2017-03-13 17:06:13 -0700591 << "::castFrom(::android::hardware::details::wrapPassthrough("
Yifan Hong7a118f52016-12-07 11:21:15 -0800592 << name << "));\n";
593 out.sIf(wrappedName + " == nullptr", [&] {
594 // Fatal error. Happens when the BsFoo class is not found in the binary
595 // or any dynamic libraries.
596 handleError();
597 }).endl();
598 }).sElse([&] {
599 out << wrappedName << " = " << name << ";\n";
600 }).endl().endl();
601}
602
Steven Moreland69e7c702016-09-09 11:16:32 -0700603status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700604 const Method *method) const {
605 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700606
607 out << " {\n";
608 out.indent();
609
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800610 if (method->isHidlReserved()
611 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
612 method->cppImpl(IMPL_PASSTHROUGH, out);
613 out.unindent();
614 out << "}\n\n";
615 return OK;
616 }
617
Steven Moreland69e7c702016-09-09 11:16:32 -0700618 const bool returnsValue = !method->results().empty();
619 const TypedVar *elidedReturn = method->canElideCallback();
620
Steven Moreland67f67b42016-09-29 08:59:02 -0700621 if (returnsValue && elidedReturn == nullptr) {
622 generateCheckNonNull(out, "_hidl_cb");
623 }
624
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700625 generateCppInstrumentationCall(
626 out,
627 InstrumentationEvent::PASSTHROUGH_ENTRY,
628 method);
629
Yifan Hong7a118f52016-12-07 11:21:15 -0800630
631 for (const auto &arg : method->args()) {
632 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
633 out << "return ::android::hardware::Status::fromExceptionCode(\n";
634 out.indent(2, [&] {
635 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800636 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800637 });
638 });
639 }
640
641 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700642 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700643
644 if (method->isOneway()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800645 out << "addOnewayTask([this, &_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700646 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800647 out << ", "
648 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
649 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700650 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700651 out << "] {\n";
652 out.indent();
653 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700654 }
655
656 out << "mImpl->"
657 << method->name()
658 << "(";
659
660 bool first = true;
661 for (const auto &arg : method->args()) {
662 if (!first) {
663 out << ", ";
664 }
665 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800666 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700667 }
668 if (returnsValue && elidedReturn == nullptr) {
669 if (!method->args().empty()) {
670 out << ", ";
671 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800672 out << "[&](";
673 first = true;
674 for (const auto &arg : method->results()) {
675 if (!first) {
676 out << ", ";
677 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700678
Yifan Hong7a118f52016-12-07 11:21:15 -0800679 out << "const auto &_hidl_out_"
680 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800681
682 first = false;
683 }
684
685 out << ") {\n";
686 out.indent();
687 status_t status = generateCppInstrumentationCall(
688 out,
689 InstrumentationEvent::PASSTHROUGH_EXIT,
690 method);
691 if (status != OK) {
692 return status;
693 }
694
Yifan Hong7a118f52016-12-07 11:21:15 -0800695 for (const auto &arg : method->results()) {
696 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
697 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
698 out.indent(2, [&] {
699 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800700 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800701 });
702 out << "return;\n";
703 });
704 }
705
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800706 out << "_hidl_cb(";
707 first = true;
708 for (const auto &arg : method->results()) {
709 if (!first) {
710 out << ", ";
711 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800712 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800713 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
714 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800715 }
716 out << ");\n";
717 out.unindent();
718 out << "});\n\n";
719 } else {
720 out << ");\n\n";
721 if (elidedReturn != nullptr) {
722 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800723 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800724 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000725 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800726 }
727 status_t status = generateCppInstrumentationCall(
728 out,
729 InstrumentationEvent::PASSTHROUGH_EXIT,
730 method);
731 if (status != OK) {
732 return status;
733 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700734 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700735
736 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700737 out.unindent();
738 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700739 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700740
741 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700742
743 out.unindent();
744 out << "}\n";
745
746 return OK;
747}
748
Yifan Hong068c5522016-10-31 14:07:25 -0700749status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700750
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700751 const Interface *iface = mRootScope->getInterface();
752
Yifan Hong10fe0b52016-10-19 14:20:17 -0700753 const Interface *prevIterface = nullptr;
754 for (const auto &tuple : iface->allMethodsFromRoot()) {
755 const Method *method = tuple.method();
756 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700757
Yifan Hong10fe0b52016-10-19 14:20:17 -0700758 if(prevIterface != superInterface) {
759 if (prevIterface != nullptr) {
760 out << "\n";
761 }
762 out << "// Methods from "
763 << superInterface->fullName()
764 << " follow.\n";
765 prevIterface = superInterface;
766 }
Yifan Hong068c5522016-10-31 14:07:25 -0700767 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700768
Yifan Hong10fe0b52016-10-19 14:20:17 -0700769 if (err != OK) {
770 return err;
771 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700772 }
773
Yifan Hong10fe0b52016-10-19 14:20:17 -0700774 out << "\n";
775
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700776 return OK;
777}
778
Andreas Huberb82318c2016-08-02 14:45:54 -0700779status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700780 std::string ifaceName;
781 if (!AST::isInterface(&ifaceName)) {
782 // types.hal does not get a stub header.
783 return OK;
784 }
785
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700786 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800787 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700788
Andreas Huberb82318c2016-08-02 14:45:54 -0700789 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700790 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700791 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700792 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700793 path.append(".h");
794
Andreas Huberd2943e12016-08-05 11:59:31 -0700795 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700796 FILE *file = fopen(path.c_str(), "w");
797
798 if (file == NULL) {
799 return -errno;
800 }
801
802 Formatter out(file);
803
Steven Moreland40786312016-08-16 10:29:40 -0700804 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700805
806 out << "#ifndef " << guard << "\n";
807 out << "#define " << guard << "\n\n";
808
Yifan Hongeefe4f22017-01-04 15:32:42 -0800809 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700810 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700811
812 enterLeaveNamespace(out, true /* enter */);
813 out << "\n";
814
815 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800816 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100817 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800818 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000819 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100820 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800821 out << " : public "
822 << gIBaseFqName.getInterfaceStubFqName().cppName()
823 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100824 }
Andreas Huber881227d2016-08-02 14:20:21 -0700825
826 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800827 out << "explicit "
828 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700829 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100830 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800831 out << "explicit "
832 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100833 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800834 << " const std::string& HidlInstrumentor_package,"
835 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700836 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700837 out << "::android::status_t onTransact(\n";
838 out.indent();
839 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700840 out << "uint32_t _hidl_code,\n";
841 out << "const ::android::hardware::Parcel &_hidl_data,\n";
842 out << "::android::hardware::Parcel *_hidl_reply,\n";
843 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700844 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700845 out.unindent();
846 out.unindent();
847
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100848 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
849 out.unindent();
850 out << "private:\n";
851 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800852
853 status_t err = generateMethods(out, [&](const Method *method, const Interface *iface) {
854 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
855 return OK;
856 }
857 const bool returnsValue = !method->results().empty();
858 const TypedVar *elidedReturn = method->canElideCallback();
859
860 if (elidedReturn == nullptr && returnsValue) {
861 out << "using " << method->name() << "_cb = "
862 << iface->fqName().cppName()
863 << "::" << method->name() << "_cb;\n";
864 }
865 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800866 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800867 return OK;
868 });
869 if (err != OK) {
870 return err;
871 }
872
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100873 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700874 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700875 out << "};\n\n";
876
877 enterLeaveNamespace(out, false /* enter */);
878
879 out << "\n#endif // " << guard << "\n";
880
881 return OK;
882}
883
Andreas Huberb82318c2016-08-02 14:45:54 -0700884status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700885 std::string ifaceName;
886 if (!AST::isInterface(&ifaceName)) {
887 // types.hal does not get a proxy header.
888 return OK;
889 }
890
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700891 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800892 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700893
Andreas Huberb82318c2016-08-02 14:45:54 -0700894 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700895 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700896 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800897 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700898 path.append(".h");
899
Andreas Huberd2943e12016-08-05 11:59:31 -0700900 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700901 FILE *file = fopen(path.c_str(), "w");
902
903 if (file == NULL) {
904 return -errno;
905 }
906
907 Formatter out(file);
908
Yifan Hongeefe4f22017-01-04 15:32:42 -0800909 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700910
911 out << "#ifndef " << guard << "\n";
912 out << "#define " << guard << "\n\n";
913
Martijn Coenen115d4282016-12-19 05:14:04 +0100914 out << "#include <hidl/HidlTransportSupport.h>\n\n";
915
Andreas Huber881227d2016-08-02 14:20:21 -0700916 std::vector<std::string> packageComponents;
917 getPackageAndVersionComponents(
918 &packageComponents, false /* cpp_compatible */);
919
Yifan Hongeefe4f22017-01-04 15:32:42 -0800920 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700921 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700922
923 enterLeaveNamespace(out, true /* enter */);
924 out << "\n";
925
926 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800927 << proxyName
928 << " : public ::android::hardware::BpInterface<"
929 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000930 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700931
932 out.indent();
933
Yifan Hongeefe4f22017-01-04 15:32:42 -0800934 out << "explicit "
935 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700936 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700937 << "\n\n";
938
Yifan Hong10fe0b52016-10-19 14:20:17 -0700939 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700940
Yifan Hong068c5522016-10-31 14:07:25 -0700941 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
942 method->generateCppSignature(out);
943 out << " override;\n";
944 return OK;
945 });
Steven Moreland9c387612016-09-07 09:54:26 -0700946
947 if (err != OK) {
948 return err;
949 }
Andreas Huber881227d2016-08-02 14:20:21 -0700950
951 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100952 out << "private:\n";
953 out.indent();
954 out << "std::mutex _hidl_mMutex;\n"
955 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
956 << " _hidl_mDeathRecipients;\n";
957 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700958 out << "};\n\n";
959
960 enterLeaveNamespace(out, false /* enter */);
961
962 out << "\n#endif // " << guard << "\n";
963
964 return OK;
965}
966
Andreas Huberb82318c2016-08-02 14:45:54 -0700967status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700968
Andreas Huberb82318c2016-08-02 14:45:54 -0700969 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700970 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700971 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700972
973 std::string ifaceName;
974 std::string baseName;
975
Yifan Hongfe95aa22016-10-19 17:26:45 -0700976 const Interface *iface = nullptr;
977 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700978 if (!AST::isInterface(&ifaceName)) {
979 baseName = "types";
980 isInterface = false;
981 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700982 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700983 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700984 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700985 }
986
987 path.append(baseName);
988
989 if (baseName != "types") {
990 path.append("All");
991 }
992
993 path.append(".cpp");
994
Andreas Huberd2943e12016-08-05 11:59:31 -0700995 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700996 FILE *file = fopen(path.c_str(), "w");
997
998 if (file == NULL) {
999 return -errno;
1000 }
1001
1002 Formatter out(file);
1003
Steven Moreland623c0042017-01-13 14:42:29 -08001004 out << "#define LOG_TAG \""
1005 << mPackage.string() << "::" << baseName
1006 << "\"\n\n";
1007
Steven Moreland05cd4232016-11-21 16:01:12 -08001008 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001009 out << "#include <cutils/trace.h>\n";
1010 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001011 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -07001012 // This is a no-op for IServiceManager itself.
1013 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
1014
Steven Morelandbec74ed2017-01-25 17:42:35 -08001015 // TODO(b/34274385) remove this
1016 out << "#include <hidl/LegacySupport.h>\n";
1017
Yifan Hongeefe4f22017-01-04 15:32:42 -08001018 generateCppPackageInclude(out, mPackage, iface->getProxyName());
1019 generateCppPackageInclude(out, mPackage, iface->getStubName());
1020 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001021
1022 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -07001023 generateCppPackageInclude(out,
1024 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -08001025 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001026 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -08001027
1028 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001029 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -07001030 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -08001031 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -07001032 }
1033
1034 out << "\n";
1035
1036 enterLeaveNamespace(out, true /* enter */);
1037 out << "\n";
1038
1039 status_t err = generateTypeSource(out, ifaceName);
1040
1041 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001042 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001043
1044 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -08001045 out << "const char* "
1046 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -07001047 << "::descriptor(\""
1048 << iface->fqName().string()
1049 << "\");\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +01001050 out << "__attribute__((constructor))";
1051 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001052 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001053 out << "::android::hardware::details::gBnConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001054 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001055 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001056 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001057 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001058 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001059 out << "return new "
1060 << iface->getStubName()
1061 << "(reinterpret_cast<"
1062 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001063 << " *>(iIntf));\n";
1064 });
Yifan Hongb04de382017-02-06 15:31:52 -08001065 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001066 });
Yifan Honga159f3b2017-03-16 14:53:51 -07001067 out << "::android::hardware::details::gBsConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001068 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001069 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001070 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001071 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -08001072 << gIBaseFqName.cppName()
1073 << "> {\n";
1074 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001075 out << "return new "
1076 << iface->getPassthroughName()
1077 << "(reinterpret_cast<"
1078 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001079 << " *>(iIntf));\n";
1080 });
Yifan Hongb04de382017-02-06 15:31:52 -08001081 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001082 });
Yifan Hong158655a2016-11-08 12:34:07 -08001083 });
Martijn Coenen8adcb652017-02-03 17:37:36 +01001084 out << "};\n\n";
1085 out << "__attribute__((destructor))";
1086 out << "static void static_destructor() {\n";
1087 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001088 out << "::android::hardware::details::gBnConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001089 << iface->localName()
1090 << "::descriptor);\n";
Yifan Honga159f3b2017-03-16 14:53:51 -07001091 out << "::android::hardware::details::gBsConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001092 << iface->localName()
1093 << "::descriptor);\n";
1094 });
1095 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001096
Yifan Hongfe95aa22016-10-19 17:26:45 -07001097 err = generateInterfaceSource(out);
1098 }
1099
1100 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001101 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001102 }
1103
1104 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001105 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001106 }
1107
Steven Moreland40786312016-08-16 10:29:40 -07001108 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001109 err = generatePassthroughSource(out);
1110 }
1111
1112 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001113 const Interface *iface = mRootScope->getInterface();
1114
Yifan Hongc8934042016-11-17 17:10:52 -08001115 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001116 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001117 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001118 std::string package = iface->fqName().package()
1119 + iface->fqName().atVersion();
1120
Yifan Hongeefe4f22017-01-04 15:32:42 -08001121 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001122 }
Steven Moreland40786312016-08-16 10:29:40 -07001123 }
1124
Andreas Huber881227d2016-08-02 14:20:21 -07001125 enterLeaveNamespace(out, false /* enter */);
1126
1127 return err;
1128}
1129
Steven Moreland67f67b42016-09-29 08:59:02 -07001130// static
1131void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001132 out.sIf(nonNull + " == nullptr", [&] {
1133 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1134 out.indent(2, [&] {
1135 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1136 });
1137 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001138}
1139
Andreas Huber881227d2016-08-02 14:20:21 -07001140status_t AST::generateTypeSource(
1141 Formatter &out, const std::string &ifaceName) const {
1142 return mRootScope->emitTypeDefinitions(out, ifaceName);
1143}
1144
Andreas Hubere7ff2282016-08-16 13:50:03 -07001145void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001146 Formatter &out,
1147 const std::vector<TypedVar *> &args,
1148 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001149 if (args.empty()) {
1150 return;
1151 }
1152
1153 for (const auto &arg : args) {
1154 const Type &type = arg->type();
1155
Yifan Hong3b320f82016-11-01 15:15:54 -07001156 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001157 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001158 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001159 << ";\n";
1160 }
1161
1162 out << "\n";
1163}
1164
Andreas Huber881227d2016-08-02 14:20:21 -07001165void AST::emitCppReaderWriter(
1166 Formatter &out,
1167 const std::string &parcelObj,
1168 bool parcelObjIsPointer,
1169 const TypedVar *arg,
1170 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001171 Type::ErrorMode mode,
1172 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001173 const Type &type = arg->type();
1174
Andreas Huber881227d2016-08-02 14:20:21 -07001175 type.emitReaderWriter(
1176 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001177 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001178 parcelObj,
1179 parcelObjIsPointer,
1180 isReader,
1181 mode);
1182}
1183
Yifan Hongbf459bc2016-08-23 16:50:37 -07001184void AST::emitCppResolveReferences(
1185 Formatter &out,
1186 const std::string &parcelObj,
1187 bool parcelObjIsPointer,
1188 const TypedVar *arg,
1189 bool isReader,
1190 Type::ErrorMode mode,
1191 bool addPrefixToName) const {
1192 const Type &type = arg->type();
1193 if(type.needsResolveReferences()) {
1194 type.emitResolveReferences(
1195 out,
1196 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1197 isReader, // nameIsPointer
1198 parcelObj,
1199 parcelObjIsPointer,
1200 isReader,
1201 mode);
1202 }
1203}
1204
Yifan Hong068c5522016-10-31 14:07:25 -07001205status_t AST::generateProxyMethodSource(Formatter &out,
1206 const std::string &klassName,
1207 const Method *method,
1208 const Interface *superInterface) const {
1209
1210 method->generateCppSignature(out,
1211 klassName,
1212 true /* specify namespaces */);
1213
1214 const bool returnsValue = !method->results().empty();
1215 const TypedVar *elidedReturn = method->canElideCallback();
1216
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001217 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001218
1219 out.indent();
1220
Martijn Coenen115d4282016-12-19 05:14:04 +01001221 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1222 method->cppImpl(IMPL_PROXY, out);
1223 out.unindent();
1224 out << "}\n\n";
1225 return OK;
1226 }
1227
Yifan Hong068c5522016-10-31 14:07:25 -07001228 if (returnsValue && elidedReturn == nullptr) {
1229 generateCheckNonNull(out, "_hidl_cb");
1230 }
1231
1232 status_t status = generateCppInstrumentationCall(
1233 out,
1234 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001235 method);
1236 if (status != OK) {
1237 return status;
1238 }
1239
1240 out << "::android::hardware::Parcel _hidl_data;\n";
1241 out << "::android::hardware::Parcel _hidl_reply;\n";
1242 out << "::android::status_t _hidl_err;\n";
1243 out << "::android::hardware::Status _hidl_status;\n\n";
1244
1245 declareCppReaderLocals(
1246 out, method->results(), true /* forResults */);
1247
1248 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001249 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001250 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001251 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1252
Martijn Coenenfff73352017-01-04 16:36:31 +01001253 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001254 // First DFS: write all buffers and resolve pointers for parent
1255 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001256 if (arg->type().isInterface()) {
1257 hasInterfaceArgument = true;
1258 }
Yifan Hong068c5522016-10-31 14:07:25 -07001259 emitCppReaderWriter(
1260 out,
1261 "_hidl_data",
1262 false /* parcelObjIsPointer */,
1263 arg,
1264 false /* reader */,
1265 Type::ErrorMode_Goto,
1266 false /* addPrefixToName */);
1267 }
1268
1269 // Second DFS: resolve references.
1270 for (const auto &arg : method->args()) {
1271 emitCppResolveReferences(
1272 out,
1273 "_hidl_data",
1274 false /* parcelObjIsPointer */,
1275 arg,
1276 false /* reader */,
1277 Type::ErrorMode_Goto,
1278 false /* addPrefixToName */);
1279 }
1280
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001281 if (hasInterfaceArgument) {
1282 // Start binder threadpool to handle incoming transactions
1283 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1284 }
Yifan Hong068c5522016-10-31 14:07:25 -07001285 out << "_hidl_err = remote()->transact("
1286 << method->getSerialId()
1287 << " /* "
1288 << method->name()
1289 << " */, _hidl_data, &_hidl_reply";
1290
1291 if (method->isOneway()) {
1292 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1293 }
1294 out << ");\n";
1295
1296 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1297
1298 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001299 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001300 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1301 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1302
1303
1304 // First DFS: write all buffers and resolve pointers for parent
1305 for (const auto &arg : method->results()) {
1306 emitCppReaderWriter(
1307 out,
1308 "_hidl_reply",
1309 false /* parcelObjIsPointer */,
1310 arg,
1311 true /* reader */,
1312 Type::ErrorMode_Goto,
1313 true /* addPrefixToName */);
1314 }
1315
1316 // Second DFS: resolve references.
1317 for (const auto &arg : method->results()) {
1318 emitCppResolveReferences(
1319 out,
1320 "_hidl_reply",
1321 false /* parcelObjIsPointer */,
1322 arg,
1323 true /* reader */,
1324 Type::ErrorMode_Goto,
1325 true /* addPrefixToName */);
1326 }
1327
1328 if (returnsValue && elidedReturn == nullptr) {
1329 out << "_hidl_cb(";
1330
1331 bool first = true;
1332 for (const auto &arg : method->results()) {
1333 if (!first) {
1334 out << ", ";
1335 }
1336
1337 if (arg->type().resultNeedsDeref()) {
1338 out << "*";
1339 }
1340 out << "_hidl_out_" << arg->name();
1341
1342 first = false;
1343 }
1344
1345 out << ");\n\n";
1346 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001347 }
1348 status = generateCppInstrumentationCall(
1349 out,
1350 InstrumentationEvent::CLIENT_API_EXIT,
1351 method);
1352 if (status != OK) {
1353 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001354 }
1355
1356 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001357 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1358 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001359 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001360 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1361 } else {
1362 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1363 out << "return ::android::hardware::Return<void>();\n\n";
1364 }
1365
1366 out.unindent();
1367 out << "_hidl_error:\n";
1368 out.indent();
1369 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1370 out << "return ::android::hardware::Return<";
1371 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001372 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001373 } else {
1374 out << "void";
1375 }
1376 out << ">(_hidl_status);\n";
1377
1378 out.unindent();
1379 out << "}\n\n";
1380 return OK;
1381}
1382
Andreas Huber881227d2016-08-02 14:20:21 -07001383status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001384 Formatter &out, const FQName &fqName) const {
1385 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001386
1387 out << klassName
1388 << "::"
1389 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001390 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001391
1392 out.indent();
1393 out.indent();
1394
1395 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001396 << "<"
1397 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001398 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001399 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001400 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001401 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001402 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001403 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001404
Andreas Huber881227d2016-08-02 14:20:21 -07001405 out.unindent();
1406 out.unindent();
1407 out << "}\n\n";
1408
Yifan Hong068c5522016-10-31 14:07:25 -07001409 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1410 return generateProxyMethodSource(out, klassName, method, superInterface);
1411 });
Andreas Huber881227d2016-08-02 14:20:21 -07001412
Yifan Hong068c5522016-10-31 14:07:25 -07001413 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001414}
1415
1416status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001417 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001418 const Interface *iface) const {
1419 const std::string interfaceName = iface->localName();
1420 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001421
Steven Moreland40786312016-08-16 10:29:40 -07001422 out << klassName
1423 << "::"
1424 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001425 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001426
1427 out.indent();
1428 out.indent();
1429
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001430 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001431 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001432 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001433 out << ": "
1434 << gIBaseFqName.getInterfaceStubFqName().cppName()
1435 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001436 }
1437
1438 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001439 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001440 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001441 << "\") { \n";
1442 out.indent();
1443 out << "_hidl_mImpl = _hidl_impl;\n";
1444 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001445
1446 out.unindent();
1447 out.unindent();
1448 out << "}\n\n";
1449
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001450 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001451 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001452 // class properly.
1453 out << klassName
1454 << "::"
1455 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001456 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1457 << " const std::string &HidlInstrumentor_package,"
1458 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001459
1460 out.indent();
1461 out.indent();
1462
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001463 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001464 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001465 out.indent();
1466 out << "_hidl_mImpl = _hidl_impl;\n";
1467 out.unindent();
1468
1469 out.unindent();
1470 out.unindent();
1471 out << "}\n\n";
1472 }
1473
Yifan Hongbcffce22017-02-01 15:52:06 -08001474 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1475 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1476 return OK;
1477 }
1478 method->generateCppSignature(out, iface->getStubName());
1479 out << " ";
1480 out.block([&] {
1481 method->cppImpl(IMPL_STUB_IMPL, out);
1482 }).endl();
1483 return OK;
1484 });
Steven Moreland60818632017-02-04 00:33:42 -08001485 if (err != OK) {
1486 return err;
1487 }
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001488
Andreas Huber881227d2016-08-02 14:20:21 -07001489 out << "::android::status_t " << klassName << "::onTransact(\n";
1490
1491 out.indent();
1492 out.indent();
1493
Iliyan Malchev549e2592016-08-10 08:59:12 -07001494 out << "uint32_t _hidl_code,\n"
1495 << "const ::android::hardware::Parcel &_hidl_data,\n"
1496 << "::android::hardware::Parcel *_hidl_reply,\n"
1497 << "uint32_t _hidl_flags,\n"
1498 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001499
1500 out.unindent();
1501
Iliyan Malchev549e2592016-08-10 08:59:12 -07001502 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001503 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001504 out.indent();
1505
Yifan Hong10fe0b52016-10-19 14:20:17 -07001506 for (const auto &tuple : iface->allMethodsFromRoot()) {
1507 const Method *method = tuple.method();
1508 const Interface *superInterface = tuple.interface();
1509 out << "case "
1510 << method->getSerialId()
1511 << " /* "
1512 << method->name()
1513 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001514
Yifan Hong10fe0b52016-10-19 14:20:17 -07001515 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001516
Yifan Hong10fe0b52016-10-19 14:20:17 -07001517 status_t err =
1518 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001519
Yifan Hong10fe0b52016-10-19 14:20:17 -07001520 if (err != OK) {
1521 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001522 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001523
1524 out.unindent();
1525 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001526 }
1527
1528 out << "default:\n{\n";
1529 out.indent();
1530
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001531 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001532
1533 out.indent();
1534 out.indent();
1535
Iliyan Malchev549e2592016-08-10 08:59:12 -07001536 out << "_hidl_code, _hidl_data, _hidl_reply, "
1537 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001538
1539 out.unindent();
1540 out.unindent();
1541
1542 out.unindent();
1543 out << "}\n";
1544
1545 out.unindent();
1546 out << "}\n\n";
1547
Yifan Honga018ed52016-12-13 16:35:08 -08001548 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1549 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1550 out.indent(2, [&] {
1551 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1552 out << "_hidl_reply);\n";
1553 });
1554 });
Andreas Huber881227d2016-08-02 14:20:21 -07001555
Iliyan Malchev549e2592016-08-10 08:59:12 -07001556 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001557
1558 out.unindent();
1559 out << "}\n\n";
1560
1561 return OK;
1562}
1563
1564status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001565 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001566 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1567 method->cppImpl(IMPL_STUB, out);
1568 out << "break;\n";
1569 return OK;
1570 }
1571
Yifan Hongeefe4f22017-01-04 15:32:42 -08001572 out << "if (!_hidl_data.enforceInterface("
1573 << iface->fullName()
1574 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001575
Andreas Huber881227d2016-08-02 14:20:21 -07001576 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001577 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001578 out << "break;\n";
1579 out.unindent();
1580 out << "}\n\n";
1581
Andreas Huber5e44a292016-09-27 14:52:39 -07001582 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001583
Yifan Hongbf459bc2016-08-23 16:50:37 -07001584 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001585 for (const auto &arg : method->args()) {
1586 emitCppReaderWriter(
1587 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001588 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001589 false /* parcelObjIsPointer */,
1590 arg,
1591 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001592 Type::ErrorMode_Break,
1593 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001594 }
1595
Yifan Hongbf459bc2016-08-23 16:50:37 -07001596 // Second DFS: resolve references
1597 for (const auto &arg : method->args()) {
1598 emitCppResolveReferences(
1599 out,
1600 "_hidl_data",
1601 false /* parcelObjIsPointer */,
1602 arg,
1603 true /* reader */,
1604 Type::ErrorMode_Break,
1605 false /* addPrefixToName */);
1606 }
1607
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001608 status_t status = generateCppInstrumentationCall(
1609 out,
1610 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001611 method);
1612 if (status != OK) {
1613 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001614 }
1615
Andreas Huber881227d2016-08-02 14:20:21 -07001616 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001617 const TypedVar *elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -08001618 const std::string callee =
1619 (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL))
1620 ? "this" : "_hidl_mImpl";
Andreas Huber881227d2016-08-02 14:20:21 -07001621
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001622 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001623 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001624 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001625 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001626 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001627 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001628 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001629
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001630 bool first = true;
1631 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001632 if (!first) {
1633 out << ", ";
1634 }
1635
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001636 if (arg->type().resultNeedsDeref()) {
1637 out << "*";
1638 }
1639
1640 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001641
1642 first = false;
1643 }
1644
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001645 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001646 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1647 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001648
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001649 elidedReturn->type().emitReaderWriter(
1650 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001651 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001652 "_hidl_reply",
1653 true, /* parcelObjIsPointer */
1654 false, /* isReader */
1655 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001656
Yifan Hongbf459bc2016-08-23 16:50:37 -07001657 emitCppResolveReferences(
1658 out,
1659 "_hidl_reply",
1660 true /* parcelObjIsPointer */,
1661 elidedReturn,
1662 false /* reader */,
1663 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001664 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001665
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001666 status_t status = generateCppInstrumentationCall(
1667 out,
1668 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001669 method);
1670 if (status != OK) {
1671 return status;
1672 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001673
Iliyan Malchev549e2592016-08-10 08:59:12 -07001674 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001675 } else {
1676 if (returnsValue) {
1677 out << "bool _hidl_callbackCalled = false;\n\n";
1678 }
Andreas Huber881227d2016-08-02 14:20:21 -07001679
Yifan Hongcd2ae452017-01-31 14:33:40 -08001680 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001681
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001682 bool first = true;
1683 for (const auto &arg : method->args()) {
1684 if (!first) {
1685 out << ", ";
1686 }
Andreas Huber881227d2016-08-02 14:20:21 -07001687
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001688 if (arg->type().resultNeedsDeref()) {
1689 out << "*";
1690 }
1691
1692 out << arg->name();
1693
1694 first = false;
1695 }
1696
1697 if (returnsValue) {
1698 if (!first) {
1699 out << ", ";
1700 }
1701
1702 out << "[&](";
1703
1704 first = true;
1705 for (const auto &arg : method->results()) {
1706 if (!first) {
1707 out << ", ";
1708 }
1709
Yifan Honga47eef32016-12-12 10:38:54 -08001710 out << "const auto &_hidl_out_" << arg->name();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001711
1712 first = false;
1713 }
1714
1715 out << ") {\n";
1716 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001717 out << "if (_hidl_callbackCalled) {\n";
1718 out.indent();
1719 out << "LOG_ALWAYS_FATAL(\""
1720 << method->name()
1721 << ": _hidl_cb called a second time, but must be called once.\");\n";
1722 out.unindent();
1723 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001724 out << "_hidl_callbackCalled = true;\n\n";
1725
Yifan Hong859e53f2016-11-14 19:08:24 -08001726 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1727 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001728
Yifan Hongbf459bc2016-08-23 16:50:37 -07001729 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001730 for (const auto &arg : method->results()) {
1731 emitCppReaderWriter(
1732 out,
1733 "_hidl_reply",
1734 true /* parcelObjIsPointer */,
1735 arg,
1736 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001737 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001738 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001739 }
1740
Yifan Hongbf459bc2016-08-23 16:50:37 -07001741 // Second DFS: resolve references
1742 for (const auto &arg : method->results()) {
1743 emitCppResolveReferences(
1744 out,
1745 "_hidl_reply",
1746 true /* parcelObjIsPointer */,
1747 arg,
1748 false /* reader */,
1749 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001750 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001751 }
1752
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001753 status_t status = generateCppInstrumentationCall(
1754 out,
1755 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001756 method);
1757 if (status != OK) {
1758 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001759 }
1760
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001761 out << "_hidl_cb(*_hidl_reply);\n";
1762
1763 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001764 out << "});\n\n";
1765 } else {
1766 out << ");\n\n";
1767 status_t status = generateCppInstrumentationCall(
1768 out,
1769 InstrumentationEvent::SERVER_API_EXIT,
1770 method);
1771 if (status != OK) {
1772 return status;
1773 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001774 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001775
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001776 if (returnsValue) {
1777 out << "if (!_hidl_callbackCalled) {\n";
1778 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001779 out << "LOG_ALWAYS_FATAL(\""
1780 << method->name()
1781 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001782 out.unindent();
1783 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001784 } else {
1785 out << "::android::hardware::writeToParcel("
1786 << "::android::hardware::Status::ok(), "
1787 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001788 }
Andreas Huber881227d2016-08-02 14:20:21 -07001789 }
1790
1791 out << "break;\n";
1792
1793 return OK;
1794}
1795
Steven Moreland69e7c702016-09-09 11:16:32 -07001796status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1797 std::string ifaceName;
1798 if (!AST::isInterface(&ifaceName)) {
1799 // types.hal does not get a stub header.
1800 return OK;
1801 }
1802
1803 const Interface *iface = mRootScope->getInterface();
1804
Yifan Hongeefe4f22017-01-04 15:32:42 -08001805 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001806
1807 bool supportOneway = iface->hasOnewayMethods();
1808
1809 std::string path = outputPath;
1810 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1811 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1812 path.append(klassName);
1813 path.append(".h");
1814
1815 CHECK(Coordinator::MakeParentHierarchy(path));
1816 FILE *file = fopen(path.c_str(), "w");
1817
1818 if (file == NULL) {
1819 return -errno;
1820 }
1821
1822 Formatter out(file);
1823
1824 const std::string guard = makeHeaderGuard(klassName);
1825
1826 out << "#ifndef " << guard << "\n";
1827 out << "#define " << guard << "\n\n";
1828
1829 std::vector<std::string> packageComponents;
1830 getPackageAndVersionComponents(
1831 &packageComponents, false /* cpp_compatible */);
1832
Yifan Hongb0949432016-12-15 15:32:24 -08001833 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001834 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001835
1836 generateCppPackageInclude(out, mPackage, ifaceName);
1837 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001838
Yifan Hong7a118f52016-12-07 11:21:15 -08001839 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001840 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001841 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001842 }
1843
1844 enterLeaveNamespace(out, true /* enter */);
1845 out << "\n";
1846
1847 out << "struct "
1848 << klassName
1849 << " : " << ifaceName
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001850 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001851
1852 out.indent();
1853 out << "explicit "
1854 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001855 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001856 << ifaceName
1857 << "> impl);\n";
1858
Yifan Hong068c5522016-10-31 14:07:25 -07001859 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1860 return generatePassthroughMethod(out, method);
1861 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001862
1863 if (err != OK) {
1864 return err;
1865 }
1866
1867 out.unindent();
1868 out << "private:\n";
1869 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001870 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001871
1872 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001873 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001874
1875 out << "\n";
1876
1877 out << "::android::hardware::Return<void> addOnewayTask("
1878 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001879 }
1880
1881 out.unindent();
1882
1883 out << "};\n\n";
1884
1885 enterLeaveNamespace(out, false /* enter */);
1886
1887 out << "\n#endif // " << guard << "\n";
1888
1889 return OK;
1890}
1891
Yifan Hongfe95aa22016-10-19 17:26:45 -07001892status_t AST::generateInterfaceSource(Formatter &out) const {
1893 const Interface *iface = mRootScope->getInterface();
1894
Yifan Hong2d7126b2016-10-20 15:12:57 -07001895 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001896 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001897
Yifan Hong3d746092016-12-07 14:26:33 -08001898 for (const Interface *superType : iface->typeChain()) {
1899 out << "// static \n"
1900 << childTypeResult
Yifan Hongeefe4f22017-01-04 15:32:42 -08001901 << " "
1902 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001903 << "::castFrom("
1904 << superType->getCppArgumentType()
1905 << " parent) {\n";
1906 out.indent();
1907 if (iface == superType) {
1908 out << "return parent;\n";
1909 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001910 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001911 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001912 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001913 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001914 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001915 << ">(\n";
1916 out.indent();
1917 out.indent();
1918 out << "parent, \""
1919 << iface->fqName().string()
1920 << "\");\n";
1921 out.unindent();
1922 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001923 }
Yifan Hong3d746092016-12-07 14:26:33 -08001924 out.unindent();
1925 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001926 }
1927
1928 return OK;
1929}
1930
Steven Moreland69e7c702016-09-09 11:16:32 -07001931status_t AST::generatePassthroughSource(Formatter &out) const {
1932 const Interface *iface = mRootScope->getInterface();
1933
Yifan Hongeefe4f22017-01-04 15:32:42 -08001934 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001935
1936 out << klassName
1937 << "::"
1938 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001939 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001940 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001941 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001942 << mPackage.string()
1943 << "\", \""
1944 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001945 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001946 if (iface->hasOnewayMethods()) {
1947 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001948 out.indent([&] {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001949 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1950 });
1951 }
1952 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001953
1954 if (iface->hasOnewayMethods()) {
1955 out << "::android::hardware::Return<void> "
1956 << klassName
1957 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1958 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001959 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001960 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001961 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1962 out.indent();
1963 out.indent();
1964 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1965 out.unindent();
1966 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001967 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001968 out << "}\n";
1969
Steven Morelandd366c262016-10-11 15:29:10 -07001970 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001971
1972 out.unindent();
1973 out << "}\n\n";
1974
1975
1976 }
1977
1978 return OK;
1979}
1980
Martijn Coenen7b295242016-11-04 16:52:56 +01001981status_t AST::generateCppAtraceCall(Formatter &out,
1982 InstrumentationEvent event,
1983 const Method *method) const {
1984 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001985 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001986 switch (event) {
1987 case SERVER_API_ENTRY:
1988 {
1989 out << "atrace_begin(ATRACE_TAG_HAL, \""
1990 << baseString + "::server\");\n";
1991 break;
1992 }
1993 case CLIENT_API_ENTRY:
1994 {
1995 out << "atrace_begin(ATRACE_TAG_HAL, \""
1996 << baseString + "::client\");\n";
1997 break;
1998 }
1999 case PASSTHROUGH_ENTRY:
2000 {
2001 out << "atrace_begin(ATRACE_TAG_HAL, \""
2002 << baseString + "::passthrough\");\n";
2003 break;
2004 }
2005 case SERVER_API_EXIT:
2006 case CLIENT_API_EXIT:
2007 case PASSTHROUGH_EXIT:
2008 {
2009 out << "atrace_end(ATRACE_TAG_HAL);\n";
2010 break;
2011 }
2012 default:
2013 {
2014 LOG(ERROR) << "Unsupported instrumentation event: " << event;
2015 return UNKNOWN_ERROR;
2016 }
2017 }
2018
2019 return OK;
2020}
2021
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002022status_t AST::generateCppInstrumentationCall(
2023 Formatter &out,
2024 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07002025 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01002026 status_t err = generateCppAtraceCall(out, event, method);
2027 if (err != OK) {
2028 return err;
2029 }
2030
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002031 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
2032 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002033 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002034 std::string event_str = "";
2035 switch (event) {
2036 case SERVER_API_ENTRY:
2037 {
2038 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
2039 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002040 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002041 << (arg->type().resultNeedsDeref() ? "" : "&")
2042 << arg->name()
2043 << ");\n";
2044 }
2045 break;
2046 }
2047 case SERVER_API_EXIT:
2048 {
2049 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07002050 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002051 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07002052 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002053 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002054 }
2055 break;
2056 }
2057 case CLIENT_API_ENTRY:
2058 {
2059 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2060 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002061 out << "_hidl_args.push_back((void *)&"
2062 << arg->name()
2063 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002064 }
2065 break;
2066 }
2067 case CLIENT_API_EXIT:
2068 {
2069 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2070 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002071 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002072 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002073 << "_hidl_out_"
2074 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002075 << ");\n";
2076 }
2077 break;
2078 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002079 case PASSTHROUGH_ENTRY:
2080 {
2081 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2082 for (const auto &arg : method->args()) {
2083 out << "_hidl_args.push_back((void *)&"
2084 << arg->name()
2085 << ");\n";
2086 }
2087 break;
2088 }
2089 case PASSTHROUGH_EXIT:
2090 {
2091 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002092 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002093 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002094 << arg->name()
2095 << ");\n";
2096 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002097 break;
2098 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002099 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002100 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002101 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002102 return UNKNOWN_ERROR;
2103 }
2104 }
2105
Steven Moreland031ccf12016-10-31 15:54:38 -07002106 const Interface *iface = mRootScope->getInterface();
2107
Steven Moreland1ab31442016-11-03 18:37:51 -07002108 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002109 out.indent();
2110 out << "callback("
2111 << event_str
2112 << ", \""
2113 << mPackage.package()
2114 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002115 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002116 << "\", \""
2117 << iface->localName()
2118 << "\", \""
2119 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002120 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002121 out.unindent();
2122 out << "}\n";
2123 out.unindent();
2124 out << "}\n\n";
2125
2126 return OK;
2127}
2128
Andreas Huber881227d2016-08-02 14:20:21 -07002129} // namespace android