blob: 26765bb0f28ff6bb034f088fc00248ea513ecb3c [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 Hong31f07ff2017-03-21 18:56:35 +0000159 << "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 Hong31f07ff2017-03-21 18:56:35 +0000165 // 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 Hong31f07ff2017-03-21 18:56:35 +0000208 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 Hong31f07ff2017-03-21 18:56:35 +0000215
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 Hong31f07ff2017-03-21 18:56:35 +0000250 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 Hong31f07ff2017-03-21 18:56:35 +0000267 }).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 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700451 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700452 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700453 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700454 }
Steven Moreland40786312016-08-16 10:29:40 -0700455
Yifan Hong3d746092016-12-07 14:26:33 -0800456 out << "// cast static functions\n";
457 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700458
Yifan Hong3d746092016-12-07 14:26:33 -0800459 for (const Interface *superType : iface->typeChain()) {
460 out << "static "
461 << childTypeResult
462 << " castFrom("
463 << superType->getCppArgumentType()
464 << " parent"
465 << ");\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700466 }
467
Steven Morelandd39133b2016-11-11 12:30:08 -0800468 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700469
Yifan Hongc8934042016-11-17 17:10:52 -0800470 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800471 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800472 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800473 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800474 }
Andreas Huber881227d2016-08-02 14:20:21 -0700475 }
476
477 if (isInterface) {
478 out.unindent();
479
Andreas Hubere3f769a2016-10-10 10:54:44 -0700480 out << "};\n\n";
481 }
482
483 err = mRootScope->emitGlobalTypeDeclarations(out);
484
485 if (err != OK) {
486 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700487 }
488
489 out << "\n";
490 enterLeaveNamespace(out, false /* enter */);
491
492 out << "\n#endif // " << guard << "\n";
493
494 return OK;
495}
496
Steven Moreland40786312016-08-16 10:29:40 -0700497status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
498 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800499 bool isInterface = AST::isInterface(&ifaceName);
500 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800501 std::string klassName{};
502
503 if(isInterface) {
504 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800505 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800506 } else {
507 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700508 }
509
Steven Moreland40786312016-08-16 10:29:40 -0700510 std::string path = outputPath;
511 path.append(mCoordinator->convertPackageRootToPath(mPackage));
512 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
513 path.append(klassName + ".h");
514
Yifan Hong244e82d2016-11-11 11:13:57 -0800515 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700516
517 if (file == NULL) {
518 return -errno;
519 }
520
521 Formatter out(file);
522
523 const std::string guard = makeHeaderGuard(klassName);
524
525 out << "#ifndef " << guard << "\n";
526 out << "#define " << guard << "\n\n";
527
Yifan Hong244e82d2016-11-11 11:13:57 -0800528 if (isInterface) {
529 generateCppPackageInclude(out, mPackage, ifaceName);
530 } else {
531 generateCppPackageInclude(out, mPackage, "types");
532 }
Steven Moreland40786312016-08-16 10:29:40 -0700533
Steven Morelandee88eed2016-10-31 17:49:00 -0700534 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700535
536 for (const auto &item : mImportedNames) {
537 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800538 generateCppPackageInclude(out, item, "hwtypes");
539 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800540 generateCppPackageInclude(out, item, item.getInterfaceStubName());
541 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700542 }
Steven Moreland40786312016-08-16 10:29:40 -0700543 }
544
545 out << "\n";
546
Martijn Coenen93915102016-09-01 01:35:52 +0200547 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700548 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100549 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700550
551 out << "\n";
552
553 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700554
Yifan Hong244e82d2016-11-11 11:13:57 -0800555 status_t err = mRootScope->emitGlobalHwDeclarations(out);
556 if (err != OK) {
557 return err;
558 }
Steven Moreland40786312016-08-16 10:29:40 -0700559
560 enterLeaveNamespace(out, false /* enter */);
561
562 out << "\n#endif // " << guard << "\n";
563
564 return OK;
565}
566
Andreas Huber881227d2016-08-02 14:20:21 -0700567status_t AST::emitTypeDeclarations(Formatter &out) const {
568 return mRootScope->emitTypeDeclarations(out);
569}
570
Yifan Hong7a118f52016-12-07 11:21:15 -0800571static void wrapPassthroughArg(Formatter &out,
572 const TypedVar *arg, bool addPrefixToName,
573 std::function<void(void)> handleError) {
574 if (!arg->type().isInterface()) {
575 return;
576 }
577 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
578 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
579 + arg->name();
580 const Interface &iface = static_cast<const Interface &>(arg->type());
581 out << iface.getCppStackType() << " " << wrappedName << ";\n";
582 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
583 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
584 out << wrappedName
585 << " = "
586 << iface.fqName().cppName()
Yifan Hong052425a2017-03-13 17:06:13 -0700587 << "::castFrom(::android::hardware::details::wrapPassthrough("
Yifan Hong7a118f52016-12-07 11:21:15 -0800588 << name << "));\n";
589 out.sIf(wrappedName + " == nullptr", [&] {
590 // Fatal error. Happens when the BsFoo class is not found in the binary
591 // or any dynamic libraries.
592 handleError();
593 }).endl();
594 }).sElse([&] {
595 out << wrappedName << " = " << name << ";\n";
596 }).endl().endl();
597}
598
Steven Moreland69e7c702016-09-09 11:16:32 -0700599status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700600 const Method *method) const {
601 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700602
603 out << " {\n";
604 out.indent();
605
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800606 if (method->isHidlReserved()
607 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
608 method->cppImpl(IMPL_PASSTHROUGH, out);
609 out.unindent();
610 out << "}\n\n";
611 return OK;
612 }
613
Steven Moreland69e7c702016-09-09 11:16:32 -0700614 const bool returnsValue = !method->results().empty();
615 const TypedVar *elidedReturn = method->canElideCallback();
616
Steven Moreland67f67b42016-09-29 08:59:02 -0700617 if (returnsValue && elidedReturn == nullptr) {
618 generateCheckNonNull(out, "_hidl_cb");
619 }
620
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700621 generateCppInstrumentationCall(
622 out,
623 InstrumentationEvent::PASSTHROUGH_ENTRY,
624 method);
625
Yifan Hong7a118f52016-12-07 11:21:15 -0800626
627 for (const auto &arg : method->args()) {
628 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
629 out << "return ::android::hardware::Status::fromExceptionCode(\n";
630 out.indent(2, [&] {
631 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800632 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800633 });
634 });
635 }
636
637 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700638 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700639
640 if (method->isOneway()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800641 out << "addOnewayTask([this, &_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700642 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800643 out << ", "
644 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
645 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700646 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700647 out << "] {\n";
648 out.indent();
649 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700650 }
651
652 out << "mImpl->"
653 << method->name()
654 << "(";
655
656 bool first = true;
657 for (const auto &arg : method->args()) {
658 if (!first) {
659 out << ", ";
660 }
661 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800662 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700663 }
664 if (returnsValue && elidedReturn == nullptr) {
665 if (!method->args().empty()) {
666 out << ", ";
667 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800668 out << "[&](";
669 first = true;
670 for (const auto &arg : method->results()) {
671 if (!first) {
672 out << ", ";
673 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700674
Yifan Hong7a118f52016-12-07 11:21:15 -0800675 out << "const auto &_hidl_out_"
676 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800677
678 first = false;
679 }
680
681 out << ") {\n";
682 out.indent();
683 status_t status = generateCppInstrumentationCall(
684 out,
685 InstrumentationEvent::PASSTHROUGH_EXIT,
686 method);
687 if (status != OK) {
688 return status;
689 }
690
Yifan Hong7a118f52016-12-07 11:21:15 -0800691 for (const auto &arg : method->results()) {
692 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
693 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
694 out.indent(2, [&] {
695 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800696 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800697 });
698 out << "return;\n";
699 });
700 }
701
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800702 out << "_hidl_cb(";
703 first = true;
704 for (const auto &arg : method->results()) {
705 if (!first) {
706 out << ", ";
707 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800708 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800709 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
710 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800711 }
712 out << ");\n";
713 out.unindent();
714 out << "});\n\n";
715 } else {
716 out << ");\n\n";
717 if (elidedReturn != nullptr) {
718 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800719 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800720 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000721 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800722 }
723 status_t status = generateCppInstrumentationCall(
724 out,
725 InstrumentationEvent::PASSTHROUGH_EXIT,
726 method);
727 if (status != OK) {
728 return status;
729 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700730 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700731
732 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700733 out.unindent();
734 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700735 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700736
737 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700738
739 out.unindent();
740 out << "}\n";
741
742 return OK;
743}
744
Yifan Hong068c5522016-10-31 14:07:25 -0700745status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700746
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700747 const Interface *iface = mRootScope->getInterface();
748
Yifan Hong10fe0b52016-10-19 14:20:17 -0700749 const Interface *prevIterface = nullptr;
750 for (const auto &tuple : iface->allMethodsFromRoot()) {
751 const Method *method = tuple.method();
752 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700753
Yifan Hong10fe0b52016-10-19 14:20:17 -0700754 if(prevIterface != superInterface) {
755 if (prevIterface != nullptr) {
756 out << "\n";
757 }
758 out << "// Methods from "
759 << superInterface->fullName()
760 << " follow.\n";
761 prevIterface = superInterface;
762 }
Yifan Hong068c5522016-10-31 14:07:25 -0700763 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700764
Yifan Hong10fe0b52016-10-19 14:20:17 -0700765 if (err != OK) {
766 return err;
767 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700768 }
769
Yifan Hong10fe0b52016-10-19 14:20:17 -0700770 out << "\n";
771
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700772 return OK;
773}
774
Andreas Huberb82318c2016-08-02 14:45:54 -0700775status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700776 std::string ifaceName;
777 if (!AST::isInterface(&ifaceName)) {
778 // types.hal does not get a stub header.
779 return OK;
780 }
781
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700782 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800783 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700784
Andreas Huberb82318c2016-08-02 14:45:54 -0700785 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700786 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700787 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700788 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700789 path.append(".h");
790
Andreas Huberd2943e12016-08-05 11:59:31 -0700791 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700792 FILE *file = fopen(path.c_str(), "w");
793
794 if (file == NULL) {
795 return -errno;
796 }
797
798 Formatter out(file);
799
Steven Moreland40786312016-08-16 10:29:40 -0700800 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700801
802 out << "#ifndef " << guard << "\n";
803 out << "#define " << guard << "\n\n";
804
Yifan Hongeefe4f22017-01-04 15:32:42 -0800805 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700806 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700807
808 enterLeaveNamespace(out, true /* enter */);
809 out << "\n";
810
811 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800812 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100813 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800814 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000815 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100816 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800817 out << " : public "
818 << gIBaseFqName.getInterfaceStubFqName().cppName()
819 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100820 }
Andreas Huber881227d2016-08-02 14:20:21 -0700821
822 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800823 out << "explicit "
824 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700825 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100826 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800827 out << "explicit "
828 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100829 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800830 << " const std::string& HidlInstrumentor_package,"
831 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700832 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700833 out << "::android::status_t onTransact(\n";
834 out.indent();
835 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700836 out << "uint32_t _hidl_code,\n";
837 out << "const ::android::hardware::Parcel &_hidl_data,\n";
838 out << "::android::hardware::Parcel *_hidl_reply,\n";
839 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700840 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700841 out.unindent();
842 out.unindent();
843
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100844 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
845 out.unindent();
846 out << "private:\n";
847 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800848
849 status_t err = generateMethods(out, [&](const Method *method, const Interface *iface) {
850 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
851 return OK;
852 }
853 const bool returnsValue = !method->results().empty();
854 const TypedVar *elidedReturn = method->canElideCallback();
855
856 if (elidedReturn == nullptr && returnsValue) {
857 out << "using " << method->name() << "_cb = "
858 << iface->fqName().cppName()
859 << "::" << method->name() << "_cb;\n";
860 }
861 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800862 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800863 return OK;
864 });
865 if (err != OK) {
866 return err;
867 }
868
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100869 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700870 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700871 out << "};\n\n";
872
873 enterLeaveNamespace(out, false /* enter */);
874
875 out << "\n#endif // " << guard << "\n";
876
877 return OK;
878}
879
Andreas Huberb82318c2016-08-02 14:45:54 -0700880status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700881 std::string ifaceName;
882 if (!AST::isInterface(&ifaceName)) {
883 // types.hal does not get a proxy header.
884 return OK;
885 }
886
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700887 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800888 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700889
Andreas Huberb82318c2016-08-02 14:45:54 -0700890 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700891 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700892 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800893 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700894 path.append(".h");
895
Andreas Huberd2943e12016-08-05 11:59:31 -0700896 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700897 FILE *file = fopen(path.c_str(), "w");
898
899 if (file == NULL) {
900 return -errno;
901 }
902
903 Formatter out(file);
904
Yifan Hongeefe4f22017-01-04 15:32:42 -0800905 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700906
907 out << "#ifndef " << guard << "\n";
908 out << "#define " << guard << "\n\n";
909
Martijn Coenen115d4282016-12-19 05:14:04 +0100910 out << "#include <hidl/HidlTransportSupport.h>\n\n";
911
Andreas Huber881227d2016-08-02 14:20:21 -0700912 std::vector<std::string> packageComponents;
913 getPackageAndVersionComponents(
914 &packageComponents, false /* cpp_compatible */);
915
Yifan Hongeefe4f22017-01-04 15:32:42 -0800916 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700917 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700918
919 enterLeaveNamespace(out, true /* enter */);
920 out << "\n";
921
922 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800923 << proxyName
924 << " : public ::android::hardware::BpInterface<"
925 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000926 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700927
928 out.indent();
929
Yifan Hongeefe4f22017-01-04 15:32:42 -0800930 out << "explicit "
931 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700932 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700933 << "\n\n";
934
Yifan Hong10fe0b52016-10-19 14:20:17 -0700935 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700936
Yifan Hong068c5522016-10-31 14:07:25 -0700937 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
938 method->generateCppSignature(out);
939 out << " override;\n";
940 return OK;
941 });
Steven Moreland9c387612016-09-07 09:54:26 -0700942
943 if (err != OK) {
944 return err;
945 }
Andreas Huber881227d2016-08-02 14:20:21 -0700946
947 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100948 out << "private:\n";
949 out.indent();
950 out << "std::mutex _hidl_mMutex;\n"
951 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
952 << " _hidl_mDeathRecipients;\n";
953 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::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700964
Andreas Huberb82318c2016-08-02 14:45:54 -0700965 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700966 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700967 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700968
969 std::string ifaceName;
970 std::string baseName;
971
Yifan Hongfe95aa22016-10-19 17:26:45 -0700972 const Interface *iface = nullptr;
973 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700974 if (!AST::isInterface(&ifaceName)) {
975 baseName = "types";
976 isInterface = false;
977 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700978 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700979 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700980 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700981 }
982
983 path.append(baseName);
984
985 if (baseName != "types") {
986 path.append("All");
987 }
988
989 path.append(".cpp");
990
Andreas Huberd2943e12016-08-05 11:59:31 -0700991 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700992 FILE *file = fopen(path.c_str(), "w");
993
994 if (file == NULL) {
995 return -errno;
996 }
997
998 Formatter out(file);
999
Steven Moreland623c0042017-01-13 14:42:29 -08001000 out << "#define LOG_TAG \""
1001 << mPackage.string() << "::" << baseName
1002 << "\"\n\n";
1003
Steven Moreland05cd4232016-11-21 16:01:12 -08001004 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001005 out << "#include <cutils/trace.h>\n";
1006 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001007 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -07001008 // This is a no-op for IServiceManager itself.
1009 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
1010
Steven Morelandbec74ed2017-01-25 17:42:35 -08001011 // TODO(b/34274385) remove this
1012 out << "#include <hidl/LegacySupport.h>\n";
1013
Yifan Hongeefe4f22017-01-04 15:32:42 -08001014 generateCppPackageInclude(out, mPackage, iface->getProxyName());
1015 generateCppPackageInclude(out, mPackage, iface->getStubName());
1016 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001017
1018 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -07001019 generateCppPackageInclude(out,
1020 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -08001021 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -07001022 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -08001023
1024 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001025 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -07001026 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -08001027 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -07001028 }
1029
1030 out << "\n";
1031
1032 enterLeaveNamespace(out, true /* enter */);
1033 out << "\n";
1034
1035 status_t err = generateTypeSource(out, ifaceName);
1036
1037 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001038 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001039
1040 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -08001041 out << "const char* "
1042 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -07001043 << "::descriptor(\""
1044 << iface->fqName().string()
1045 << "\");\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +01001046 out << "__attribute__((constructor))";
1047 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001048 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001049 out << "::android::hardware::details::gBnConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001050 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001051 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001052 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001053 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001054 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001055 out << "return new "
1056 << iface->getStubName()
1057 << "(reinterpret_cast<"
1058 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001059 << " *>(iIntf));\n";
1060 });
Yifan Hongb04de382017-02-06 15:31:52 -08001061 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001062 });
Yifan Honga159f3b2017-03-16 14:53:51 -07001063 out << "::android::hardware::details::gBsConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001064 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001065 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001066 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001067 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -08001068 << gIBaseFqName.cppName()
1069 << "> {\n";
1070 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001071 out << "return new "
1072 << iface->getPassthroughName()
1073 << "(reinterpret_cast<"
1074 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001075 << " *>(iIntf));\n";
1076 });
Yifan Hongb04de382017-02-06 15:31:52 -08001077 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001078 });
Yifan Hong158655a2016-11-08 12:34:07 -08001079 });
Martijn Coenen8adcb652017-02-03 17:37:36 +01001080 out << "};\n\n";
1081 out << "__attribute__((destructor))";
1082 out << "static void static_destructor() {\n";
1083 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001084 out << "::android::hardware::details::gBnConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001085 << iface->localName()
1086 << "::descriptor);\n";
Yifan Honga159f3b2017-03-16 14:53:51 -07001087 out << "::android::hardware::details::gBsConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001088 << iface->localName()
1089 << "::descriptor);\n";
1090 });
1091 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001092
Yifan Hongfe95aa22016-10-19 17:26:45 -07001093 err = generateInterfaceSource(out);
1094 }
1095
1096 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001097 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001098 }
1099
1100 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001101 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001102 }
1103
Steven Moreland40786312016-08-16 10:29:40 -07001104 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001105 err = generatePassthroughSource(out);
1106 }
1107
1108 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001109 const Interface *iface = mRootScope->getInterface();
1110
Yifan Hongc8934042016-11-17 17:10:52 -08001111 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001112 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001113 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001114 std::string package = iface->fqName().package()
1115 + iface->fqName().atVersion();
1116
Yifan Hongeefe4f22017-01-04 15:32:42 -08001117 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001118 }
Steven Moreland40786312016-08-16 10:29:40 -07001119 }
1120
Andreas Huber881227d2016-08-02 14:20:21 -07001121 enterLeaveNamespace(out, false /* enter */);
1122
1123 return err;
1124}
1125
Steven Moreland67f67b42016-09-29 08:59:02 -07001126// static
1127void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001128 out.sIf(nonNull + " == nullptr", [&] {
1129 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1130 out.indent(2, [&] {
1131 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1132 });
1133 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001134}
1135
Andreas Huber881227d2016-08-02 14:20:21 -07001136status_t AST::generateTypeSource(
1137 Formatter &out, const std::string &ifaceName) const {
1138 return mRootScope->emitTypeDefinitions(out, ifaceName);
1139}
1140
Andreas Hubere7ff2282016-08-16 13:50:03 -07001141void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001142 Formatter &out,
1143 const std::vector<TypedVar *> &args,
1144 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001145 if (args.empty()) {
1146 return;
1147 }
1148
1149 for (const auto &arg : args) {
1150 const Type &type = arg->type();
1151
Yifan Hong3b320f82016-11-01 15:15:54 -07001152 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001153 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001154 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001155 << ";\n";
1156 }
1157
1158 out << "\n";
1159}
1160
Andreas Huber881227d2016-08-02 14:20:21 -07001161void AST::emitCppReaderWriter(
1162 Formatter &out,
1163 const std::string &parcelObj,
1164 bool parcelObjIsPointer,
1165 const TypedVar *arg,
1166 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001167 Type::ErrorMode mode,
1168 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001169 const Type &type = arg->type();
1170
Andreas Huber881227d2016-08-02 14:20:21 -07001171 type.emitReaderWriter(
1172 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001173 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001174 parcelObj,
1175 parcelObjIsPointer,
1176 isReader,
1177 mode);
1178}
1179
Yifan Hongbf459bc2016-08-23 16:50:37 -07001180void AST::emitCppResolveReferences(
1181 Formatter &out,
1182 const std::string &parcelObj,
1183 bool parcelObjIsPointer,
1184 const TypedVar *arg,
1185 bool isReader,
1186 Type::ErrorMode mode,
1187 bool addPrefixToName) const {
1188 const Type &type = arg->type();
1189 if(type.needsResolveReferences()) {
1190 type.emitResolveReferences(
1191 out,
1192 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1193 isReader, // nameIsPointer
1194 parcelObj,
1195 parcelObjIsPointer,
1196 isReader,
1197 mode);
1198 }
1199}
1200
Yifan Hong068c5522016-10-31 14:07:25 -07001201status_t AST::generateProxyMethodSource(Formatter &out,
1202 const std::string &klassName,
1203 const Method *method,
1204 const Interface *superInterface) const {
1205
1206 method->generateCppSignature(out,
1207 klassName,
1208 true /* specify namespaces */);
1209
1210 const bool returnsValue = !method->results().empty();
1211 const TypedVar *elidedReturn = method->canElideCallback();
1212
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001213 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001214
1215 out.indent();
1216
Martijn Coenen115d4282016-12-19 05:14:04 +01001217 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1218 method->cppImpl(IMPL_PROXY, out);
1219 out.unindent();
1220 out << "}\n\n";
1221 return OK;
1222 }
1223
Yifan Hong068c5522016-10-31 14:07:25 -07001224 if (returnsValue && elidedReturn == nullptr) {
1225 generateCheckNonNull(out, "_hidl_cb");
1226 }
1227
1228 status_t status = generateCppInstrumentationCall(
1229 out,
1230 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001231 method);
1232 if (status != OK) {
1233 return status;
1234 }
1235
1236 out << "::android::hardware::Parcel _hidl_data;\n";
1237 out << "::android::hardware::Parcel _hidl_reply;\n";
1238 out << "::android::status_t _hidl_err;\n";
1239 out << "::android::hardware::Status _hidl_status;\n\n";
1240
1241 declareCppReaderLocals(
1242 out, method->results(), true /* forResults */);
1243
1244 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001245 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001246 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001247 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1248
Martijn Coenenfff73352017-01-04 16:36:31 +01001249 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001250 // First DFS: write all buffers and resolve pointers for parent
1251 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001252 if (arg->type().isInterface()) {
1253 hasInterfaceArgument = true;
1254 }
Yifan Hong068c5522016-10-31 14:07:25 -07001255 emitCppReaderWriter(
1256 out,
1257 "_hidl_data",
1258 false /* parcelObjIsPointer */,
1259 arg,
1260 false /* reader */,
1261 Type::ErrorMode_Goto,
1262 false /* addPrefixToName */);
1263 }
1264
1265 // Second DFS: resolve references.
1266 for (const auto &arg : method->args()) {
1267 emitCppResolveReferences(
1268 out,
1269 "_hidl_data",
1270 false /* parcelObjIsPointer */,
1271 arg,
1272 false /* reader */,
1273 Type::ErrorMode_Goto,
1274 false /* addPrefixToName */);
1275 }
1276
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001277 if (hasInterfaceArgument) {
1278 // Start binder threadpool to handle incoming transactions
1279 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1280 }
Yifan Hong068c5522016-10-31 14:07:25 -07001281 out << "_hidl_err = remote()->transact("
1282 << method->getSerialId()
1283 << " /* "
1284 << method->name()
1285 << " */, _hidl_data, &_hidl_reply";
1286
1287 if (method->isOneway()) {
1288 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1289 }
1290 out << ");\n";
1291
1292 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1293
1294 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001295 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001296 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1297 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1298
1299
1300 // First DFS: write all buffers and resolve pointers for parent
1301 for (const auto &arg : method->results()) {
1302 emitCppReaderWriter(
1303 out,
1304 "_hidl_reply",
1305 false /* parcelObjIsPointer */,
1306 arg,
1307 true /* reader */,
1308 Type::ErrorMode_Goto,
1309 true /* addPrefixToName */);
1310 }
1311
1312 // Second DFS: resolve references.
1313 for (const auto &arg : method->results()) {
1314 emitCppResolveReferences(
1315 out,
1316 "_hidl_reply",
1317 false /* parcelObjIsPointer */,
1318 arg,
1319 true /* reader */,
1320 Type::ErrorMode_Goto,
1321 true /* addPrefixToName */);
1322 }
1323
1324 if (returnsValue && elidedReturn == nullptr) {
1325 out << "_hidl_cb(";
1326
1327 bool first = true;
1328 for (const auto &arg : method->results()) {
1329 if (!first) {
1330 out << ", ";
1331 }
1332
1333 if (arg->type().resultNeedsDeref()) {
1334 out << "*";
1335 }
1336 out << "_hidl_out_" << arg->name();
1337
1338 first = false;
1339 }
1340
1341 out << ");\n\n";
1342 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001343 }
1344 status = generateCppInstrumentationCall(
1345 out,
1346 InstrumentationEvent::CLIENT_API_EXIT,
1347 method);
1348 if (status != OK) {
1349 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001350 }
1351
1352 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001353 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1354 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001355 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001356 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1357 } else {
1358 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1359 out << "return ::android::hardware::Return<void>();\n\n";
1360 }
1361
1362 out.unindent();
1363 out << "_hidl_error:\n";
1364 out.indent();
1365 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1366 out << "return ::android::hardware::Return<";
1367 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001368 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001369 } else {
1370 out << "void";
1371 }
1372 out << ">(_hidl_status);\n";
1373
1374 out.unindent();
1375 out << "}\n\n";
1376 return OK;
1377}
1378
Andreas Huber881227d2016-08-02 14:20:21 -07001379status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001380 Formatter &out, const FQName &fqName) const {
1381 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001382
1383 out << klassName
1384 << "::"
1385 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001386 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001387
1388 out.indent();
1389 out.indent();
1390
1391 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001392 << "<"
1393 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001394 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001395 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001396 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001397 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001398 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001399 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001400
Andreas Huber881227d2016-08-02 14:20:21 -07001401 out.unindent();
1402 out.unindent();
1403 out << "}\n\n";
1404
Yifan Hong068c5522016-10-31 14:07:25 -07001405 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1406 return generateProxyMethodSource(out, klassName, method, superInterface);
1407 });
Andreas Huber881227d2016-08-02 14:20:21 -07001408
Yifan Hong068c5522016-10-31 14:07:25 -07001409 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001410}
1411
1412status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001413 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001414 const Interface *iface) const {
1415 const std::string interfaceName = iface->localName();
1416 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001417
Steven Moreland40786312016-08-16 10:29:40 -07001418 out << klassName
1419 << "::"
1420 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001421 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001422
1423 out.indent();
1424 out.indent();
1425
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001426 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001427 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001428 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001429 out << ": "
1430 << gIBaseFqName.getInterfaceStubFqName().cppName()
1431 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001432 }
1433
1434 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001435 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001436 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001437 << "\") { \n";
1438 out.indent();
1439 out << "_hidl_mImpl = _hidl_impl;\n";
1440 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001441
1442 out.unindent();
1443 out.unindent();
1444 out << "}\n\n";
1445
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001446 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001447 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001448 // class properly.
1449 out << klassName
1450 << "::"
1451 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001452 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1453 << " const std::string &HidlInstrumentor_package,"
1454 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001455
1456 out.indent();
1457 out.indent();
1458
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001459 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001460 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001461 out.indent();
1462 out << "_hidl_mImpl = _hidl_impl;\n";
1463 out.unindent();
1464
1465 out.unindent();
1466 out.unindent();
1467 out << "}\n\n";
1468 }
1469
Yifan Hongbcffce22017-02-01 15:52:06 -08001470 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1471 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1472 return OK;
1473 }
1474 method->generateCppSignature(out, iface->getStubName());
1475 out << " ";
1476 out.block([&] {
1477 method->cppImpl(IMPL_STUB_IMPL, out);
1478 }).endl();
1479 return OK;
1480 });
Steven Moreland60818632017-02-04 00:33:42 -08001481 if (err != OK) {
1482 return err;
1483 }
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001484
Andreas Huber881227d2016-08-02 14:20:21 -07001485 out << "::android::status_t " << klassName << "::onTransact(\n";
1486
1487 out.indent();
1488 out.indent();
1489
Iliyan Malchev549e2592016-08-10 08:59:12 -07001490 out << "uint32_t _hidl_code,\n"
1491 << "const ::android::hardware::Parcel &_hidl_data,\n"
1492 << "::android::hardware::Parcel *_hidl_reply,\n"
1493 << "uint32_t _hidl_flags,\n"
1494 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001495
1496 out.unindent();
1497
Iliyan Malchev549e2592016-08-10 08:59:12 -07001498 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001499 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001500 out.indent();
1501
Yifan Hong10fe0b52016-10-19 14:20:17 -07001502 for (const auto &tuple : iface->allMethodsFromRoot()) {
1503 const Method *method = tuple.method();
1504 const Interface *superInterface = tuple.interface();
1505 out << "case "
1506 << method->getSerialId()
1507 << " /* "
1508 << method->name()
1509 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001510
Yifan Hong10fe0b52016-10-19 14:20:17 -07001511 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001512
Yifan Hong10fe0b52016-10-19 14:20:17 -07001513 status_t err =
1514 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001515
Yifan Hong10fe0b52016-10-19 14:20:17 -07001516 if (err != OK) {
1517 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001518 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001519
1520 out.unindent();
1521 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001522 }
1523
1524 out << "default:\n{\n";
1525 out.indent();
1526
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001527 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001528
1529 out.indent();
1530 out.indent();
1531
Iliyan Malchev549e2592016-08-10 08:59:12 -07001532 out << "_hidl_code, _hidl_data, _hidl_reply, "
1533 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001534
1535 out.unindent();
1536 out.unindent();
1537
1538 out.unindent();
1539 out << "}\n";
1540
1541 out.unindent();
1542 out << "}\n\n";
1543
Yifan Honga018ed52016-12-13 16:35:08 -08001544 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1545 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1546 out.indent(2, [&] {
1547 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1548 out << "_hidl_reply);\n";
1549 });
1550 });
Andreas Huber881227d2016-08-02 14:20:21 -07001551
Iliyan Malchev549e2592016-08-10 08:59:12 -07001552 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001553
1554 out.unindent();
1555 out << "}\n\n";
1556
1557 return OK;
1558}
1559
1560status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001561 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001562 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1563 method->cppImpl(IMPL_STUB, out);
1564 out << "break;\n";
1565 return OK;
1566 }
1567
Yifan Hongeefe4f22017-01-04 15:32:42 -08001568 out << "if (!_hidl_data.enforceInterface("
1569 << iface->fullName()
1570 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001571
Andreas Huber881227d2016-08-02 14:20:21 -07001572 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001573 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001574 out << "break;\n";
1575 out.unindent();
1576 out << "}\n\n";
1577
Andreas Huber5e44a292016-09-27 14:52:39 -07001578 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001579
Yifan Hongbf459bc2016-08-23 16:50:37 -07001580 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001581 for (const auto &arg : method->args()) {
1582 emitCppReaderWriter(
1583 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001584 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001585 false /* parcelObjIsPointer */,
1586 arg,
1587 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001588 Type::ErrorMode_Break,
1589 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001590 }
1591
Yifan Hongbf459bc2016-08-23 16:50:37 -07001592 // Second DFS: resolve references
1593 for (const auto &arg : method->args()) {
1594 emitCppResolveReferences(
1595 out,
1596 "_hidl_data",
1597 false /* parcelObjIsPointer */,
1598 arg,
1599 true /* reader */,
1600 Type::ErrorMode_Break,
1601 false /* addPrefixToName */);
1602 }
1603
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001604 status_t status = generateCppInstrumentationCall(
1605 out,
1606 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001607 method);
1608 if (status != OK) {
1609 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001610 }
1611
Andreas Huber881227d2016-08-02 14:20:21 -07001612 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001613 const TypedVar *elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -08001614 const std::string callee =
1615 (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL))
1616 ? "this" : "_hidl_mImpl";
Andreas Huber881227d2016-08-02 14:20:21 -07001617
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001618 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001619 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001620 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001621 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001622 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001623 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001624 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001625
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001626 bool first = true;
1627 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001628 if (!first) {
1629 out << ", ";
1630 }
1631
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001632 if (arg->type().resultNeedsDeref()) {
1633 out << "*";
1634 }
1635
1636 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001637
1638 first = false;
1639 }
1640
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001641 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001642 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1643 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001644
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001645 elidedReturn->type().emitReaderWriter(
1646 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001647 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001648 "_hidl_reply",
1649 true, /* parcelObjIsPointer */
1650 false, /* isReader */
1651 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001652
Yifan Hongbf459bc2016-08-23 16:50:37 -07001653 emitCppResolveReferences(
1654 out,
1655 "_hidl_reply",
1656 true /* parcelObjIsPointer */,
1657 elidedReturn,
1658 false /* reader */,
1659 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001660 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001661
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001662 status_t status = generateCppInstrumentationCall(
1663 out,
1664 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001665 method);
1666 if (status != OK) {
1667 return status;
1668 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001669
Iliyan Malchev549e2592016-08-10 08:59:12 -07001670 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001671 } else {
1672 if (returnsValue) {
1673 out << "bool _hidl_callbackCalled = false;\n\n";
1674 }
Andreas Huber881227d2016-08-02 14:20:21 -07001675
Yifan Hongcd2ae452017-01-31 14:33:40 -08001676 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001677
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001678 bool first = true;
1679 for (const auto &arg : method->args()) {
1680 if (!first) {
1681 out << ", ";
1682 }
Andreas Huber881227d2016-08-02 14:20:21 -07001683
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001684 if (arg->type().resultNeedsDeref()) {
1685 out << "*";
1686 }
1687
1688 out << arg->name();
1689
1690 first = false;
1691 }
1692
1693 if (returnsValue) {
1694 if (!first) {
1695 out << ", ";
1696 }
1697
1698 out << "[&](";
1699
1700 first = true;
1701 for (const auto &arg : method->results()) {
1702 if (!first) {
1703 out << ", ";
1704 }
1705
Yifan Honga47eef32016-12-12 10:38:54 -08001706 out << "const auto &_hidl_out_" << arg->name();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001707
1708 first = false;
1709 }
1710
1711 out << ") {\n";
1712 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001713 out << "if (_hidl_callbackCalled) {\n";
1714 out.indent();
1715 out << "LOG_ALWAYS_FATAL(\""
1716 << method->name()
1717 << ": _hidl_cb called a second time, but must be called once.\");\n";
1718 out.unindent();
1719 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001720 out << "_hidl_callbackCalled = true;\n\n";
1721
Yifan Hong859e53f2016-11-14 19:08:24 -08001722 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1723 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001724
Yifan Hongbf459bc2016-08-23 16:50:37 -07001725 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001726 for (const auto &arg : method->results()) {
1727 emitCppReaderWriter(
1728 out,
1729 "_hidl_reply",
1730 true /* parcelObjIsPointer */,
1731 arg,
1732 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001733 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001734 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001735 }
1736
Yifan Hongbf459bc2016-08-23 16:50:37 -07001737 // Second DFS: resolve references
1738 for (const auto &arg : method->results()) {
1739 emitCppResolveReferences(
1740 out,
1741 "_hidl_reply",
1742 true /* parcelObjIsPointer */,
1743 arg,
1744 false /* reader */,
1745 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001746 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001747 }
1748
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001749 status_t status = generateCppInstrumentationCall(
1750 out,
1751 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001752 method);
1753 if (status != OK) {
1754 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001755 }
1756
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001757 out << "_hidl_cb(*_hidl_reply);\n";
1758
1759 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001760 out << "});\n\n";
1761 } else {
1762 out << ");\n\n";
1763 status_t status = generateCppInstrumentationCall(
1764 out,
1765 InstrumentationEvent::SERVER_API_EXIT,
1766 method);
1767 if (status != OK) {
1768 return status;
1769 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001770 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001771
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001772 if (returnsValue) {
1773 out << "if (!_hidl_callbackCalled) {\n";
1774 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001775 out << "LOG_ALWAYS_FATAL(\""
1776 << method->name()
1777 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001778 out.unindent();
1779 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001780 } else {
1781 out << "::android::hardware::writeToParcel("
1782 << "::android::hardware::Status::ok(), "
1783 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001784 }
Andreas Huber881227d2016-08-02 14:20:21 -07001785 }
1786
1787 out << "break;\n";
1788
1789 return OK;
1790}
1791
Steven Moreland69e7c702016-09-09 11:16:32 -07001792status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1793 std::string ifaceName;
1794 if (!AST::isInterface(&ifaceName)) {
1795 // types.hal does not get a stub header.
1796 return OK;
1797 }
1798
1799 const Interface *iface = mRootScope->getInterface();
1800
Yifan Hongeefe4f22017-01-04 15:32:42 -08001801 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001802
1803 bool supportOneway = iface->hasOnewayMethods();
1804
1805 std::string path = outputPath;
1806 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1807 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1808 path.append(klassName);
1809 path.append(".h");
1810
1811 CHECK(Coordinator::MakeParentHierarchy(path));
1812 FILE *file = fopen(path.c_str(), "w");
1813
1814 if (file == NULL) {
1815 return -errno;
1816 }
1817
1818 Formatter out(file);
1819
1820 const std::string guard = makeHeaderGuard(klassName);
1821
1822 out << "#ifndef " << guard << "\n";
1823 out << "#define " << guard << "\n\n";
1824
1825 std::vector<std::string> packageComponents;
1826 getPackageAndVersionComponents(
1827 &packageComponents, false /* cpp_compatible */);
1828
Yifan Hongb0949432016-12-15 15:32:24 -08001829 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001830 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001831
1832 generateCppPackageInclude(out, mPackage, ifaceName);
1833 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001834
Yifan Hong7a118f52016-12-07 11:21:15 -08001835 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001836 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001837 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001838 }
1839
1840 enterLeaveNamespace(out, true /* enter */);
1841 out << "\n";
1842
1843 out << "struct "
1844 << klassName
1845 << " : " << ifaceName
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001846 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001847
1848 out.indent();
1849 out << "explicit "
1850 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001851 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001852 << ifaceName
1853 << "> impl);\n";
1854
Yifan Hong068c5522016-10-31 14:07:25 -07001855 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1856 return generatePassthroughMethod(out, method);
1857 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001858
1859 if (err != OK) {
1860 return err;
1861 }
1862
1863 out.unindent();
1864 out << "private:\n";
1865 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001866 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001867
1868 if (supportOneway) {
Yifan Hongef91d362017-03-20 17:18:13 -07001869 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001870
1871 out << "\n";
1872
1873 out << "::android::hardware::Return<void> addOnewayTask("
1874 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001875 }
1876
1877 out.unindent();
1878
1879 out << "};\n\n";
1880
1881 enterLeaveNamespace(out, false /* enter */);
1882
1883 out << "\n#endif // " << guard << "\n";
1884
1885 return OK;
1886}
1887
Yifan Hongfe95aa22016-10-19 17:26:45 -07001888status_t AST::generateInterfaceSource(Formatter &out) const {
1889 const Interface *iface = mRootScope->getInterface();
1890
Yifan Hong2d7126b2016-10-20 15:12:57 -07001891 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001892 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001893
Steven Morelandd4b068a2017-03-20 06:30:51 -07001894 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1895 bool reserved = method->isHidlReserved();
1896
1897 if (!reserved) {
1898 out << "// no default implementation for: ";
1899 }
1900 method->generateCppSignature(out, iface->localName());
1901 if (reserved) {
1902 out.block([&]() {
1903 method->cppImpl(IMPL_HEADER, out);
1904 }).endl();
1905 }
1906
1907 out << "\n";
1908
1909 return OK;
1910 });
1911 if (err != OK) {
1912 return err;
1913 }
1914
Yifan Hong3d746092016-12-07 14:26:33 -08001915 for (const Interface *superType : iface->typeChain()) {
1916 out << "// static \n"
1917 << childTypeResult
Yifan Hongeefe4f22017-01-04 15:32:42 -08001918 << " "
1919 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001920 << "::castFrom("
1921 << superType->getCppArgumentType()
1922 << " parent) {\n";
1923 out.indent();
1924 if (iface == superType) {
1925 out << "return parent;\n";
1926 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001927 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001928 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001929 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001930 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001931 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001932 << ">(\n";
1933 out.indent();
1934 out.indent();
1935 out << "parent, \""
1936 << iface->fqName().string()
1937 << "\");\n";
1938 out.unindent();
1939 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001940 }
Yifan Hong3d746092016-12-07 14:26:33 -08001941 out.unindent();
1942 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001943 }
1944
1945 return OK;
1946}
1947
Steven Moreland69e7c702016-09-09 11:16:32 -07001948status_t AST::generatePassthroughSource(Formatter &out) const {
1949 const Interface *iface = mRootScope->getInterface();
1950
Yifan Hongeefe4f22017-01-04 15:32:42 -08001951 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001952
1953 out << klassName
1954 << "::"
1955 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001956 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001957 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001958 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001959 << mPackage.string()
1960 << "\", \""
1961 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001962 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001963 if (iface->hasOnewayMethods()) {
1964 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001965 out.indent([&] {
Yifan Hongf01dad42017-03-20 19:03:11 -07001966 out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001967 });
1968 }
1969 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001970
1971 if (iface->hasOnewayMethods()) {
1972 out << "::android::hardware::Return<void> "
1973 << klassName
1974 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1975 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001976 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001977 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001978 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1979 out.indent();
1980 out.indent();
1981 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1982 out.unindent();
1983 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001984 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001985 out << "}\n";
1986
Steven Morelandd366c262016-10-11 15:29:10 -07001987 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001988
1989 out.unindent();
1990 out << "}\n\n";
1991
1992
1993 }
1994
1995 return OK;
1996}
1997
Martijn Coenen7b295242016-11-04 16:52:56 +01001998status_t AST::generateCppAtraceCall(Formatter &out,
1999 InstrumentationEvent event,
2000 const Method *method) const {
2001 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08002002 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01002003 switch (event) {
2004 case SERVER_API_ENTRY:
2005 {
2006 out << "atrace_begin(ATRACE_TAG_HAL, \""
2007 << baseString + "::server\");\n";
2008 break;
2009 }
2010 case CLIENT_API_ENTRY:
2011 {
2012 out << "atrace_begin(ATRACE_TAG_HAL, \""
2013 << baseString + "::client\");\n";
2014 break;
2015 }
2016 case PASSTHROUGH_ENTRY:
2017 {
2018 out << "atrace_begin(ATRACE_TAG_HAL, \""
2019 << baseString + "::passthrough\");\n";
2020 break;
2021 }
2022 case SERVER_API_EXIT:
2023 case CLIENT_API_EXIT:
2024 case PASSTHROUGH_EXIT:
2025 {
2026 out << "atrace_end(ATRACE_TAG_HAL);\n";
2027 break;
2028 }
2029 default:
2030 {
2031 LOG(ERROR) << "Unsupported instrumentation event: " << event;
2032 return UNKNOWN_ERROR;
2033 }
2034 }
2035
2036 return OK;
2037}
2038
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002039status_t AST::generateCppInstrumentationCall(
2040 Formatter &out,
2041 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07002042 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01002043 status_t err = generateCppAtraceCall(out, event, method);
2044 if (err != OK) {
2045 return err;
2046 }
2047
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002048 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
2049 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002050 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002051 std::string event_str = "";
2052 switch (event) {
2053 case SERVER_API_ENTRY:
2054 {
2055 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
2056 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002057 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002058 << (arg->type().resultNeedsDeref() ? "" : "&")
2059 << arg->name()
2060 << ");\n";
2061 }
2062 break;
2063 }
2064 case SERVER_API_EXIT:
2065 {
2066 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07002067 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002068 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07002069 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002070 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002071 }
2072 break;
2073 }
2074 case CLIENT_API_ENTRY:
2075 {
2076 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2077 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002078 out << "_hidl_args.push_back((void *)&"
2079 << arg->name()
2080 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002081 }
2082 break;
2083 }
2084 case CLIENT_API_EXIT:
2085 {
2086 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2087 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002088 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002089 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002090 << "_hidl_out_"
2091 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002092 << ");\n";
2093 }
2094 break;
2095 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002096 case PASSTHROUGH_ENTRY:
2097 {
2098 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2099 for (const auto &arg : method->args()) {
2100 out << "_hidl_args.push_back((void *)&"
2101 << arg->name()
2102 << ");\n";
2103 }
2104 break;
2105 }
2106 case PASSTHROUGH_EXIT:
2107 {
2108 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002109 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002110 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002111 << arg->name()
2112 << ");\n";
2113 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002114 break;
2115 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002116 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002117 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002118 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002119 return UNKNOWN_ERROR;
2120 }
2121 }
2122
Steven Moreland031ccf12016-10-31 15:54:38 -07002123 const Interface *iface = mRootScope->getInterface();
2124
Steven Moreland1ab31442016-11-03 18:37:51 -07002125 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002126 out.indent();
2127 out << "callback("
2128 << event_str
2129 << ", \""
2130 << mPackage.package()
2131 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002132 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002133 << "\", \""
2134 << iface->localName()
2135 << "\", \""
2136 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002137 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002138 out.unindent();
2139 out << "}\n";
2140 out.unindent();
2141 out << "}\n\n";
2142
2143 return OK;
2144}
2145
Andreas Huber881227d2016-08-02 14:20:21 -07002146} // namespace android