blob: 7f3f4cce6ef9dac215e1ed3455a3777ec2601e4e [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", [&] {
154 out << "::android::sp<::android::hidl::base::V1_0::IBase> base;\n"
155 << "::android::hardware::Return<void> ret =\n";
156 out.indent(2, [&] {
157 out << "sm->get(\"" << package << "::I" << baseName << "\", serviceName.c_str(),\n";
158 out.indent(2, [&] {
159 out << "[&base](::android::sp<::android::hidl::base::V1_0::IBase> found) ";
160 out.block([&] {
161 out << "base = found;\n";
162 });
163 out << ");\n";
164 });
165 });
166 out.sIf("ret.getStatus().isOk()", [&] {
167 out << "iface = I" << baseName << "::castFrom(base);\n";
168 out.sIf("iface != nullptr", [&] {
169 out << "return iface;\n";
170 }).endl();
171 }).endl();
172 }).endl();
173 out << "const int dlMode = RTLD_LAZY;\n";
174 out << "void *handle = nullptr;\n";
175 for (const auto &path : std::vector<std::string>({
176 "HAL_LIBRARY_PATH_ODM", "HAL_LIBRARY_PATH_VENDOR", "HAL_LIBRARY_PATH_SYSTEM"
177 })) {
178 out.sIf("handle == nullptr", [&] {
179 out << "handle = dlopen("
180 << path << " \"" << package << "-impl.so\", dlMode);\n";
181 }).endl();
182 }
183 out.sIf("handle == nullptr", [&] {
184 out << "return iface;\n";
185 }).endl();
186 out << "I" << baseName << "* (*generator)(const char* name);\n"
187 << "*(void **)(&generator) = dlsym(handle, \"HIDL_FETCH_I" << baseName << "\");\n";
188 out.sIf("generator", [&] {
189 out << "iface = (*generator)(serviceName.c_str());\n";
190 out.sIf("iface != nullptr", [&] {
191 out << "iface = new Bs" << baseName << "(iface);\n";
192 }).endl();
193 }).endl();
194 out << "return iface;\n";
195 }).endl().endl();
196
197 out << "::android::status_t I" << baseName << "::registerAsService("
198 << "const std::string &serviceName) ";
199 out.block([&] {
200 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
201 out.indent(2, [&] {
202 out << "= ::android::hardware::defaultServiceManager();\n";
203 });
204 out.sIf("sm == nullptr", [&] {
205 out << "return ::android::INVALID_OPERATION;\n";
206 }).endl();
207 out << "bool success = false;\n"
208 << "::android::hardware::Return<void> ret =\n";
209 out.indent(2, [&] {
210 out << "this->interfaceChain("
211 << "[&success, &sm, &serviceName, this](const auto &chain) ";
212 out.block([&] {
213 out << "::android::hardware::Return<bool> addRet = "
214 << "sm->add(chain, serviceName.c_str(), this);\n";
215 out << "success = addRet.isOk() && addRet;\n";
216 });
217 out << ");\n";
218 out << "success = success && ret.getStatus().isOk();\n";
219 });
220 out << "return success ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
221 }).endl().endl();
222
223 out << "bool I" << baseName << "::registerForNotifications(\n";
224 out.indent(2, [&] {
225 out << "const std::string &serviceName,\n"
226 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
227 << "&notification) ";
228 });
229 out.block([&] {
230 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
231 out.indent(2, [&] {
232 out << "= ::android::hardware::defaultServiceManager();\n";
233 });
234 out.sIf("sm == nullptr", [&] {
235 out << "return false;\n";
236 }).endl();
237 out << "::android::hardware::Return<bool> success =\n";
238 out.indent(2, [&] {
239 out << "sm->registerForNotifications(\"" << package << "::I" << baseName << "\",\n";
240 out.indent(2, [&] {
241 out << "serviceName, notification);\n";
242 });
243 });
244 out << "return success.isOk() && success;\n";
245 }).endl().endl();
246}
247
Andreas Huberb82318c2016-08-02 14:45:54 -0700248status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700249
Andreas Huberb82318c2016-08-02 14:45:54 -0700250 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700251 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700252 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700253
254 std::string ifaceName;
255 bool isInterface = true;
256 if (!AST::isInterface(&ifaceName)) {
257 ifaceName = "types";
258 isInterface = false;
259 }
260 path.append(ifaceName);
261 path.append(".h");
262
Andreas Huberd2943e12016-08-05 11:59:31 -0700263 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700264 FILE *file = fopen(path.c_str(), "w");
265
266 if (file == NULL) {
267 return -errno;
268 }
269
270 Formatter out(file);
271
272 const std::string guard = makeHeaderGuard(ifaceName);
273
274 out << "#ifndef " << guard << "\n";
275 out << "#define " << guard << "\n\n";
276
Andreas Huber737080b2016-08-02 15:38:04 -0700277 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700278 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700279 }
280
281 if (!mImportedNames.empty()) {
282 out << "\n";
283 }
284
Steven Moreland0693f312016-11-09 15:06:14 -0800285 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800286 if (isIBase()) {
287 out << "// skipped #include IServiceNotification.h\n\n";
288 } else {
289 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
290 }
Steven Moreland0693f312016-11-09 15:06:14 -0800291 }
292
Yifan Hongc8934042016-11-17 17:10:52 -0800293 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700294 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700295
296 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200297 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700298 }
299
Martijn Coenenaf712c02016-11-16 15:26:27 +0100300 out << "#include <utils/NativeHandle.h>\n";
301 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700302
303 enterLeaveNamespace(out, true /* enter */);
304 out << "\n";
305
306 if (isInterface) {
307 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700308 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700309
310 const Interface *iface = mRootScope->getInterface();
311 const Interface *superType = iface->superType();
312
Steven Moreland40786312016-08-16 10:29:40 -0700313 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800314 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700315 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000316 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700317 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700318 }
319
320 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700321
322 out.indent();
323
Andreas Huber881227d2016-08-02 14:20:21 -0700324 }
325
326 status_t err = emitTypeDeclarations(out);
327
328 if (err != OK) {
329 return err;
330 }
331
332 if (isInterface) {
333 const Interface *iface = mRootScope->getInterface();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700334 const Interface *superType = iface->superType();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700335 const std::string baseName = iface->getBaseName();
Steven Moreland19d5c172016-10-20 19:20:25 -0700336 out << "constexpr static ::android::hardware::hidl_version version = {"
Yifan Hongd7200502016-12-21 15:01:27 -0800337 << mPackage.getPackageMajorVersion() << ", "
Martijn Coenena21f1492016-09-08 15:55:14 +0200338 << mPackage.getPackageMinorVersion() << "};\n";
Yifan Hongd7200502016-12-21 15:01:27 -0800339 out << "virtual const ::android::hardware::hidl_version &"
Steven Moreland19d5c172016-10-20 19:20:25 -0700340 << "getInterfaceVersion() const {\n";
Martijn Coenena21f1492016-09-08 15:55:14 +0200341 out.indent();
342 out << "return version;\n";
343 out.unindent();
344 out << "}\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800345 out << "virtual bool isRemote() const ";
346 if (!isIBase()) {
347 out << "override ";
348 }
349 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800350
Andreas Huber881227d2016-08-02 14:20:21 -0700351 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700352 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700353
Andreas Huber881227d2016-08-02 14:20:21 -0700354 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800355 const TypedVar *elidedReturn = method->canElideCallback();
356
357 if (elidedReturn == nullptr && returnsValue) {
358 out << "using "
359 << method->name()
360 << "_cb = std::function<void("
361 << Method::GetArgSignature(method->results(),
362 true /* specify namespaces */)
363 << ")>;\n";
364 }
Andreas Huber881227d2016-08-02 14:20:21 -0700365
Andreas Huber3599d922016-08-09 10:42:57 -0700366 method->dumpAnnotations(out);
367
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700368 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700369 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700370 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700371 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700372 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700373 }
374
375 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700376 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700377 << Method::GetArgSignature(method->args(),
378 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700379
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700380 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700381 if (!method->args().empty()) {
382 out << ", ";
383 }
384
Steven Moreland67f67b42016-09-29 08:59:02 -0700385 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700386 }
387
Yifan Hong10fe0b52016-10-19 14:20:17 -0700388 out << ")";
389 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800390 if (!isIBase()) {
391 out << " override";
392 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700393 out << " {\n";
394 out.indent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100395 method->cppImpl(IMPL_HEADER, out);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700396 out.unindent();
397 out << "\n}\n";
398 } else {
399 out << " = 0;\n";
400 }
Andreas Huber881227d2016-08-02 14:20:21 -0700401 }
Steven Moreland40786312016-08-16 10:29:40 -0700402
Yifan Hong3d746092016-12-07 14:26:33 -0800403 out << "// cast static functions\n";
404 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700405
Yifan Hong3d746092016-12-07 14:26:33 -0800406 for (const Interface *superType : iface->typeChain()) {
407 out << "static "
408 << childTypeResult
409 << " castFrom("
410 << superType->getCppArgumentType()
411 << " parent"
412 << ");\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700413 }
414
Steven Morelandd39133b2016-11-11 12:30:08 -0800415 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700416
Yifan Hongc8934042016-11-17 17:10:52 -0800417 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800418 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800419 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800420 declareServiceManagerInteractions(out, baseName);
Yifan Hongc8934042016-11-17 17:10:52 -0800421 }
Yifan Hong158655a2016-11-08 12:34:07 -0800422
423 out << "private: static int hidlStaticBlock;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700424 }
425
426 if (isInterface) {
427 out.unindent();
428
Andreas Hubere3f769a2016-10-10 10:54:44 -0700429 out << "};\n\n";
430 }
431
432 err = mRootScope->emitGlobalTypeDeclarations(out);
433
434 if (err != OK) {
435 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700436 }
437
438 out << "\n";
439 enterLeaveNamespace(out, false /* enter */);
440
441 out << "\n#endif // " << guard << "\n";
442
443 return OK;
444}
445
Steven Moreland40786312016-08-16 10:29:40 -0700446status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
447 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800448 bool isInterface = AST::isInterface(&ifaceName);
449 const Interface *iface = nullptr;
450 std::string baseName{};
451 std::string klassName{};
452
453 if(isInterface) {
454 iface = mRootScope->getInterface();
455 baseName = iface->getBaseName();
456 klassName = "IHw" + baseName;
457 } else {
458 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700459 }
460
Steven Moreland40786312016-08-16 10:29:40 -0700461 std::string path = outputPath;
462 path.append(mCoordinator->convertPackageRootToPath(mPackage));
463 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
464 path.append(klassName + ".h");
465
Yifan Hong244e82d2016-11-11 11:13:57 -0800466 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700467
468 if (file == NULL) {
469 return -errno;
470 }
471
472 Formatter out(file);
473
474 const std::string guard = makeHeaderGuard(klassName);
475
476 out << "#ifndef " << guard << "\n";
477 out << "#define " << guard << "\n\n";
478
Yifan Hong244e82d2016-11-11 11:13:57 -0800479 if (isInterface) {
480 generateCppPackageInclude(out, mPackage, ifaceName);
481 } else {
482 generateCppPackageInclude(out, mPackage, "types");
483 }
Steven Moreland40786312016-08-16 10:29:40 -0700484
Steven Morelandee88eed2016-10-31 17:49:00 -0700485 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700486
487 for (const auto &item : mImportedNames) {
488 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800489 generateCppPackageInclude(out, item, "hwtypes");
490 } else {
491 generateCppPackageInclude(out, item, "Bn" + item.getInterfaceBaseName());
Martijn Coenena63e0ad2016-12-07 17:29:00 +0100492 generateCppPackageInclude(out, item, "Bp" + item.getInterfaceBaseName());
Steven Moreland40786312016-08-16 10:29:40 -0700493 }
Steven Moreland40786312016-08-16 10:29:40 -0700494 }
495
496 out << "\n";
497
Martijn Coenen93915102016-09-01 01:35:52 +0200498 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700499 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100500 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700501
502 out << "\n";
503
504 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700505
Yifan Hong244e82d2016-11-11 11:13:57 -0800506 status_t err = mRootScope->emitGlobalHwDeclarations(out);
507 if (err != OK) {
508 return err;
509 }
Steven Moreland40786312016-08-16 10:29:40 -0700510
511 enterLeaveNamespace(out, false /* enter */);
512
513 out << "\n#endif // " << guard << "\n";
514
515 return OK;
516}
517
Andreas Huber881227d2016-08-02 14:20:21 -0700518status_t AST::emitTypeDeclarations(Formatter &out) const {
519 return mRootScope->emitTypeDeclarations(out);
520}
521
Yifan Hong7a118f52016-12-07 11:21:15 -0800522static void wrapPassthroughArg(Formatter &out,
523 const TypedVar *arg, bool addPrefixToName,
524 std::function<void(void)> handleError) {
525 if (!arg->type().isInterface()) {
526 return;
527 }
528 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
529 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
530 + arg->name();
531 const Interface &iface = static_cast<const Interface &>(arg->type());
532 out << iface.getCppStackType() << " " << wrappedName << ";\n";
533 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
534 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
535 out << wrappedName
536 << " = "
537 << iface.fqName().cppName()
538 << "::castFrom(::android::hardware::wrapPassthrough("
539 << name << "));\n";
540 out.sIf(wrappedName + " == nullptr", [&] {
541 // Fatal error. Happens when the BsFoo class is not found in the binary
542 // or any dynamic libraries.
543 handleError();
544 }).endl();
545 }).sElse([&] {
546 out << wrappedName << " = " << name << ";\n";
547 }).endl().endl();
548}
549
Steven Moreland69e7c702016-09-09 11:16:32 -0700550status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700551 const Method *method) const {
552 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700553
554 out << " {\n";
555 out.indent();
556
557 const bool returnsValue = !method->results().empty();
558 const TypedVar *elidedReturn = method->canElideCallback();
559
Steven Moreland67f67b42016-09-29 08:59:02 -0700560 if (returnsValue && elidedReturn == nullptr) {
561 generateCheckNonNull(out, "_hidl_cb");
562 }
563
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700564 generateCppInstrumentationCall(
565 out,
566 InstrumentationEvent::PASSTHROUGH_ENTRY,
567 method);
568
Yifan Hong7a118f52016-12-07 11:21:15 -0800569
570 for (const auto &arg : method->args()) {
571 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
572 out << "return ::android::hardware::Status::fromExceptionCode(\n";
573 out.indent(2, [&] {
574 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800575 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800576 });
577 });
578 }
579
580 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700581 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700582
583 if (method->isOneway()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800584 out << "addOnewayTask([this, &_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700585 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800586 out << ", "
587 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
588 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700589 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700590 out << "] {\n";
591 out.indent();
592 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700593 }
594
595 out << "mImpl->"
596 << method->name()
597 << "(";
598
599 bool first = true;
600 for (const auto &arg : method->args()) {
601 if (!first) {
602 out << ", ";
603 }
604 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800605 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700606 }
607 if (returnsValue && elidedReturn == nullptr) {
608 if (!method->args().empty()) {
609 out << ", ";
610 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800611 out << "[&](";
612 first = true;
613 for (const auto &arg : method->results()) {
614 if (!first) {
615 out << ", ";
616 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700617
Yifan Hong7a118f52016-12-07 11:21:15 -0800618 out << "const auto &_hidl_out_"
619 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800620
621 first = false;
622 }
623
624 out << ") {\n";
625 out.indent();
626 status_t status = generateCppInstrumentationCall(
627 out,
628 InstrumentationEvent::PASSTHROUGH_EXIT,
629 method);
630 if (status != OK) {
631 return status;
632 }
633
Yifan Hong7a118f52016-12-07 11:21:15 -0800634 for (const auto &arg : method->results()) {
635 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
636 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
637 out.indent(2, [&] {
638 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800639 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800640 });
641 out << "return;\n";
642 });
643 }
644
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800645 out << "_hidl_cb(";
646 first = true;
647 for (const auto &arg : method->results()) {
648 if (!first) {
649 out << ", ";
650 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800651 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800652 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
653 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800654 }
655 out << ");\n";
656 out.unindent();
657 out << "});\n\n";
658 } else {
659 out << ");\n\n";
660 if (elidedReturn != nullptr) {
661 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800662 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800663 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000664 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800665 }
666 status_t status = generateCppInstrumentationCall(
667 out,
668 InstrumentationEvent::PASSTHROUGH_EXIT,
669 method);
670 if (status != OK) {
671 return status;
672 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700673 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700674
675 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700676 out.unindent();
677 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700678 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700679
680 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700681
682 out.unindent();
683 out << "}\n";
684
685 return OK;
686}
687
Yifan Hong068c5522016-10-31 14:07:25 -0700688status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700689
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700690 const Interface *iface = mRootScope->getInterface();
691
Yifan Hong10fe0b52016-10-19 14:20:17 -0700692 const Interface *prevIterface = nullptr;
693 for (const auto &tuple : iface->allMethodsFromRoot()) {
694 const Method *method = tuple.method();
695 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700696
Yifan Hong10fe0b52016-10-19 14:20:17 -0700697 if(prevIterface != superInterface) {
698 if (prevIterface != nullptr) {
699 out << "\n";
700 }
701 out << "// Methods from "
702 << superInterface->fullName()
703 << " follow.\n";
704 prevIterface = superInterface;
705 }
Yifan Hong068c5522016-10-31 14:07:25 -0700706 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700707
Yifan Hong10fe0b52016-10-19 14:20:17 -0700708 if (err != OK) {
709 return err;
710 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700711 }
712
Yifan Hong10fe0b52016-10-19 14:20:17 -0700713 out << "\n";
714
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700715 return OK;
716}
717
Andreas Huberb82318c2016-08-02 14:45:54 -0700718status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700719 std::string ifaceName;
720 if (!AST::isInterface(&ifaceName)) {
721 // types.hal does not get a stub header.
722 return OK;
723 }
724
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700725 const Interface *iface = mRootScope->getInterface();
726 const std::string baseName = iface->getBaseName();
Steven Moreland40786312016-08-16 10:29:40 -0700727 const std::string klassName = "Bn" + baseName;
Andreas Huber881227d2016-08-02 14:20:21 -0700728
Andreas Huberb82318c2016-08-02 14:45:54 -0700729 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700730 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700731 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700732 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700733 path.append(".h");
734
Andreas Huberd2943e12016-08-05 11:59:31 -0700735 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700736 FILE *file = fopen(path.c_str(), "w");
737
738 if (file == NULL) {
739 return -errno;
740 }
741
742 Formatter out(file);
743
Steven Moreland40786312016-08-16 10:29:40 -0700744 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700745
746 out << "#ifndef " << guard << "\n";
747 out << "#define " << guard << "\n\n";
748
Steven Morelandee88eed2016-10-31 17:49:00 -0700749 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
750 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700751
752 enterLeaveNamespace(out, true /* enter */);
753 out << "\n";
754
755 out << "struct "
756 << "Bn"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100757 << baseName;
758 if (iface->isIBase()) {
759 out << " : public ::android::hardware::BBinder";
760 out << ", public ::android::hardware::HidlInstrumentor {\n";
761 } else {
762 out << " : public ::android::hidl::base::V1_0::BnBase {\n";
763 }
Andreas Huber881227d2016-08-02 14:20:21 -0700764
765 out.indent();
Steven Moreland40786312016-08-16 10:29:40 -0700766 out << "explicit Bn"
767 << baseName
768 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100769 << "\n";
770 out << "explicit Bn"
771 << baseName
772 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
773 << " const std::string& prefix);"
Steven Moreland40786312016-08-16 10:29:40 -0700774 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700775 out << "::android::status_t onTransact(\n";
776 out.indent();
777 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700778 out << "uint32_t _hidl_code,\n";
779 out << "const ::android::hardware::Parcel &_hidl_data,\n";
780 out << "::android::hardware::Parcel *_hidl_reply,\n";
781 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700782 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700783 out.unindent();
784 out.unindent();
785
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100786 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
787 out.unindent();
788 out << "private:\n";
789 out.indent();
790 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700791 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700792 out << "};\n\n";
793
794 enterLeaveNamespace(out, false /* enter */);
795
796 out << "\n#endif // " << guard << "\n";
797
798 return OK;
799}
800
Andreas Huberb82318c2016-08-02 14:45:54 -0700801status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700802 std::string ifaceName;
803 if (!AST::isInterface(&ifaceName)) {
804 // types.hal does not get a proxy header.
805 return OK;
806 }
807
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700808 const Interface *iface = mRootScope->getInterface();
809 const std::string baseName = iface->getBaseName();
Andreas Huber881227d2016-08-02 14:20:21 -0700810
Andreas Huberb82318c2016-08-02 14:45:54 -0700811 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700812 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700813 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700814 path.append("Bp");
815 path.append(baseName);
816 path.append(".h");
817
Andreas Huberd2943e12016-08-05 11:59:31 -0700818 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700819 FILE *file = fopen(path.c_str(), "w");
820
821 if (file == NULL) {
822 return -errno;
823 }
824
825 Formatter out(file);
826
827 const std::string guard = makeHeaderGuard("Bp" + baseName);
828
829 out << "#ifndef " << guard << "\n";
830 out << "#define " << guard << "\n\n";
831
Martijn Coenen115d4282016-12-19 05:14:04 +0100832 out << "#include <hidl/HidlTransportSupport.h>\n\n";
833
Andreas Huber881227d2016-08-02 14:20:21 -0700834 std::vector<std::string> packageComponents;
835 getPackageAndVersionComponents(
836 &packageComponents, false /* cpp_compatible */);
837
Steven Morelandee88eed2016-10-31 17:49:00 -0700838 generateCppPackageInclude(out, mPackage, "IHw" + baseName);
839 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700840
841 enterLeaveNamespace(out, true /* enter */);
842 out << "\n";
843
844 out << "struct "
845 << "Bp"
846 << baseName
Martijn Coenena63e0ad2016-12-07 17:29:00 +0100847 << " : public ::android::hardware::BpInterface<I"
Steven Moreland40786312016-08-16 10:29:40 -0700848 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700849 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700850
851 out.indent();
852
853 out << "explicit Bp"
854 << baseName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700855 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700856 << "\n\n";
857
Yifan Hong10fe0b52016-10-19 14:20:17 -0700858 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700859
Yifan Hong068c5522016-10-31 14:07:25 -0700860 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
861 method->generateCppSignature(out);
862 out << " override;\n";
863 return OK;
864 });
Steven Moreland9c387612016-09-07 09:54:26 -0700865
866 if (err != OK) {
867 return err;
868 }
Andreas Huber881227d2016-08-02 14:20:21 -0700869
870 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100871 out << "private:\n";
872 out.indent();
873 out << "std::mutex _hidl_mMutex;\n"
874 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
875 << " _hidl_mDeathRecipients;\n";
876 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700877 out << "};\n\n";
878
879 enterLeaveNamespace(out, false /* enter */);
880
881 out << "\n#endif // " << guard << "\n";
882
883 return OK;
884}
885
Andreas Huberb82318c2016-08-02 14:45:54 -0700886status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700887
Andreas Huberb82318c2016-08-02 14:45:54 -0700888 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700889 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700890 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700891
892 std::string ifaceName;
893 std::string baseName;
894
Yifan Hongfe95aa22016-10-19 17:26:45 -0700895 const Interface *iface = nullptr;
896 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700897 if (!AST::isInterface(&ifaceName)) {
898 baseName = "types";
899 isInterface = false;
900 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700901 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700902 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700903 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700904 }
905
906 path.append(baseName);
907
908 if (baseName != "types") {
909 path.append("All");
910 }
911
912 path.append(".cpp");
913
Andreas Huberd2943e12016-08-05 11:59:31 -0700914 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700915 FILE *file = fopen(path.c_str(), "w");
916
917 if (file == NULL) {
918 return -errno;
919 }
920
921 Formatter out(file);
922
Steven Moreland05cd4232016-11-21 16:01:12 -0800923 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100924 out << "#include <cutils/trace.h>\n";
925 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700926 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700927 // This is a no-op for IServiceManager itself.
928 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
929
Steven Morelandee88eed2016-10-31 17:49:00 -0700930 generateCppPackageInclude(out, mPackage, "Bp" + baseName);
931 generateCppPackageInclude(out, mPackage, "Bn" + baseName);
932 generateCppPackageInclude(out, mPackage, "Bs" + baseName);
Yifan Hongfe95aa22016-10-19 17:26:45 -0700933
934 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700935 generateCppPackageInclude(out,
936 superType->fqName(),
937 "Bp" + superType->getBaseName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700938 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800939
940 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700941 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700942 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800943 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700944 }
945
946 out << "\n";
947
948 enterLeaveNamespace(out, true /* enter */);
949 out << "\n";
950
951 status_t err = generateTypeSource(out, ifaceName);
952
953 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700954 const Interface *iface = mRootScope->getInterface();
Steven Moreland19d5c172016-10-20 19:20:25 -0700955 out << "constexpr ::android::hardware::hidl_version "
956 << ifaceName
957 << "::version;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700958
959 // need to be put here, generateStubSource is using this.
Steven Morelandd39133b2016-11-11 12:30:08 -0800960 out << "const char* I"
Yifan Hong10fe0b52016-10-19 14:20:17 -0700961 << iface->getBaseName()
962 << "::descriptor(\""
963 << iface->fqName().string()
964 << "\");\n\n";
965
Yifan Hong158655a2016-11-08 12:34:07 -0800966 out << "int I"
967 << iface->getBaseName()
968 << "::hidlStaticBlock = []() -> int {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800969 out.indent([&] {
Steven Morelandd39133b2016-11-11 12:30:08 -0800970 out << "::android::hardware::gBnConstructorMap[I"
Yifan Hong158655a2016-11-08 12:34:07 -0800971 << iface->getBaseName()
Steven Morelandd39133b2016-11-11 12:30:08 -0800972 << "::descriptor]\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800973 out.indent(2, [&] {
Yifan Hong158655a2016-11-08 12:34:07 -0800974 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800975 out.indent([&] {
Yifan Hong158655a2016-11-08 12:34:07 -0800976 out << "return new Bn"
977 << iface->getBaseName()
978 << "(reinterpret_cast<I"
979 << iface->getBaseName()
980 << " *>(iIntf));\n";
981 });
982 out << "};\n";
983 });
Yifan Hong7a118f52016-12-07 11:21:15 -0800984 out << "::android::hardware::gBsConstructorMap[I"
985 << iface->getBaseName()
986 << "::descriptor]\n";
987 out.indent(2, [&] {
988 out << "= [](void *iIntf) -> ::android::sp<"
989 << gIBaseFqName.cppName()
990 << "> {\n";
991 out.indent([&] {
992 out << "return new Bs"
993 << iface->getBaseName()
994 << "(reinterpret_cast<I"
995 << iface->getBaseName()
996 << " *>(iIntf));\n";
997 });
998 out << "};\n";
999 });
Yifan Hong158655a2016-11-08 12:34:07 -08001000 out << "return 1;\n";
1001 });
1002 out << "}();\n\n";
1003
Yifan Hongfe95aa22016-10-19 17:26:45 -07001004 err = generateInterfaceSource(out);
1005 }
1006
1007 if (err == OK && isInterface) {
Andreas Huber881227d2016-08-02 14:20:21 -07001008 err = generateProxySource(out, baseName);
1009 }
1010
1011 if (err == OK && isInterface) {
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001012 err = generateStubSource(out, iface, baseName);
Andreas Huber881227d2016-08-02 14:20:21 -07001013 }
1014
Steven Moreland40786312016-08-16 10:29:40 -07001015 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001016 err = generatePassthroughSource(out);
1017 }
1018
1019 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001020 const Interface *iface = mRootScope->getInterface();
1021
Yifan Hongc8934042016-11-17 17:10:52 -08001022 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001023 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001024 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001025 std::string package = iface->fqName().package()
1026 + iface->fqName().atVersion();
1027
1028 implementServiceManagerInteractions(out, baseName, package);
Yifan Hongc8934042016-11-17 17:10:52 -08001029 }
Steven Moreland40786312016-08-16 10:29:40 -07001030 }
1031
Andreas Huber881227d2016-08-02 14:20:21 -07001032 enterLeaveNamespace(out, false /* enter */);
1033
1034 return err;
1035}
1036
Steven Moreland67f67b42016-09-29 08:59:02 -07001037// static
1038void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001039 out.sIf(nonNull + " == nullptr", [&] {
1040 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1041 out.indent(2, [&] {
1042 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1043 });
1044 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001045}
1046
Andreas Huber881227d2016-08-02 14:20:21 -07001047status_t AST::generateTypeSource(
1048 Formatter &out, const std::string &ifaceName) const {
1049 return mRootScope->emitTypeDefinitions(out, ifaceName);
1050}
1051
Andreas Hubere7ff2282016-08-16 13:50:03 -07001052void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001053 Formatter &out,
1054 const std::vector<TypedVar *> &args,
1055 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001056 if (args.empty()) {
1057 return;
1058 }
1059
1060 for (const auto &arg : args) {
1061 const Type &type = arg->type();
1062
Yifan Hong3b320f82016-11-01 15:15:54 -07001063 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001064 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001065 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001066 << ";\n";
1067 }
1068
1069 out << "\n";
1070}
1071
Andreas Huber881227d2016-08-02 14:20:21 -07001072void AST::emitCppReaderWriter(
1073 Formatter &out,
1074 const std::string &parcelObj,
1075 bool parcelObjIsPointer,
1076 const TypedVar *arg,
1077 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001078 Type::ErrorMode mode,
1079 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001080 const Type &type = arg->type();
1081
Andreas Huber881227d2016-08-02 14:20:21 -07001082 type.emitReaderWriter(
1083 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001084 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001085 parcelObj,
1086 parcelObjIsPointer,
1087 isReader,
1088 mode);
1089}
1090
Yifan Hongbf459bc2016-08-23 16:50:37 -07001091void AST::emitCppResolveReferences(
1092 Formatter &out,
1093 const std::string &parcelObj,
1094 bool parcelObjIsPointer,
1095 const TypedVar *arg,
1096 bool isReader,
1097 Type::ErrorMode mode,
1098 bool addPrefixToName) const {
1099 const Type &type = arg->type();
1100 if(type.needsResolveReferences()) {
1101 type.emitResolveReferences(
1102 out,
1103 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1104 isReader, // nameIsPointer
1105 parcelObj,
1106 parcelObjIsPointer,
1107 isReader,
1108 mode);
1109 }
1110}
1111
Yifan Hong068c5522016-10-31 14:07:25 -07001112status_t AST::generateProxyMethodSource(Formatter &out,
1113 const std::string &klassName,
1114 const Method *method,
1115 const Interface *superInterface) const {
1116
1117 method->generateCppSignature(out,
1118 klassName,
1119 true /* specify namespaces */);
1120
1121 const bool returnsValue = !method->results().empty();
1122 const TypedVar *elidedReturn = method->canElideCallback();
1123
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001124 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001125
1126 out.indent();
1127
Martijn Coenen115d4282016-12-19 05:14:04 +01001128 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1129 method->cppImpl(IMPL_PROXY, out);
1130 out.unindent();
1131 out << "}\n\n";
1132 return OK;
1133 }
1134
Yifan Hong068c5522016-10-31 14:07:25 -07001135 if (returnsValue && elidedReturn == nullptr) {
1136 generateCheckNonNull(out, "_hidl_cb");
1137 }
1138
1139 status_t status = generateCppInstrumentationCall(
1140 out,
1141 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001142 method);
1143 if (status != OK) {
1144 return status;
1145 }
1146
1147 out << "::android::hardware::Parcel _hidl_data;\n";
1148 out << "::android::hardware::Parcel _hidl_reply;\n";
1149 out << "::android::status_t _hidl_err;\n";
1150 out << "::android::hardware::Status _hidl_status;\n\n";
1151
1152 declareCppReaderLocals(
1153 out, method->results(), true /* forResults */);
1154
1155 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongc8934042016-11-17 17:10:52 -08001156 out << superInterface->fqName().cppNamespace()
1157 << "::I"
1158 << superInterface->getBaseName();
Yifan Hong068c5522016-10-31 14:07:25 -07001159 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001160 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1161
1162 // First DFS: write all buffers and resolve pointers for parent
1163 for (const auto &arg : method->args()) {
1164 emitCppReaderWriter(
1165 out,
1166 "_hidl_data",
1167 false /* parcelObjIsPointer */,
1168 arg,
1169 false /* reader */,
1170 Type::ErrorMode_Goto,
1171 false /* addPrefixToName */);
1172 }
1173
1174 // Second DFS: resolve references.
1175 for (const auto &arg : method->args()) {
1176 emitCppResolveReferences(
1177 out,
1178 "_hidl_data",
1179 false /* parcelObjIsPointer */,
1180 arg,
1181 false /* reader */,
1182 Type::ErrorMode_Goto,
1183 false /* addPrefixToName */);
1184 }
1185
1186 out << "_hidl_err = remote()->transact("
1187 << method->getSerialId()
1188 << " /* "
1189 << method->name()
1190 << " */, _hidl_data, &_hidl_reply";
1191
1192 if (method->isOneway()) {
1193 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1194 }
1195 out << ");\n";
1196
1197 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1198
1199 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001200 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001201 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1202 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1203
1204
1205 // First DFS: write all buffers and resolve pointers for parent
1206 for (const auto &arg : method->results()) {
1207 emitCppReaderWriter(
1208 out,
1209 "_hidl_reply",
1210 false /* parcelObjIsPointer */,
1211 arg,
1212 true /* reader */,
1213 Type::ErrorMode_Goto,
1214 true /* addPrefixToName */);
1215 }
1216
1217 // Second DFS: resolve references.
1218 for (const auto &arg : method->results()) {
1219 emitCppResolveReferences(
1220 out,
1221 "_hidl_reply",
1222 false /* parcelObjIsPointer */,
1223 arg,
1224 true /* reader */,
1225 Type::ErrorMode_Goto,
1226 true /* addPrefixToName */);
1227 }
1228
1229 if (returnsValue && elidedReturn == nullptr) {
1230 out << "_hidl_cb(";
1231
1232 bool first = true;
1233 for (const auto &arg : method->results()) {
1234 if (!first) {
1235 out << ", ";
1236 }
1237
1238 if (arg->type().resultNeedsDeref()) {
1239 out << "*";
1240 }
1241 out << "_hidl_out_" << arg->name();
1242
1243 first = false;
1244 }
1245
1246 out << ");\n\n";
1247 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001248 }
1249 status = generateCppInstrumentationCall(
1250 out,
1251 InstrumentationEvent::CLIENT_API_EXIT,
1252 method);
1253 if (status != OK) {
1254 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001255 }
1256
1257 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001258 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1259 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001260 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001261 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1262 } else {
1263 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1264 out << "return ::android::hardware::Return<void>();\n\n";
1265 }
1266
1267 out.unindent();
1268 out << "_hidl_error:\n";
1269 out.indent();
1270 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1271 out << "return ::android::hardware::Return<";
1272 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001273 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001274 } else {
1275 out << "void";
1276 }
1277 out << ">(_hidl_status);\n";
1278
1279 out.unindent();
1280 out << "}\n\n";
1281 return OK;
1282}
1283
Andreas Huber881227d2016-08-02 14:20:21 -07001284status_t AST::generateProxySource(
1285 Formatter &out, const std::string &baseName) const {
1286 const std::string klassName = "Bp" + baseName;
1287
1288 out << klassName
1289 << "::"
1290 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001291 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001292
1293 out.indent();
1294 out.indent();
1295
1296 out << ": BpInterface"
Martijn Coenena63e0ad2016-12-07 17:29:00 +01001297 << "<I"
Andreas Huber881227d2016-08-02 14:20:21 -07001298 << baseName
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001299 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001300 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001301 << mPackage.string()
1302 << "::I"
1303 << baseName
1304 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001305
Andreas Huber881227d2016-08-02 14:20:21 -07001306 out.unindent();
1307 out.unindent();
1308 out << "}\n\n";
1309
Yifan Hong068c5522016-10-31 14:07:25 -07001310 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1311 return generateProxyMethodSource(out, klassName, method, superInterface);
1312 });
Andreas Huber881227d2016-08-02 14:20:21 -07001313
Yifan Hong068c5522016-10-31 14:07:25 -07001314 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001315}
1316
1317status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001318 Formatter &out,
1319 const Interface *iface,
1320 const std::string &baseName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001321 const std::string klassName = "Bn" + baseName;
1322
Steven Moreland40786312016-08-16 10:29:40 -07001323 out << klassName
1324 << "::"
1325 << klassName
1326 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl)\n";
1327
1328 out.indent();
1329 out.indent();
1330
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001331 if (iface->isIBase()) {
1332 out << ": ::android::hardware::HidlInstrumentor(\"";
1333 } else {
1334 out << ": ::android::hidl::base::V1_0::BnBase(_hidl_impl, \"";
1335 }
1336
1337 out << mPackage.string()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001338 << "::I"
1339 << baseName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001340 << "\") { \n";
1341 out.indent();
1342 out << "_hidl_mImpl = _hidl_impl;\n";
1343 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001344
1345 out.unindent();
1346 out.unindent();
1347 out << "}\n\n";
1348
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001349 if (iface->isIBase()) {
1350 // BnBase has a constructor to initialize the HidlInstrumentor
1351 // class properly.
1352 out << klassName
1353 << "::"
1354 << klassName
1355 << "(const ::android::sp<I" << baseName <<"> &_hidl_impl,"
1356 << " const std::string &prefix)\n";
1357
1358 out.indent();
1359 out.indent();
1360
1361 out << ": ::android::hardware::HidlInstrumentor(prefix) { \n";
1362 out.indent();
1363 out << "_hidl_mImpl = _hidl_impl;\n";
1364 out.unindent();
1365
1366 out.unindent();
1367 out.unindent();
1368 out << "}\n\n";
1369 }
1370
1371
Andreas Huber881227d2016-08-02 14:20:21 -07001372 out << "::android::status_t " << klassName << "::onTransact(\n";
1373
1374 out.indent();
1375 out.indent();
1376
Iliyan Malchev549e2592016-08-10 08:59:12 -07001377 out << "uint32_t _hidl_code,\n"
1378 << "const ::android::hardware::Parcel &_hidl_data,\n"
1379 << "::android::hardware::Parcel *_hidl_reply,\n"
1380 << "uint32_t _hidl_flags,\n"
1381 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001382
1383 out.unindent();
1384
Iliyan Malchev549e2592016-08-10 08:59:12 -07001385 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001386 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001387 out.indent();
1388
Yifan Hong10fe0b52016-10-19 14:20:17 -07001389 for (const auto &tuple : iface->allMethodsFromRoot()) {
1390 const Method *method = tuple.method();
1391 const Interface *superInterface = tuple.interface();
1392 out << "case "
1393 << method->getSerialId()
1394 << " /* "
1395 << method->name()
1396 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001397
Yifan Hong10fe0b52016-10-19 14:20:17 -07001398 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001399
Yifan Hong10fe0b52016-10-19 14:20:17 -07001400 status_t err =
1401 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001402
Yifan Hong10fe0b52016-10-19 14:20:17 -07001403 if (err != OK) {
1404 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001405 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001406
1407 out.unindent();
1408 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001409 }
1410
1411 out << "default:\n{\n";
1412 out.indent();
1413
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001414 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001415
1416 out.indent();
1417 out.indent();
1418
Iliyan Malchev549e2592016-08-10 08:59:12 -07001419 out << "_hidl_code, _hidl_data, _hidl_reply, "
1420 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001421
1422 out.unindent();
1423 out.unindent();
1424
1425 out.unindent();
1426 out << "}\n";
1427
1428 out.unindent();
1429 out << "}\n\n";
1430
Yifan Honga018ed52016-12-13 16:35:08 -08001431 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1432 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1433 out.indent(2, [&] {
1434 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1435 out << "_hidl_reply);\n";
1436 });
1437 });
Andreas Huber881227d2016-08-02 14:20:21 -07001438
Iliyan Malchev549e2592016-08-10 08:59:12 -07001439 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001440
1441 out.unindent();
1442 out << "}\n\n";
1443
1444 return OK;
1445}
1446
1447status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001448 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001449 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1450 method->cppImpl(IMPL_STUB, out);
1451 out << "break;\n";
1452 return OK;
1453 }
1454
Yifan Hong10fe0b52016-10-19 14:20:17 -07001455 out << "if (!_hidl_data.enforceInterface(";
1456
Yifan Hongc8934042016-11-17 17:10:52 -08001457 out << iface->fqName().cppNamespace()
1458 << "::I"
1459 << iface->getBaseName();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001460
1461 out << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001462
Andreas Huber881227d2016-08-02 14:20:21 -07001463 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001464 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001465 out << "break;\n";
1466 out.unindent();
1467 out << "}\n\n";
1468
Andreas Huber5e44a292016-09-27 14:52:39 -07001469 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001470
Yifan Hongbf459bc2016-08-23 16:50:37 -07001471 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001472 for (const auto &arg : method->args()) {
1473 emitCppReaderWriter(
1474 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001475 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001476 false /* parcelObjIsPointer */,
1477 arg,
1478 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001479 Type::ErrorMode_Break,
1480 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001481 }
1482
Yifan Hongbf459bc2016-08-23 16:50:37 -07001483 // Second DFS: resolve references
1484 for (const auto &arg : method->args()) {
1485 emitCppResolveReferences(
1486 out,
1487 "_hidl_data",
1488 false /* parcelObjIsPointer */,
1489 arg,
1490 true /* reader */,
1491 Type::ErrorMode_Break,
1492 false /* addPrefixToName */);
1493 }
1494
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001495 status_t status = generateCppInstrumentationCall(
1496 out,
1497 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001498 method);
1499 if (status != OK) {
1500 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001501 }
1502
Andreas Huber881227d2016-08-02 14:20:21 -07001503 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001504 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001505
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001506 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001507 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001508 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001509 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001510 << " = "
1511 << "_hidl_mImpl->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001512 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001513
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001514 bool first = true;
1515 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001516 if (!first) {
1517 out << ", ";
1518 }
1519
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001520 if (arg->type().resultNeedsDeref()) {
1521 out << "*";
1522 }
1523
1524 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001525
1526 first = false;
1527 }
1528
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001529 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001530 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1531 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001532
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001533 elidedReturn->type().emitReaderWriter(
1534 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001535 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001536 "_hidl_reply",
1537 true, /* parcelObjIsPointer */
1538 false, /* isReader */
1539 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001540
Yifan Hongbf459bc2016-08-23 16:50:37 -07001541 emitCppResolveReferences(
1542 out,
1543 "_hidl_reply",
1544 true /* parcelObjIsPointer */,
1545 elidedReturn,
1546 false /* reader */,
1547 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001548 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001549
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001550 status_t status = generateCppInstrumentationCall(
1551 out,
1552 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001553 method);
1554 if (status != OK) {
1555 return status;
1556 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001557
Iliyan Malchev549e2592016-08-10 08:59:12 -07001558 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001559 } else {
1560 if (returnsValue) {
1561 out << "bool _hidl_callbackCalled = false;\n\n";
1562 }
Andreas Huber881227d2016-08-02 14:20:21 -07001563
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001564 out << "_hidl_mImpl->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001565
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001566 bool first = true;
1567 for (const auto &arg : method->args()) {
1568 if (!first) {
1569 out << ", ";
1570 }
Andreas Huber881227d2016-08-02 14:20:21 -07001571
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001572 if (arg->type().resultNeedsDeref()) {
1573 out << "*";
1574 }
1575
1576 out << arg->name();
1577
1578 first = false;
1579 }
1580
1581 if (returnsValue) {
1582 if (!first) {
1583 out << ", ";
1584 }
1585
1586 out << "[&](";
1587
1588 first = true;
1589 for (const auto &arg : method->results()) {
1590 if (!first) {
1591 out << ", ";
1592 }
1593
Yifan Honga47eef32016-12-12 10:38:54 -08001594 out << "const auto &_hidl_out_" << arg->name();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001595
1596 first = false;
1597 }
1598
1599 out << ") {\n";
1600 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001601 out << "if (_hidl_callbackCalled) {\n";
1602 out.indent();
1603 out << "LOG_ALWAYS_FATAL(\""
1604 << method->name()
1605 << ": _hidl_cb called a second time, but must be called once.\");\n";
1606 out.unindent();
1607 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001608 out << "_hidl_callbackCalled = true;\n\n";
1609
Yifan Hong859e53f2016-11-14 19:08:24 -08001610 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1611 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001612
Yifan Hongbf459bc2016-08-23 16:50:37 -07001613 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001614 for (const auto &arg : method->results()) {
1615 emitCppReaderWriter(
1616 out,
1617 "_hidl_reply",
1618 true /* parcelObjIsPointer */,
1619 arg,
1620 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001621 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001622 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001623 }
1624
Yifan Hongbf459bc2016-08-23 16:50:37 -07001625 // Second DFS: resolve references
1626 for (const auto &arg : method->results()) {
1627 emitCppResolveReferences(
1628 out,
1629 "_hidl_reply",
1630 true /* parcelObjIsPointer */,
1631 arg,
1632 false /* reader */,
1633 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001634 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001635 }
1636
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001637 status_t status = generateCppInstrumentationCall(
1638 out,
1639 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001640 method);
1641 if (status != OK) {
1642 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001643 }
1644
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001645 out << "_hidl_cb(*_hidl_reply);\n";
1646
1647 out.unindent();
1648 out << "}\n";
1649 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001650 out << ");\n\n";
1651
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001652 if (returnsValue) {
1653 out << "if (!_hidl_callbackCalled) {\n";
1654 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001655 out << "LOG_ALWAYS_FATAL(\""
1656 << method->name()
1657 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001658 out.unindent();
1659 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001660 } else {
1661 out << "::android::hardware::writeToParcel("
1662 << "::android::hardware::Status::ok(), "
1663 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001664 }
Andreas Huber881227d2016-08-02 14:20:21 -07001665 }
1666
1667 out << "break;\n";
1668
1669 return OK;
1670}
1671
Steven Moreland69e7c702016-09-09 11:16:32 -07001672status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1673 std::string ifaceName;
1674 if (!AST::isInterface(&ifaceName)) {
1675 // types.hal does not get a stub header.
1676 return OK;
1677 }
1678
1679 const Interface *iface = mRootScope->getInterface();
1680
1681 const std::string baseName = iface->getBaseName();
1682 const std::string klassName = "Bs" + baseName;
1683
1684 bool supportOneway = iface->hasOnewayMethods();
1685
1686 std::string path = outputPath;
1687 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1688 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1689 path.append(klassName);
1690 path.append(".h");
1691
1692 CHECK(Coordinator::MakeParentHierarchy(path));
1693 FILE *file = fopen(path.c_str(), "w");
1694
1695 if (file == NULL) {
1696 return -errno;
1697 }
1698
1699 Formatter out(file);
1700
1701 const std::string guard = makeHeaderGuard(klassName);
1702
1703 out << "#ifndef " << guard << "\n";
1704 out << "#define " << guard << "\n\n";
1705
1706 std::vector<std::string> packageComponents;
1707 getPackageAndVersionComponents(
1708 &packageComponents, false /* cpp_compatible */);
1709
Yifan Hongb0949432016-12-15 15:32:24 -08001710 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001711 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001712
1713 generateCppPackageInclude(out, mPackage, ifaceName);
1714 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001715
Yifan Hong7a118f52016-12-07 11:21:15 -08001716 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001717 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001718 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001719 }
1720
1721 enterLeaveNamespace(out, true /* enter */);
1722 out << "\n";
1723
1724 out << "struct "
1725 << klassName
1726 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001727 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001728
1729 out.indent();
1730 out << "explicit "
1731 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001732 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001733 << ifaceName
1734 << "> impl);\n";
1735
Yifan Hong068c5522016-10-31 14:07:25 -07001736 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1737 return generatePassthroughMethod(out, method);
1738 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001739
1740 if (err != OK) {
1741 return err;
1742 }
1743
1744 out.unindent();
1745 out << "private:\n";
1746 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001747 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001748
1749 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001750 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001751
1752 out << "\n";
1753
1754 out << "::android::hardware::Return<void> addOnewayTask("
1755 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001756 }
1757
1758 out.unindent();
1759
1760 out << "};\n\n";
1761
1762 enterLeaveNamespace(out, false /* enter */);
1763
1764 out << "\n#endif // " << guard << "\n";
1765
1766 return OK;
1767}
1768
Yifan Hongfe95aa22016-10-19 17:26:45 -07001769status_t AST::generateInterfaceSource(Formatter &out) const {
1770 const Interface *iface = mRootScope->getInterface();
1771
Yifan Hong2d7126b2016-10-20 15:12:57 -07001772 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001773 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001774
Yifan Hong3d746092016-12-07 14:26:33 -08001775 for (const Interface *superType : iface->typeChain()) {
1776 out << "// static \n"
1777 << childTypeResult
1778 << " I"
1779 << iface->getBaseName()
1780 << "::castFrom("
1781 << superType->getCppArgumentType()
1782 << " parent) {\n";
1783 out.indent();
1784 if (iface == superType) {
1785 out << "return parent;\n";
1786 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001787 out << "return ::android::hardware::castInterface<";
1788 out << "I" << iface->getBaseName() << ", "
1789 << superType->fqName().cppName() << ", "
Martijn Coenena63e0ad2016-12-07 17:29:00 +01001790 << iface->getProxyName().cppLocalName() << ", "
1791 << superType->getProxyName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001792 << ">(\n";
1793 out.indent();
1794 out.indent();
1795 out << "parent, \""
1796 << iface->fqName().string()
1797 << "\");\n";
1798 out.unindent();
1799 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001800 }
Yifan Hong3d746092016-12-07 14:26:33 -08001801 out.unindent();
1802 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001803 }
1804
1805 return OK;
1806}
1807
Steven Moreland69e7c702016-09-09 11:16:32 -07001808status_t AST::generatePassthroughSource(Formatter &out) const {
1809 const Interface *iface = mRootScope->getInterface();
1810
1811 const std::string baseName = iface->getBaseName();
1812 const std::string klassName = "Bs" + baseName;
1813
1814 out << klassName
1815 << "::"
1816 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001817 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001818 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001819 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001820 << iface->fqName().string()
1821 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001822 if (iface->hasOnewayMethods()) {
1823 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001824 out.indent([&] {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001825 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1826 });
1827 }
1828 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001829
1830 if (iface->hasOnewayMethods()) {
1831 out << "::android::hardware::Return<void> "
1832 << klassName
1833 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1834 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001835 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001836 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001837 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1838 out.indent();
1839 out.indent();
1840 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1841 out.unindent();
1842 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001843 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001844 out << "}\n";
1845
Steven Morelandd366c262016-10-11 15:29:10 -07001846 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001847
1848 out.unindent();
1849 out << "}\n\n";
1850
1851
1852 }
1853
1854 return OK;
1855}
1856
Martijn Coenen7b295242016-11-04 16:52:56 +01001857status_t AST::generateCppAtraceCall(Formatter &out,
1858 InstrumentationEvent event,
1859 const Method *method) const {
1860 const Interface *iface = mRootScope->getInterface();
1861 std::string baseString = "HIDL::I" + iface->getBaseName() + "::" + method->name();
1862 switch (event) {
1863 case SERVER_API_ENTRY:
1864 {
1865 out << "atrace_begin(ATRACE_TAG_HAL, \""
1866 << baseString + "::server\");\n";
1867 break;
1868 }
1869 case CLIENT_API_ENTRY:
1870 {
1871 out << "atrace_begin(ATRACE_TAG_HAL, \""
1872 << baseString + "::client\");\n";
1873 break;
1874 }
1875 case PASSTHROUGH_ENTRY:
1876 {
1877 out << "atrace_begin(ATRACE_TAG_HAL, \""
1878 << baseString + "::passthrough\");\n";
1879 break;
1880 }
1881 case SERVER_API_EXIT:
1882 case CLIENT_API_EXIT:
1883 case PASSTHROUGH_EXIT:
1884 {
1885 out << "atrace_end(ATRACE_TAG_HAL);\n";
1886 break;
1887 }
1888 default:
1889 {
1890 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1891 return UNKNOWN_ERROR;
1892 }
1893 }
1894
1895 return OK;
1896}
1897
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001898status_t AST::generateCppInstrumentationCall(
1899 Formatter &out,
1900 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001901 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001902 status_t err = generateCppAtraceCall(out, event, method);
1903 if (err != OK) {
1904 return err;
1905 }
1906
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001907 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1908 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001909 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001910 std::string event_str = "";
1911 switch (event) {
1912 case SERVER_API_ENTRY:
1913 {
1914 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1915 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001916 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001917 << (arg->type().resultNeedsDeref() ? "" : "&")
1918 << arg->name()
1919 << ");\n";
1920 }
1921 break;
1922 }
1923 case SERVER_API_EXIT:
1924 {
1925 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001926 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001927 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001928 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001929 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001930 }
1931 break;
1932 }
1933 case CLIENT_API_ENTRY:
1934 {
1935 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1936 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001937 out << "_hidl_args.push_back((void *)&"
1938 << arg->name()
1939 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001940 }
1941 break;
1942 }
1943 case CLIENT_API_EXIT:
1944 {
1945 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1946 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001947 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001948 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001949 << "_hidl_out_"
1950 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001951 << ");\n";
1952 }
1953 break;
1954 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001955 case PASSTHROUGH_ENTRY:
1956 {
1957 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1958 for (const auto &arg : method->args()) {
1959 out << "_hidl_args.push_back((void *)&"
1960 << arg->name()
1961 << ");\n";
1962 }
1963 break;
1964 }
1965 case PASSTHROUGH_EXIT:
1966 {
1967 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001968 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001969 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001970 << arg->name()
1971 << ");\n";
1972 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001973 break;
1974 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001975 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001976 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001977 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001978 return UNKNOWN_ERROR;
1979 }
1980 }
1981
Steven Moreland031ccf12016-10-31 15:54:38 -07001982 const Interface *iface = mRootScope->getInterface();
1983
Steven Moreland1ab31442016-11-03 18:37:51 -07001984 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001985 out.indent();
1986 out << "callback("
1987 << event_str
1988 << ", \""
1989 << mPackage.package()
1990 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07001991 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001992 << "\", \""
1993 << iface->localName()
1994 << "\", \""
1995 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001996 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001997 out.unindent();
1998 out << "}\n";
1999 out.unindent();
2000 out << "}\n\n";
2001
2002 return OK;
2003}
2004
Andreas Huber881227d2016-08-02 14:20:21 -07002005} // namespace android
2006