blob: b1661c7343a5a67be6a3b083996848f416b43def [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 Hong83c8e5f2016-12-13 14:33:53 -0800128static void declareServiceManagerInteractions(Formatter &out, const std::string &baseName) {
129 out << "static ::android::sp<I" << baseName << "> getService("
130 << "const std::string &serviceName, bool getStub=false);\n";
131 out << "::android::status_t registerAsService(const std::string &serviceName);\n";
132 out << "static bool registerForNotifications(\n";
133 out.indent(2, [&] {
134 out << "const std::string &serviceName,\n"
135 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
136 << "&notification);\n";
137 });
138
139}
140
141static void implementServiceManagerInteractions(Formatter &out,
142 const std::string &baseName, const std::string &package) {
143
144 out << "// static\n"
145 << "::android::sp<I" << baseName << "> I" << baseName << "::getService("
146 << "const std::string &serviceName, bool getStub) ";
147 out.block([&] {
148 out << "::android::sp<I" << baseName << "> iface;\n"
149 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
150 out.indent(2, [&] {
151 out << "= ::android::hardware::defaultServiceManager();\n";
152 });
153 out.sIf("sm != nullptr && !getStub", [&] {
Martijn Coenenb40ef022017-01-02 15:21:46 +0100154 out << "::android::hardware::Return<::android::sp<::android::hidl::base::V1_0::IBase>> ret = \n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800155 out.indent(2, [&] {
Martijn Coenenb40ef022017-01-02 15:21:46 +0100156 out << "sm->get(\"" << package << "::I" << baseName << "\", serviceName.c_str());\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800157 });
Steven Morelandcd00b9b2016-12-29 10:34:03 -0800158 out.sIf("ret.isOk()", [&] {
Martijn Coenenb40ef022017-01-02 15:21:46 +0100159 out << "iface = I" << baseName << "::castFrom(ret);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800160 out.sIf("iface != nullptr", [&] {
161 out << "return iface;\n";
162 }).endl();
163 }).endl();
164 }).endl();
165 out << "const int dlMode = RTLD_LAZY;\n";
166 out << "void *handle = nullptr;\n";
167 for (const auto &path : std::vector<std::string>({
168 "HAL_LIBRARY_PATH_ODM", "HAL_LIBRARY_PATH_VENDOR", "HAL_LIBRARY_PATH_SYSTEM"
169 })) {
170 out.sIf("handle == nullptr", [&] {
171 out << "handle = dlopen("
172 << path << " \"" << package << "-impl.so\", dlMode);\n";
173 }).endl();
174 }
175 out.sIf("handle == nullptr", [&] {
176 out << "return iface;\n";
177 }).endl();
178 out << "I" << baseName << "* (*generator)(const char* name);\n"
179 << "*(void **)(&generator) = dlsym(handle, \"HIDL_FETCH_I" << baseName << "\");\n";
180 out.sIf("generator", [&] {
181 out << "iface = (*generator)(serviceName.c_str());\n";
182 out.sIf("iface != nullptr", [&] {
183 out << "iface = new Bs" << baseName << "(iface);\n";
184 }).endl();
185 }).endl();
186 out << "return iface;\n";
187 }).endl().endl();
188
189 out << "::android::status_t I" << baseName << "::registerAsService("
190 << "const std::string &serviceName) ";
191 out.block([&] {
192 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
193 out.indent(2, [&] {
194 out << "= ::android::hardware::defaultServiceManager();\n";
195 });
196 out.sIf("sm == nullptr", [&] {
197 out << "return ::android::INVALID_OPERATION;\n";
198 }).endl();
199 out << "bool success = false;\n"
200 << "::android::hardware::Return<void> ret =\n";
201 out.indent(2, [&] {
202 out << "this->interfaceChain("
203 << "[&success, &sm, &serviceName, this](const auto &chain) ";
204 out.block([&] {
205 out << "::android::hardware::Return<bool> addRet = "
206 << "sm->add(chain, serviceName.c_str(), this);\n";
207 out << "success = addRet.isOk() && addRet;\n";
208 });
209 out << ");\n";
Steven Morelandcd00b9b2016-12-29 10:34:03 -0800210 out << "success = success && ret.isOk();\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800211 });
212 out << "return success ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
213 }).endl().endl();
214
215 out << "bool I" << baseName << "::registerForNotifications(\n";
216 out.indent(2, [&] {
217 out << "const std::string &serviceName,\n"
218 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
219 << "&notification) ";
220 });
221 out.block([&] {
222 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
223 out.indent(2, [&] {
224 out << "= ::android::hardware::defaultServiceManager();\n";
225 });
226 out.sIf("sm == nullptr", [&] {
227 out << "return false;\n";
228 }).endl();
229 out << "::android::hardware::Return<bool> success =\n";
230 out.indent(2, [&] {
231 out << "sm->registerForNotifications(\"" << package << "::I" << baseName << "\",\n";
232 out.indent(2, [&] {
233 out << "serviceName, notification);\n";
234 });
235 });
236 out << "return success.isOk() && success;\n";
237 }).endl().endl();
238}
239
Andreas Huberb82318c2016-08-02 14:45:54 -0700240status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700241
Andreas Huberb82318c2016-08-02 14:45:54 -0700242 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700243 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700244 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700245
246 std::string ifaceName;
247 bool isInterface = true;
248 if (!AST::isInterface(&ifaceName)) {
249 ifaceName = "types";
250 isInterface = false;
251 }
252 path.append(ifaceName);
253 path.append(".h");
254
Andreas Huberd2943e12016-08-05 11:59:31 -0700255 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700256 FILE *file = fopen(path.c_str(), "w");
257
258 if (file == NULL) {
259 return -errno;
260 }
261
262 Formatter out(file);
263
264 const std::string guard = makeHeaderGuard(ifaceName);
265
266 out << "#ifndef " << guard << "\n";
267 out << "#define " << guard << "\n\n";
268
Andreas Huber737080b2016-08-02 15:38:04 -0700269 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700270 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700271 }
272
273 if (!mImportedNames.empty()) {
274 out << "\n";
275 }
276
Steven Moreland0693f312016-11-09 15:06:14 -0800277 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800278 if (isIBase()) {
279 out << "// skipped #include IServiceNotification.h\n\n";
280 } else {
281 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
282 }
Steven Moreland0693f312016-11-09 15:06:14 -0800283 }
284
Yifan Hongc8934042016-11-17 17:10:52 -0800285 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700286 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700287
288 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200289 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700290 }
291
Martijn Coenenaf712c02016-11-16 15:26:27 +0100292 out << "#include <utils/NativeHandle.h>\n";
293 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700294
295 enterLeaveNamespace(out, true /* enter */);
296 out << "\n";
297
298 if (isInterface) {
299 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700300 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700301
302 const Interface *iface = mRootScope->getInterface();
303 const Interface *superType = iface->superType();
304
Steven Moreland40786312016-08-16 10:29:40 -0700305 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800306 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700307 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000308 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700309 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700310 }
311
312 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700313
314 out.indent();
315
Andreas Huber881227d2016-08-02 14:20:21 -0700316 }
317
318 status_t err = emitTypeDeclarations(out);
319
320 if (err != OK) {
321 return err;
322 }
323
324 if (isInterface) {
325 const Interface *iface = mRootScope->getInterface();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700326 const Interface *superType = iface->superType();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700327 const std::string baseName = iface->getBaseName();
Yifan Hongc8934042016-11-17 17:10:52 -0800328 out << "virtual bool isRemote() const ";
329 if (!isIBase()) {
330 out << "override ";
331 }
332 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800333
Andreas Huber881227d2016-08-02 14:20:21 -0700334 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700335 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700336
Andreas Huber881227d2016-08-02 14:20:21 -0700337 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800338 const TypedVar *elidedReturn = method->canElideCallback();
339
340 if (elidedReturn == nullptr && returnsValue) {
341 out << "using "
342 << method->name()
343 << "_cb = std::function<void("
344 << Method::GetArgSignature(method->results(),
345 true /* specify namespaces */)
346 << ")>;\n";
347 }
Andreas Huber881227d2016-08-02 14:20:21 -0700348
Andreas Huber3599d922016-08-09 10:42:57 -0700349 method->dumpAnnotations(out);
350
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700351 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700352 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700353 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700354 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700355 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700356 }
357
358 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700359 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700360 << Method::GetArgSignature(method->args(),
361 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700362
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700363 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700364 if (!method->args().empty()) {
365 out << ", ";
366 }
367
Steven Moreland67f67b42016-09-29 08:59:02 -0700368 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700369 }
370
Yifan Hong10fe0b52016-10-19 14:20:17 -0700371 out << ")";
372 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800373 if (!isIBase()) {
374 out << " override";
375 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700376 out << " {\n";
377 out.indent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100378 method->cppImpl(IMPL_HEADER, out);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700379 out.unindent();
380 out << "\n}\n";
381 } else {
382 out << " = 0;\n";
383 }
Andreas Huber881227d2016-08-02 14:20:21 -0700384 }
Steven Moreland40786312016-08-16 10:29:40 -0700385
Yifan Hong3d746092016-12-07 14:26:33 -0800386 out << "// cast static functions\n";
387 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700388
Yifan Hong3d746092016-12-07 14:26:33 -0800389 for (const Interface *superType : iface->typeChain()) {
390 out << "static "
391 << childTypeResult
392 << " castFrom("
393 << superType->getCppArgumentType()
394 << " parent"
395 << ");\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700396 }
397
Steven Morelandd39133b2016-11-11 12:30:08 -0800398 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700399
Yifan Hongc8934042016-11-17 17:10:52 -0800400 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800401 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800402 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800403 declareServiceManagerInteractions(out, baseName);
Yifan Hongc8934042016-11-17 17:10:52 -0800404 }
Yifan Hong158655a2016-11-08 12:34:07 -0800405
406 out << "private: static int hidlStaticBlock;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700407 }
408
409 if (isInterface) {
410 out.unindent();
411
Andreas Hubere3f769a2016-10-10 10:54:44 -0700412 out << "};\n\n";
413 }
414
415 err = mRootScope->emitGlobalTypeDeclarations(out);
416
417 if (err != OK) {
418 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700419 }
420
421 out << "\n";
422 enterLeaveNamespace(out, false /* enter */);
423
424 out << "\n#endif // " << guard << "\n";
425
426 return OK;
427}
428
Steven Moreland40786312016-08-16 10:29:40 -0700429status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
430 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800431 bool isInterface = AST::isInterface(&ifaceName);
432 const Interface *iface = nullptr;
433 std::string baseName{};
434 std::string klassName{};
435
436 if(isInterface) {
437 iface = mRootScope->getInterface();
438 baseName = iface->getBaseName();
439 klassName = "IHw" + baseName;
440 } else {
441 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700442 }
443
Steven Moreland40786312016-08-16 10:29:40 -0700444 std::string path = outputPath;
445 path.append(mCoordinator->convertPackageRootToPath(mPackage));
446 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
447 path.append(klassName + ".h");
448
Yifan Hong244e82d2016-11-11 11:13:57 -0800449 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700450
451 if (file == NULL) {
452 return -errno;
453 }
454
455 Formatter out(file);
456
457 const std::string guard = makeHeaderGuard(klassName);
458
459 out << "#ifndef " << guard << "\n";
460 out << "#define " << guard << "\n\n";
461
Yifan Hong244e82d2016-11-11 11:13:57 -0800462 if (isInterface) {
463 generateCppPackageInclude(out, mPackage, ifaceName);
464 } else {
465 generateCppPackageInclude(out, mPackage, "types");
466 }
Steven Moreland40786312016-08-16 10:29:40 -0700467
Steven Morelandee88eed2016-10-31 17:49:00 -0700468 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700469
470 for (const auto &item : mImportedNames) {
471 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800472 generateCppPackageInclude(out, item, "hwtypes");
473 } else {
474 generateCppPackageInclude(out, item, "Bn" + item.getInterfaceBaseName());
Martijn Coenena63e0ad2016-12-07 17:29:00 +0100475 generateCppPackageInclude(out, item, "Bp" + item.getInterfaceBaseName());
Steven Moreland40786312016-08-16 10:29:40 -0700476 }
Steven Moreland40786312016-08-16 10:29:40 -0700477 }
478
479 out << "\n";
480
Martijn Coenen93915102016-09-01 01:35:52 +0200481 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700482 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100483 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700484
485 out << "\n";
486
487 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700488
Yifan Hong244e82d2016-11-11 11:13:57 -0800489 status_t err = mRootScope->emitGlobalHwDeclarations(out);
490 if (err != OK) {
491 return err;
492 }
Steven Moreland40786312016-08-16 10:29:40 -0700493
494 enterLeaveNamespace(out, false /* enter */);
495
496 out << "\n#endif // " << guard << "\n";
497
498 return OK;
499}
500
Andreas Huber881227d2016-08-02 14:20:21 -0700501status_t AST::emitTypeDeclarations(Formatter &out) const {
502 return mRootScope->emitTypeDeclarations(out);
503}
504
Yifan Hong7a118f52016-12-07 11:21:15 -0800505static void wrapPassthroughArg(Formatter &out,
506 const TypedVar *arg, bool addPrefixToName,
507 std::function<void(void)> handleError) {
508 if (!arg->type().isInterface()) {
509 return;
510 }
511 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
512 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
513 + arg->name();
514 const Interface &iface = static_cast<const Interface &>(arg->type());
515 out << iface.getCppStackType() << " " << wrappedName << ";\n";
516 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
517 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
518 out << wrappedName
519 << " = "
520 << iface.fqName().cppName()
521 << "::castFrom(::android::hardware::wrapPassthrough("
522 << name << "));\n";
523 out.sIf(wrappedName + " == nullptr", [&] {
524 // Fatal error. Happens when the BsFoo class is not found in the binary
525 // or any dynamic libraries.
526 handleError();
527 }).endl();
528 }).sElse([&] {
529 out << wrappedName << " = " << name << ";\n";
530 }).endl().endl();
531}
532
Steven Moreland69e7c702016-09-09 11:16:32 -0700533status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700534 const Method *method) const {
535 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700536
537 out << " {\n";
538 out.indent();
539
540 const bool returnsValue = !method->results().empty();
541 const TypedVar *elidedReturn = method->canElideCallback();
542
Steven Moreland67f67b42016-09-29 08:59:02 -0700543 if (returnsValue && elidedReturn == nullptr) {
544 generateCheckNonNull(out, "_hidl_cb");
545 }
546
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700547 generateCppInstrumentationCall(
548 out,
549 InstrumentationEvent::PASSTHROUGH_ENTRY,
550 method);
551
Yifan Hong7a118f52016-12-07 11:21:15 -0800552
553 for (const auto &arg : method->args()) {
554 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
555 out << "return ::android::hardware::Status::fromExceptionCode(\n";
556 out.indent(2, [&] {
557 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800558 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800559 });
560 });
561 }
562
563 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700564 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700565
566 if (method->isOneway()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800567 out << "addOnewayTask([this, &_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700568 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800569 out << ", "
570 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
571 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700572 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700573 out << "] {\n";
574 out.indent();
575 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700576 }
577
578 out << "mImpl->"
579 << method->name()
580 << "(";
581
582 bool first = true;
583 for (const auto &arg : method->args()) {
584 if (!first) {
585 out << ", ";
586 }
587 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800588 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700589 }
590 if (returnsValue && elidedReturn == nullptr) {
591 if (!method->args().empty()) {
592 out << ", ";
593 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800594 out << "[&](";
595 first = true;
596 for (const auto &arg : method->results()) {
597 if (!first) {
598 out << ", ";
599 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700600
Yifan Hong7a118f52016-12-07 11:21:15 -0800601 out << "const auto &_hidl_out_"
602 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800603
604 first = false;
605 }
606
607 out << ") {\n";
608 out.indent();
609 status_t status = generateCppInstrumentationCall(
610 out,
611 InstrumentationEvent::PASSTHROUGH_EXIT,
612 method);
613 if (status != OK) {
614 return status;
615 }
616
Yifan Hong7a118f52016-12-07 11:21:15 -0800617 for (const auto &arg : method->results()) {
618 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
619 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
620 out.indent(2, [&] {
621 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800622 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800623 });
624 out << "return;\n";
625 });
626 }
627
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800628 out << "_hidl_cb(";
629 first = true;
630 for (const auto &arg : method->results()) {
631 if (!first) {
632 out << ", ";
633 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800634 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800635 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
636 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800637 }
638 out << ");\n";
639 out.unindent();
640 out << "});\n\n";
641 } else {
642 out << ");\n\n";
643 if (elidedReturn != nullptr) {
644 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800645 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800646 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000647 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800648 }
649 status_t status = generateCppInstrumentationCall(
650 out,
651 InstrumentationEvent::PASSTHROUGH_EXIT,
652 method);
653 if (status != OK) {
654 return status;
655 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700656 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700657
658 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700659 out.unindent();
660 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700661 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700662
663 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700664
665 out.unindent();
666 out << "}\n";
667
668 return OK;
669}
670
Yifan Hong068c5522016-10-31 14:07:25 -0700671status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700672
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700673 const Interface *iface = mRootScope->getInterface();
674
Yifan Hong10fe0b52016-10-19 14:20:17 -0700675 const Interface *prevIterface = nullptr;
676 for (const auto &tuple : iface->allMethodsFromRoot()) {
677 const Method *method = tuple.method();
678 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700679
Yifan Hong10fe0b52016-10-19 14:20:17 -0700680 if(prevIterface != superInterface) {
681 if (prevIterface != nullptr) {
682 out << "\n";
683 }
684 out << "// Methods from "
685 << superInterface->fullName()
686 << " follow.\n";
687 prevIterface = superInterface;
688 }
Yifan Hong068c5522016-10-31 14:07:25 -0700689 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700690
Yifan Hong10fe0b52016-10-19 14:20:17 -0700691 if (err != OK) {
692 return err;
693 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700694 }
695
Yifan Hong10fe0b52016-10-19 14:20:17 -0700696 out << "\n";
697
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700698 return OK;
699}
700
Andreas Huberb82318c2016-08-02 14:45:54 -0700701status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700702 std::string ifaceName;
703 if (!AST::isInterface(&ifaceName)) {
704 // types.hal does not get a stub header.
705 return OK;
706 }
707
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700708 const Interface *iface = mRootScope->getInterface();
709 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700710 const std::string klassName = "Bn" + baseName;
Andreas Huber881227d2016-08-02 14:20:21 -0700711
Andreas Huberb82318c2016-08-02 14:45:54 -0700712 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700713 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700714 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700715 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700716 path.append(".h");
717
Andreas Huberd2943e12016-08-05 11:59:31 -0700718 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700719 FILE *file = fopen(path.c_str(), "w");
720
721 if (file == NULL) {
722 return -errno;
723 }
724
725 Formatter out(file);
726
Steven Moreland40786312016-08-16 10:29:40 -0700727 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700728
729 out << "#ifndef " << guard << "\n";
730 out << "#define " << guard << "\n\n";
731
Steven Morelandee88eed2016-10-31 17:49:00 -0700732 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
733 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700734
735 enterLeaveNamespace(out, true /* enter */);
736 out << "\n";
737
738 out << "struct "
739 << "Bn"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100740 << baseName;
741 if (iface->isIBase()) {
742 out << " : public ::android::hardware::BBinder";
743 out << ", public ::android::hardware::HidlInstrumentor {\n";
744 } else {
745 out << " : public ::android::hidl::base::V1_0::BnBase {\n";
746 }
Andreas Huber881227d2016-08-02 14:20:21 -0700747
748 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700749 out << "explicit Bn"
750 << baseName
751 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100752 << "\n";
753 out << "explicit Bn"
754 << baseName
755 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
756 << " const std::string& prefix);"
Steven Moreland40786312016-08-16 10:29:40 -0700757 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700758 out << "::android::status_t onTransact(\n";
759 out.indent();
760 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700761 out << "uint32_t _hidl_code,\n";
762 out << "const ::android::hardware::Parcel &_hidl_data,\n";
763 out << "::android::hardware::Parcel *_hidl_reply,\n";
764 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700765 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700766 out.unindent();
767 out.unindent();
768
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100769 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
770 out.unindent();
771 out << "private:\n";
772 out.indent();
773 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700774 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700775 out << "};\n\n";
776
777 enterLeaveNamespace(out, false /* enter */);
778
779 out << "\n#endif // " << guard << "\n";
780
781 return OK;
782}
783
Andreas Huberb82318c2016-08-02 14:45:54 -0700784status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700785 std::string ifaceName;
786 if (!AST::isInterface(&ifaceName)) {
787 // types.hal does not get a proxy header.
788 return OK;
789 }
790
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700791 const Interface *iface = mRootScope->getInterface();
792 const std::string baseName = iface->getBaseName();
Andreas Huber881227d2016-08-02 14:20:21 -0700793
Andreas Huberb82318c2016-08-02 14:45:54 -0700794 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700795 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700796 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700797 path.append("Bp");
798 path.append(baseName);
799 path.append(".h");
800
Andreas Huberd2943e12016-08-05 11:59:31 -0700801 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700802 FILE *file = fopen(path.c_str(), "w");
803
804 if (file == NULL) {
805 return -errno;
806 }
807
808 Formatter out(file);
809
810 const std::string guard = makeHeaderGuard("Bp" + baseName);
811
812 out << "#ifndef " << guard << "\n";
813 out << "#define " << guard << "\n\n";
814
Martijn Coenen115d4282016-12-19 05:14:04 +0100815 out << "#include <hidl/HidlTransportSupport.h>\n\n";
816
Andreas Huber881227d2016-08-02 14:20:21 -0700817 std::vector<std::string> packageComponents;
818 getPackageAndVersionComponents(
819 &packageComponents, false /* cpp_compatible */);
820
Steven Morelandee88eed2016-10-31 17:49:00 -0700821 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
822 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700823
824 enterLeaveNamespace(out, true /* enter */);
825 out << "\n";
826
827 out << "struct "
828 << "Bp"
829 << baseName
Martijn Coenena63e0ad2016-12-07 17:29:00 +0100830 << " : public ::android::hardware::BpInterface<I"
Steven Moreland40786312016-08-16 10:29:40 -0700831 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700832 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700833
834 out.indent();
835
836 out << "explicit Bp"
837 << baseName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700838 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700839 << "\n\n";
840
Yifan Hong10fe0b52016-10-19 14:20:17 -0700841 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700842
Yifan Hong068c5522016-10-31 14:07:25 -0700843 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
844 method->generateCppSignature(out);
845 out << " override;\n";
846 return OK;
847 });
Steven Moreland9c387612016-09-07 09:54:26 -0700848
849 if (err != OK) {
850 return err;
851 }
Andreas Huber881227d2016-08-02 14:20:21 -0700852
853 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100854 out << "private:\n";
855 out.indent();
856 out << "std::mutex _hidl_mMutex;\n"
857 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
858 << " _hidl_mDeathRecipients;\n";
859 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700860 out << "};\n\n";
861
862 enterLeaveNamespace(out, false /* enter */);
863
864 out << "\n#endif // " << guard << "\n";
865
866 return OK;
867}
868
Andreas Huberb82318c2016-08-02 14:45:54 -0700869status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700870
Andreas Huberb82318c2016-08-02 14:45:54 -0700871 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700872 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700873 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700874
875 std::string ifaceName;
876 std::string baseName;
877
Yifan Hongfe95aa22016-10-19 17:26:45 -0700878 const Interface *iface = nullptr;
879 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700880 if (!AST::isInterface(&ifaceName)) {
881 baseName = "types";
882 isInterface = false;
883 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700884 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700885 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700886 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700887 }
888
889 path.append(baseName);
890
891 if (baseName != "types") {
892 path.append("All");
893 }
894
895 path.append(".cpp");
896
Andreas Huberd2943e12016-08-05 11:59:31 -0700897 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700898 FILE *file = fopen(path.c_str(), "w");
899
900 if (file == NULL) {
901 return -errno;
902 }
903
904 Formatter out(file);
905
Steven Moreland05cd4232016-11-21 16:01:12 -0800906 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100907 out << "#include <cutils/trace.h>\n";
908 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700909 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700910 // This is a no-op for IServiceManager itself.
911 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
912
Steven Morelandee88eed2016-10-31 17:49:00 -0700913 generateCppPackageInclude(out, mPackage, "Bp" + baseName);
914 generateCppPackageInclude(out, mPackage, "Bn" + baseName);
915 generateCppPackageInclude(out, mPackage, "Bs" + baseName);
Yifan Hongfe95aa22016-10-19 17:26:45 -0700916
917 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700918 generateCppPackageInclude(out,
919 superType->fqName(),
920 "Bp" + superType->getBaseName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700921 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800922
923 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700924 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700925 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800926 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700927 }
928
929 out << "\n";
930
931 enterLeaveNamespace(out, true /* enter */);
932 out << "\n";
933
934 status_t err = generateTypeSource(out, ifaceName);
935
936 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700937 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700938
939 // need to be put here, generateStubSource is using this.
Steven Morelandd39133b2016-11-11 12:30:08 -0800940 out << "const char* I"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700941 << iface->getBaseName()
942 << "::descriptor(\""
943 << iface->fqName().string()
944 << "\");\n\n";
945
Yifan Hong158655a2016-11-08 12:34:07 -0800946 out << "int I"
947 << iface->getBaseName()
948 << "::hidlStaticBlock = []() -> int {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800949 out.indent([&] {
Steven Morelandd39133b2016-11-11 12:30:08 -0800950 out << "::android::hardware::gBnConstructorMap[I"
Yifan Hong158655a2016-11-08 12:34:07 -0800951 << iface->getBaseName()
Steven Morelandd39133b2016-11-11 12:30:08 -0800952 << "::descriptor]\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800953 out.indent(2, [&] {
Yifan Hong158655a2016-11-08 12:34:07 -0800954 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800955 out.indent([&] {
Yifan Hong158655a2016-11-08 12:34:07 -0800956 out << "return new Bn"
957 << iface->getBaseName()
958 << "(reinterpret_cast<I"
959 << iface->getBaseName()
960 << " *>(iIntf));\n";
961 });
962 out << "};\n";
963 });
Yifan Hong7a118f52016-12-07 11:21:15 -0800964 out << "::android::hardware::gBsConstructorMap[I"
965 << iface->getBaseName()
966 << "::descriptor]\n";
967 out.indent(2, [&] {
968 out << "= [](void *iIntf) -> ::android::sp<"
969 << gIBaseFqName.cppName()
970 << "> {\n";
971 out.indent([&] {
972 out << "return new Bs"
973 << iface->getBaseName()
974 << "(reinterpret_cast<I"
975 << iface->getBaseName()
976 << " *>(iIntf));\n";
977 });
978 out << "};\n";
979 });
Yifan Hong158655a2016-11-08 12:34:07 -0800980 out << "return 1;\n";
981 });
982 out << "}();\n\n";
983
Yifan Hongfe95aa22016-10-19 17:26:45 -0700984 err = generateInterfaceSource(out);
985 }
986
987 if (err == OK && isInterface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700988 err = generateProxySource(out, baseName);
989 }
990
991 if (err == OK && isInterface) {
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100992 err = generateStubSource(out, iface, baseName);
Andreas Huber881227d2016-08-02 14:20:21 -0700993 }
994
Steven Moreland40786312016-08-16 10:29:40 -0700995 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -0700996 err = generatePassthroughSource(out);
997 }
998
999 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001000 const Interface *iface = mRootScope->getInterface();
1001
Yifan Hongc8934042016-11-17 17:10:52 -08001002 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001003 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001004 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001005 std::string package = iface->fqName().package()
1006 + iface->fqName().atVersion();
1007
1008 implementServiceManagerInteractions(out, baseName, package);
Yifan Hongc8934042016-11-17 17:10:52 -08001009 }
Steven Moreland40786312016-08-16 10:29:40 -07001010 }
1011
Andreas Huber881227d2016-08-02 14:20:21 -07001012 enterLeaveNamespace(out, false /* enter */);
1013
1014 return err;
1015}
1016
Steven Moreland67f67b42016-09-29 08:59:02 -07001017// static
1018void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001019 out.sIf(nonNull + " == nullptr", [&] {
1020 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1021 out.indent(2, [&] {
1022 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1023 });
1024 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001025}
1026
Andreas Huber881227d2016-08-02 14:20:21 -07001027status_t AST::generateTypeSource(
1028 Formatter &out, const std::string &ifaceName) const {
1029 return mRootScope->emitTypeDefinitions(out, ifaceName);
1030}
1031
Andreas Hubere7ff2282016-08-16 13:50:03 -07001032void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001033 Formatter &out,
1034 const std::vector<TypedVar *> &args,
1035 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001036 if (args.empty()) {
1037 return;
1038 }
1039
1040 for (const auto &arg : args) {
1041 const Type &type = arg->type();
1042
Yifan Hong3b320f82016-11-01 15:15:54 -07001043 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001044 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001045 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001046 << ";\n";
1047 }
1048
1049 out << "\n";
1050}
1051
Andreas Huber881227d2016-08-02 14:20:21 -07001052void AST::emitCppReaderWriter(
1053 Formatter &out,
1054 const std::string &parcelObj,
1055 bool parcelObjIsPointer,
1056 const TypedVar *arg,
1057 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001058 Type::ErrorMode mode,
1059 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001060 const Type &type = arg->type();
1061
Andreas Huber881227d2016-08-02 14:20:21 -07001062 type.emitReaderWriter(
1063 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001064 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001065 parcelObj,
1066 parcelObjIsPointer,
1067 isReader,
1068 mode);
1069}
1070
Yifan Hongbf459bc2016-08-23 16:50:37 -07001071void AST::emitCppResolveReferences(
1072 Formatter &out,
1073 const std::string &parcelObj,
1074 bool parcelObjIsPointer,
1075 const TypedVar *arg,
1076 bool isReader,
1077 Type::ErrorMode mode,
1078 bool addPrefixToName) const {
1079 const Type &type = arg->type();
1080 if(type.needsResolveReferences()) {
1081 type.emitResolveReferences(
1082 out,
1083 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1084 isReader, // nameIsPointer
1085 parcelObj,
1086 parcelObjIsPointer,
1087 isReader,
1088 mode);
1089 }
1090}
1091
Yifan Hong068c5522016-10-31 14:07:25 -07001092status_t AST::generateProxyMethodSource(Formatter &out,
1093 const std::string &klassName,
1094 const Method *method,
1095 const Interface *superInterface) const {
1096
1097 method->generateCppSignature(out,
1098 klassName,
1099 true /* specify namespaces */);
1100
1101 const bool returnsValue = !method->results().empty();
1102 const TypedVar *elidedReturn = method->canElideCallback();
1103
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001104 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001105
1106 out.indent();
1107
Martijn Coenen115d4282016-12-19 05:14:04 +01001108 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1109 method->cppImpl(IMPL_PROXY, out);
1110 out.unindent();
1111 out << "}\n\n";
1112 return OK;
1113 }
1114
Yifan Hong068c5522016-10-31 14:07:25 -07001115 if (returnsValue && elidedReturn == nullptr) {
1116 generateCheckNonNull(out, "_hidl_cb");
1117 }
1118
1119 status_t status = generateCppInstrumentationCall(
1120 out,
1121 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001122 method);
1123 if (status != OK) {
1124 return status;
1125 }
1126
1127 out << "::android::hardware::Parcel _hidl_data;\n";
1128 out << "::android::hardware::Parcel _hidl_reply;\n";
1129 out << "::android::status_t _hidl_err;\n";
1130 out << "::android::hardware::Status _hidl_status;\n\n";
1131
1132 declareCppReaderLocals(
1133 out, method->results(), true /* forResults */);
1134
1135 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongc8934042016-11-17 17:10:52 -08001136 out << superInterface->fqName().cppNamespace()
1137 << "::I"
1138 << superInterface->getBaseName();
Yifan Hong068c5522016-10-31 14:07:25 -07001139 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001140 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1141
Martijn Coenenfff73352017-01-04 16:36:31 +01001142 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001143 // First DFS: write all buffers and resolve pointers for parent
1144 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001145 if (arg->type().isInterface()) {
1146 hasInterfaceArgument = true;
1147 }
Yifan Hong068c5522016-10-31 14:07:25 -07001148 emitCppReaderWriter(
1149 out,
1150 "_hidl_data",
1151 false /* parcelObjIsPointer */,
1152 arg,
1153 false /* reader */,
1154 Type::ErrorMode_Goto,
1155 false /* addPrefixToName */);
1156 }
1157
1158 // Second DFS: resolve references.
1159 for (const auto &arg : method->args()) {
1160 emitCppResolveReferences(
1161 out,
1162 "_hidl_data",
1163 false /* parcelObjIsPointer */,
1164 arg,
1165 false /* reader */,
1166 Type::ErrorMode_Goto,
1167 false /* addPrefixToName */);
1168 }
1169
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001170 if (hasInterfaceArgument) {
1171 // Start binder threadpool to handle incoming transactions
1172 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1173 }
Yifan Hong068c5522016-10-31 14:07:25 -07001174 out << "_hidl_err = remote()->transact("
1175 << method->getSerialId()
1176 << " /* "
1177 << method->name()
1178 << " */, _hidl_data, &_hidl_reply";
1179
1180 if (method->isOneway()) {
1181 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1182 }
1183 out << ");\n";
1184
1185 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1186
1187 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001188 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001189 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1190 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1191
1192
1193 // First DFS: write all buffers and resolve pointers for parent
1194 for (const auto &arg : method->results()) {
1195 emitCppReaderWriter(
1196 out,
1197 "_hidl_reply",
1198 false /* parcelObjIsPointer */,
1199 arg,
1200 true /* reader */,
1201 Type::ErrorMode_Goto,
1202 true /* addPrefixToName */);
1203 }
1204
1205 // Second DFS: resolve references.
1206 for (const auto &arg : method->results()) {
1207 emitCppResolveReferences(
1208 out,
1209 "_hidl_reply",
1210 false /* parcelObjIsPointer */,
1211 arg,
1212 true /* reader */,
1213 Type::ErrorMode_Goto,
1214 true /* addPrefixToName */);
1215 }
1216
1217 if (returnsValue && elidedReturn == nullptr) {
1218 out << "_hidl_cb(";
1219
1220 bool first = true;
1221 for (const auto &arg : method->results()) {
1222 if (!first) {
1223 out << ", ";
1224 }
1225
1226 if (arg->type().resultNeedsDeref()) {
1227 out << "*";
1228 }
1229 out << "_hidl_out_" << arg->name();
1230
1231 first = false;
1232 }
1233
1234 out << ");\n\n";
1235 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001236 }
1237 status = generateCppInstrumentationCall(
1238 out,
1239 InstrumentationEvent::CLIENT_API_EXIT,
1240 method);
1241 if (status != OK) {
1242 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001243 }
1244
1245 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001246 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1247 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001248 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001249 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1250 } else {
1251 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1252 out << "return ::android::hardware::Return<void>();\n\n";
1253 }
1254
1255 out.unindent();
1256 out << "_hidl_error:\n";
1257 out.indent();
1258 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1259 out << "return ::android::hardware::Return<";
1260 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001261 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001262 } else {
1263 out << "void";
1264 }
1265 out << ">(_hidl_status);\n";
1266
1267 out.unindent();
1268 out << "}\n\n";
1269 return OK;
1270}
1271
Andreas Huber881227d2016-08-02 14:20:21 -07001272status_t AST::generateProxySource(
1273 Formatter &out, const std::string &baseName) const {
1274 const std::string klassName = "Bp" + baseName;
1275
1276 out << klassName
1277 << "::"
1278 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001279 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001280
1281 out.indent();
1282 out.indent();
1283
1284 out << ": BpInterface"
Martijn Coenena63e0ad2016-12-07 17:29:00 +01001285 << "<I"
Andreas Huber881227d2016-08-02 14:20:21 -07001286 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001287 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001288 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001289 << mPackage.string()
1290 << "::I"
1291 << baseName
1292 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001293
Andreas Huber881227d2016-08-02 14:20:21 -07001294 out.unindent();
1295 out.unindent();
1296 out << "}\n\n";
1297
Yifan Hong068c5522016-10-31 14:07:25 -07001298 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1299 return generateProxyMethodSource(out, klassName, method, superInterface);
1300 });
Andreas Huber881227d2016-08-02 14:20:21 -07001301
Yifan Hong068c5522016-10-31 14:07:25 -07001302 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001303}
1304
1305status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001306 Formatter &out,
1307 const Interface *iface,
1308 const std::string &baseName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001309 const std::string klassName = "Bn" + baseName;
1310
Steven Moreland40786312016-08-16 10:29:40 -07001311 out << klassName
1312 << "::"
1313 << klassName
1314 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl)\n";
1315
1316 out.indent();
1317 out.indent();
1318
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001319 if (iface->isIBase()) {
1320 out << ": ::android::hardware::HidlInstrumentor(\"";
1321 } else {
1322 out << ": ::android::hidl::base::V1_0::BnBase(_hidl_impl, \"";
1323 }
1324
1325 out << mPackage.string()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001326 << "::I"
1327 << baseName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001328 << "\") { \n";
1329 out.indent();
1330 out << "_hidl_mImpl = _hidl_impl;\n";
1331 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001332
1333 out.unindent();
1334 out.unindent();
1335 out << "}\n\n";
1336
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001337 if (iface->isIBase()) {
1338 // BnBase has a constructor to initialize the HidlInstrumentor
1339 // class properly.
1340 out << klassName
1341 << "::"
1342 << klassName
1343 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl,"
1344 << " const std::string &prefix)\n";
1345
1346 out.indent();
1347 out.indent();
1348
1349 out << ": ::android::hardware::HidlInstrumentor(prefix) { \n";
1350 out.indent();
1351 out << "_hidl_mImpl = _hidl_impl;\n";
1352 out.unindent();
1353
1354 out.unindent();
1355 out.unindent();
1356 out << "}\n\n";
1357 }
1358
1359
Andreas Huber881227d2016-08-02 14:20:21 -07001360 out << "::android::status_t " << klassName << "::onTransact(\n";
1361
1362 out.indent();
1363 out.indent();
1364
Iliyan Malchev549e2592016-08-10 08:59:12 -07001365 out << "uint32_t _hidl_code,\n"
1366 << "const ::android::hardware::Parcel &_hidl_data,\n"
1367 << "::android::hardware::Parcel *_hidl_reply,\n"
1368 << "uint32_t _hidl_flags,\n"
1369 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001370
1371 out.unindent();
1372
Iliyan Malchev549e2592016-08-10 08:59:12 -07001373 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001374 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001375 out.indent();
1376
Yifan Hong10fe0b52016-10-19 14:20:17 -07001377 for (const auto &tuple : iface->allMethodsFromRoot()) {
1378 const Method *method = tuple.method();
1379 const Interface *superInterface = tuple.interface();
1380 out << "case "
1381 << method->getSerialId()
1382 << " /* "
1383 << method->name()
1384 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001385
Yifan Hong10fe0b52016-10-19 14:20:17 -07001386 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001387
Yifan Hong10fe0b52016-10-19 14:20:17 -07001388 status_t err =
1389 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001390
Yifan Hong10fe0b52016-10-19 14:20:17 -07001391 if (err != OK) {
1392 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001393 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001394
1395 out.unindent();
1396 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001397 }
1398
1399 out << "default:\n{\n";
1400 out.indent();
1401
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001402 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001403
1404 out.indent();
1405 out.indent();
1406
Iliyan Malchev549e2592016-08-10 08:59:12 -07001407 out << "_hidl_code, _hidl_data, _hidl_reply, "
1408 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001409
1410 out.unindent();
1411 out.unindent();
1412
1413 out.unindent();
1414 out << "}\n";
1415
1416 out.unindent();
1417 out << "}\n\n";
1418
Yifan Honga018ed52016-12-13 16:35:08 -08001419 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1420 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1421 out.indent(2, [&] {
1422 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1423 out << "_hidl_reply);\n";
1424 });
1425 });
Andreas Huber881227d2016-08-02 14:20:21 -07001426
Iliyan Malchev549e2592016-08-10 08:59:12 -07001427 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001428
1429 out.unindent();
1430 out << "}\n\n";
1431
1432 return OK;
1433}
1434
1435status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001436 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001437 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1438 method->cppImpl(IMPL_STUB, out);
1439 out << "break;\n";
1440 return OK;
1441 }
1442
Yifan Hong10fe0b52016-10-19 14:20:17 -07001443 out << "if (!_hidl_data.enforceInterface(";
1444
Yifan Hongc8934042016-11-17 17:10:52 -08001445 out << iface->fqName().cppNamespace()
1446 << "::I"
1447 << iface->getBaseName();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001448
1449 out << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001450
Andreas Huber881227d2016-08-02 14:20:21 -07001451 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001452 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001453 out << "break;\n";
1454 out.unindent();
1455 out << "}\n\n";
1456
Andreas Huber5e44a292016-09-27 14:52:39 -07001457 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001458
Yifan Hongbf459bc2016-08-23 16:50:37 -07001459 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001460 for (const auto &arg : method->args()) {
1461 emitCppReaderWriter(
1462 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001463 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001464 false /* parcelObjIsPointer */,
1465 arg,
1466 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001467 Type::ErrorMode_Break,
1468 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001469 }
1470
Yifan Hongbf459bc2016-08-23 16:50:37 -07001471 // Second DFS: resolve references
1472 for (const auto &arg : method->args()) {
1473 emitCppResolveReferences(
1474 out,
1475 "_hidl_data",
1476 false /* parcelObjIsPointer */,
1477 arg,
1478 true /* reader */,
1479 Type::ErrorMode_Break,
1480 false /* addPrefixToName */);
1481 }
1482
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001483 status_t status = generateCppInstrumentationCall(
1484 out,
1485 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001486 method);
1487 if (status != OK) {
1488 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001489 }
1490
Andreas Huber881227d2016-08-02 14:20:21 -07001491 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001492 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001493
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001494 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001495 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001496 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001497 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001498 << " = "
1499 << "_hidl_mImpl->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001500 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001501
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001502 bool first = true;
1503 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001504 if (!first) {
1505 out << ", ";
1506 }
1507
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001508 if (arg->type().resultNeedsDeref()) {
1509 out << "*";
1510 }
1511
1512 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001513
1514 first = false;
1515 }
1516
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001517 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001518 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1519 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001520
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001521 elidedReturn->type().emitReaderWriter(
1522 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001523 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001524 "_hidl_reply",
1525 true, /* parcelObjIsPointer */
1526 false, /* isReader */
1527 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001528
Yifan Hongbf459bc2016-08-23 16:50:37 -07001529 emitCppResolveReferences(
1530 out,
1531 "_hidl_reply",
1532 true /* parcelObjIsPointer */,
1533 elidedReturn,
1534 false /* reader */,
1535 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001536 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001537
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001538 status_t status = generateCppInstrumentationCall(
1539 out,
1540 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001541 method);
1542 if (status != OK) {
1543 return status;
1544 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001545
Iliyan Malchev549e2592016-08-10 08:59:12 -07001546 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001547 } else {
1548 if (returnsValue) {
1549 out << "bool _hidl_callbackCalled = false;\n\n";
1550 }
Andreas Huber881227d2016-08-02 14:20:21 -07001551
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001552 out << "_hidl_mImpl->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001553
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001554 bool first = true;
1555 for (const auto &arg : method->args()) {
1556 if (!first) {
1557 out << ", ";
1558 }
Andreas Huber881227d2016-08-02 14:20:21 -07001559
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001560 if (arg->type().resultNeedsDeref()) {
1561 out << "*";
1562 }
1563
1564 out << arg->name();
1565
1566 first = false;
1567 }
1568
1569 if (returnsValue) {
1570 if (!first) {
1571 out << ", ";
1572 }
1573
1574 out << "[&](";
1575
1576 first = true;
1577 for (const auto &arg : method->results()) {
1578 if (!first) {
1579 out << ", ";
1580 }
1581
Yifan Honga47eef32016-12-12 10:38:54 -08001582 out << "const auto &_hidl_out_" << arg->name();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001583
1584 first = false;
1585 }
1586
1587 out << ") {\n";
1588 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001589 out << "if (_hidl_callbackCalled) {\n";
1590 out.indent();
1591 out << "LOG_ALWAYS_FATAL(\""
1592 << method->name()
1593 << ": _hidl_cb called a second time, but must be called once.\");\n";
1594 out.unindent();
1595 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001596 out << "_hidl_callbackCalled = true;\n\n";
1597
Yifan Hong859e53f2016-11-14 19:08:24 -08001598 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1599 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001600
Yifan Hongbf459bc2016-08-23 16:50:37 -07001601 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001602 for (const auto &arg : method->results()) {
1603 emitCppReaderWriter(
1604 out,
1605 "_hidl_reply",
1606 true /* parcelObjIsPointer */,
1607 arg,
1608 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001609 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001610 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001611 }
1612
Yifan Hongbf459bc2016-08-23 16:50:37 -07001613 // Second DFS: resolve references
1614 for (const auto &arg : method->results()) {
1615 emitCppResolveReferences(
1616 out,
1617 "_hidl_reply",
1618 true /* parcelObjIsPointer */,
1619 arg,
1620 false /* reader */,
1621 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001622 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001623 }
1624
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001625 status_t status = generateCppInstrumentationCall(
1626 out,
1627 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001628 method);
1629 if (status != OK) {
1630 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001631 }
1632
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001633 out << "_hidl_cb(*_hidl_reply);\n";
1634
1635 out.unindent();
1636 out << "}\n";
1637 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001638 out << ");\n\n";
1639
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001640 if (returnsValue) {
1641 out << "if (!_hidl_callbackCalled) {\n";
1642 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001643 out << "LOG_ALWAYS_FATAL(\""
1644 << method->name()
1645 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001646 out.unindent();
1647 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001648 } else {
1649 out << "::android::hardware::writeToParcel("
1650 << "::android::hardware::Status::ok(), "
1651 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001652 }
Andreas Huber881227d2016-08-02 14:20:21 -07001653 }
1654
1655 out << "break;\n";
1656
1657 return OK;
1658}
1659
Steven Moreland69e7c702016-09-09 11:16:32 -07001660status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1661 std::string ifaceName;
1662 if (!AST::isInterface(&ifaceName)) {
1663 // types.hal does not get a stub header.
1664 return OK;
1665 }
1666
1667 const Interface *iface = mRootScope->getInterface();
1668
1669 const std::string baseName = iface->getBaseName();
1670 const std::string klassName = "Bs" + baseName;
1671
1672 bool supportOneway = iface->hasOnewayMethods();
1673
1674 std::string path = outputPath;
1675 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1676 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1677 path.append(klassName);
1678 path.append(".h");
1679
1680 CHECK(Coordinator::MakeParentHierarchy(path));
1681 FILE *file = fopen(path.c_str(), "w");
1682
1683 if (file == NULL) {
1684 return -errno;
1685 }
1686
1687 Formatter out(file);
1688
1689 const std::string guard = makeHeaderGuard(klassName);
1690
1691 out << "#ifndef " << guard << "\n";
1692 out << "#define " << guard << "\n\n";
1693
1694 std::vector<std::string> packageComponents;
1695 getPackageAndVersionComponents(
1696 &packageComponents, false /* cpp_compatible */);
1697
Yifan Hongb0949432016-12-15 15:32:24 -08001698 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001699 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001700
1701 generateCppPackageInclude(out, mPackage, ifaceName);
1702 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001703
Yifan Hong7a118f52016-12-07 11:21:15 -08001704 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001705 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001706 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001707 }
1708
1709 enterLeaveNamespace(out, true /* enter */);
1710 out << "\n";
1711
1712 out << "struct "
1713 << klassName
1714 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001715 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001716
1717 out.indent();
1718 out << "explicit "
1719 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001720 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001721 << ifaceName
1722 << "> impl);\n";
1723
Yifan Hong068c5522016-10-31 14:07:25 -07001724 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1725 return generatePassthroughMethod(out, method);
1726 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001727
1728 if (err != OK) {
1729 return err;
1730 }
1731
1732 out.unindent();
1733 out << "private:\n";
1734 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001735 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001736
1737 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001738 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001739
1740 out << "\n";
1741
1742 out << "::android::hardware::Return<void> addOnewayTask("
1743 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001744 }
1745
1746 out.unindent();
1747
1748 out << "};\n\n";
1749
1750 enterLeaveNamespace(out, false /* enter */);
1751
1752 out << "\n#endif // " << guard << "\n";
1753
1754 return OK;
1755}
1756
Yifan Hongfe95aa22016-10-19 17:26:45 -07001757status_t AST::generateInterfaceSource(Formatter &out) const {
1758 const Interface *iface = mRootScope->getInterface();
1759
Yifan Hong2d7126b2016-10-20 15:12:57 -07001760 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001761 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001762
Yifan Hong3d746092016-12-07 14:26:33 -08001763 for (const Interface *superType : iface->typeChain()) {
1764 out << "// static \n"
1765 << childTypeResult
1766 << " I"
1767 << iface->getBaseName()
1768 << "::castFrom("
1769 << superType->getCppArgumentType()
1770 << " parent) {\n";
1771 out.indent();
1772 if (iface == superType) {
1773 out << "return parent;\n";
1774 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001775 out << "return ::android::hardware::castInterface<";
1776 out << "I" << iface->getBaseName() << ", "
1777 << superType->fqName().cppName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001778 << iface->getProxyFqName().cppLocalName() << ", "
1779 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001780 << ">(\n";
1781 out.indent();
1782 out.indent();
1783 out << "parent, \""
1784 << iface->fqName().string()
1785 << "\");\n";
1786 out.unindent();
1787 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001788 }
Yifan Hong3d746092016-12-07 14:26:33 -08001789 out.unindent();
1790 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001791 }
1792
1793 return OK;
1794}
1795
Steven Moreland69e7c702016-09-09 11:16:32 -07001796status_t AST::generatePassthroughSource(Formatter &out) const {
1797 const Interface *iface = mRootScope->getInterface();
1798
1799 const std::string baseName = iface->getBaseName();
1800 const std::string klassName = "Bs" + baseName;
1801
1802 out << klassName
1803 << "::"
1804 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001805 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001806 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001807 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001808 << iface->fqName().string()
1809 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001810 if (iface->hasOnewayMethods()) {
1811 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001812 out.indent([&] {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001813 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1814 });
1815 }
1816 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001817
1818 if (iface->hasOnewayMethods()) {
1819 out << "::android::hardware::Return<void> "
1820 << klassName
1821 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1822 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001823 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001824 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001825 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1826 out.indent();
1827 out.indent();
1828 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1829 out.unindent();
1830 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001831 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001832 out << "}\n";
1833
Steven Morelandd366c262016-10-11 15:29:10 -07001834 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001835
1836 out.unindent();
1837 out << "}\n\n";
1838
1839
1840 }
1841
1842 return OK;
1843}
1844
Martijn Coenen7b295242016-11-04 16:52:56 +01001845status_t AST::generateCppAtraceCall(Formatter &out,
1846 InstrumentationEvent event,
1847 const Method *method) const {
1848 const Interface *iface = mRootScope->getInterface();
1849 std::string baseString = "HIDL::I" + iface->getBaseName() + "::" + method->name();
1850 switch (event) {
1851 case SERVER_API_ENTRY:
1852 {
1853 out << "atrace_begin(ATRACE_TAG_HAL, \""
1854 << baseString + "::server\");\n";
1855 break;
1856 }
1857 case CLIENT_API_ENTRY:
1858 {
1859 out << "atrace_begin(ATRACE_TAG_HAL, \""
1860 << baseString + "::client\");\n";
1861 break;
1862 }
1863 case PASSTHROUGH_ENTRY:
1864 {
1865 out << "atrace_begin(ATRACE_TAG_HAL, \""
1866 << baseString + "::passthrough\");\n";
1867 break;
1868 }
1869 case SERVER_API_EXIT:
1870 case CLIENT_API_EXIT:
1871 case PASSTHROUGH_EXIT:
1872 {
1873 out << "atrace_end(ATRACE_TAG_HAL);\n";
1874 break;
1875 }
1876 default:
1877 {
1878 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1879 return UNKNOWN_ERROR;
1880 }
1881 }
1882
1883 return OK;
1884}
1885
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001886status_t AST::generateCppInstrumentationCall(
1887 Formatter &out,
1888 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001889 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001890 status_t err = generateCppAtraceCall(out, event, method);
1891 if (err != OK) {
1892 return err;
1893 }
1894
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001895 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1896 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001897 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001898 std::string event_str = "";
1899 switch (event) {
1900 case SERVER_API_ENTRY:
1901 {
1902 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1903 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001904 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001905 << (arg->type().resultNeedsDeref() ? "" : "&")
1906 << arg->name()
1907 << ");\n";
1908 }
1909 break;
1910 }
1911 case SERVER_API_EXIT:
1912 {
1913 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001914 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001915 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001916 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001917 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001918 }
1919 break;
1920 }
1921 case CLIENT_API_ENTRY:
1922 {
1923 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1924 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001925 out << "_hidl_args.push_back((void *)&"
1926 << arg->name()
1927 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001928 }
1929 break;
1930 }
1931 case CLIENT_API_EXIT:
1932 {
1933 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1934 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001935 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001936 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001937 << "_hidl_out_"
1938 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001939 << ");\n";
1940 }
1941 break;
1942 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001943 case PASSTHROUGH_ENTRY:
1944 {
1945 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1946 for (const auto &arg : method->args()) {
1947 out << "_hidl_args.push_back((void *)&"
1948 << arg->name()
1949 << ");\n";
1950 }
1951 break;
1952 }
1953 case PASSTHROUGH_EXIT:
1954 {
1955 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001956 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001957 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001958 << arg->name()
1959 << ");\n";
1960 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001961 break;
1962 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001963 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001964 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001965 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001966 return UNKNOWN_ERROR;
1967 }
1968 }
1969
Steven Moreland031ccf12016-10-31 15:54:38 -07001970 const Interface *iface = mRootScope->getInterface();
1971
Steven Moreland1ab31442016-11-03 18:37:51 -07001972 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001973 out.indent();
1974 out << "callback("
1975 << event_str
1976 << ", \""
1977 << mPackage.package()
1978 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07001979 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001980 << "\", \""
1981 << iface->localName()
1982 << "\", \""
1983 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001984 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001985 out.unindent();
1986 out << "}\n";
1987 out.unindent();
1988 out << "}\n\n";
1989
1990 return OK;
1991}
1992
Andreas Huber881227d2016-08-02 14:20:21 -07001993} // namespace android
1994