blob: 7529460ab5fcb56143923af550df14099a823e37 [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Huber881227d2016-08-02 14:20:21 -070017#include "AST.h"
18
19#include "Coordinator.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070020#include "EnumType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070021#include "Interface.h"
22#include "Method.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070023#include "ScalarType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070024#include "Scope.h"
25
Andreas Huberdca261f2016-08-04 13:47:51 -070026#include <algorithm>
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070027#include <hidl-util/Formatter.h>
Steven Moreland5708edf2016-11-04 15:33:31 +000028#include <hidl-util/StringHelper.h>
Andreas Huber881227d2016-08-02 14:20:21 -070029#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070030#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070031#include <vector>
32
33namespace android {
34
Andreas Huberb82318c2016-08-02 14:45:54 -070035status_t AST::generateCpp(const std::string &outputPath) const {
36 status_t err = generateInterfaceHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070037
38 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070039 err = generateStubHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070040 }
41
42 if (err == OK) {
Steven Moreland40786312016-08-16 10:29:40 -070043 err = generateHwBinderHeader(outputPath);
44 }
45
46 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070047 err = generateProxyHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070048 }
49
50 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070051 err = generateAllSource(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070052 }
53
Steven Moreland69e7c702016-09-09 11:16:32 -070054 if (err == OK) {
Yifan Hong7a118f52016-12-07 11:21:15 -080055 err = generatePassthroughHeader(outputPath);
Steven Moreland69e7c702016-09-09 11:16:32 -070056 }
57
Andreas Huber881227d2016-08-02 14:20:21 -070058 return err;
59}
60
Andreas Huber737080b2016-08-02 15:38:04 -070061void AST::getPackageComponents(
62 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070063 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070064}
65
66void AST::getPackageAndVersionComponents(
67 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070068 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070069}
70
Steven Moreland5708edf2016-11-04 15:33:31 +000071std::string AST::makeHeaderGuard(const std::string &baseName,
72 bool indicateGenerated) const {
73 std::string guard;
Andreas Huber881227d2016-08-02 14:20:21 -070074
Steven Moreland5708edf2016-11-04 15:33:31 +000075 if (indicateGenerated) {
76 guard += "HIDL_GENERATED_";
77 }
78
79 guard += StringHelper::Uppercase(mPackage.tokenName());
Andreas Huber881227d2016-08-02 14:20:21 -070080 guard += "_";
Steven Moreland5708edf2016-11-04 15:33:31 +000081 guard += StringHelper::Uppercase(baseName);
82 guard += "_H";
Andreas Huber881227d2016-08-02 14:20:21 -070083
84 return guard;
85}
86
Steven Morelandee88eed2016-10-31 17:49:00 -070087// static
88void AST::generateCppPackageInclude(
89 Formatter &out,
90 const FQName &package,
91 const std::string &klass) {
92
93 out << "#include <";
94
95 std::vector<std::string> components;
96 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
97
98 for (const auto &component : components) {
99 out << component << "/";
100 }
101
102 out << klass
103 << ".h>\n";
104}
105
Andreas Huber881227d2016-08-02 14:20:21 -0700106void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
107 std::vector<std::string> packageComponents;
108 getPackageAndVersionComponents(
109 &packageComponents, true /* cpp_compatible */);
110
111 if (enter) {
112 for (const auto &component : packageComponents) {
113 out << "namespace " << component << " {\n";
114 }
Andreas Huber0e00de42016-08-03 09:56:02 -0700115
Andreas Huber2831d512016-08-15 09:33:47 -0700116 out.setNamespace(mPackage.cppNamespace() + "::");
Andreas Huber881227d2016-08-02 14:20:21 -0700117 } else {
Andreas Huber0e00de42016-08-03 09:56:02 -0700118 out.setNamespace(std::string());
119
Andreas Huber881227d2016-08-02 14:20:21 -0700120 for (auto it = packageComponents.rbegin();
121 it != packageComponents.rend();
122 ++it) {
123 out << "} // namespace " << *it << "\n";
124 }
125 }
126}
127
Yifan Hongeefe4f22017-01-04 15:32:42 -0800128static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
129 out << "static ::android::sp<" << interfaceName << "> getService("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800130 << "const std::string &serviceName=\"default\", bool getStub=false);\n";
131 out << "static ::android::sp<" << interfaceName << "> getService("
132 << "const char serviceName[], bool getStub=false)"
133 << " { std::string str(serviceName ? serviceName : \"\");"
134 << " return getService(str, getStub); }\n";
135 out << "static ::android::sp<" << interfaceName << "> getService("
136 << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
137 // without c_str the std::string constructor is ambiguous
138 << " { std::string str(serviceName.c_str());"
139 << " return getService(str, getStub); }\n";
140 out << "static ::android::sp<" << interfaceName << "> getService("
141 << "bool getStub) { return getService(\"default\", getStub); }\n";
142 out << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800143 out << "static bool registerForNotifications(\n";
144 out.indent(2, [&] {
145 out << "const std::string &serviceName,\n"
146 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
147 << "&notification);\n";
148 });
149
150}
151
152static void implementServiceManagerInteractions(Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -0800153 const FQName &fqName, const std::string &package) {
154
155 const std::string interfaceName = fqName.getInterfaceName();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800156
157 out << "// static\n"
Yifan Hongeefe4f22017-01-04 15:32:42 -0800158 << "::android::sp<" << interfaceName << "> " << interfaceName << "::getService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800159 << "const std::string &serviceName, bool getStub) ";
160 out.block([&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000161 out << "::android::sp<" << interfaceName << "> iface = nullptr;\n";
Yifan Hongd3b58ed2017-01-30 14:13:10 -0800162 out << "::android::vintf::Transport transport = ::android::hardware::getTransport("
Yifan Hong152866b2017-02-28 15:34:27 -0800163 << interfaceName << "::descriptor, serviceName);\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000164
165 out.sIf("!getStub && "
166 "(transport == ::android::vintf::Transport::HWBINDER || "
Steven Moreland15835172017-01-30 16:21:42 -0800167 "transport == ::android::vintf::Transport::TOGGLED || "
Steven Morelandf10af872017-01-25 16:01:56 +0000168 "transport == ::android::vintf::Transport::EMPTY)", [&] {
169 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800170 out.indent(2, [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000171 out << "= ::android::hardware::defaultServiceManager();\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800172 });
Steven Morelandf10af872017-01-25 16:01:56 +0000173 out.sIf("sm != nullptr", [&] {
Steven Morelandbec74ed2017-01-25 17:42:35 -0800174 // TODO(b/34274385) remove sysprop check
Steven Moreland15835172017-01-30 16:21:42 -0800175 out.sIf("transport == ::android::vintf::Transport::HWBINDER ||"
176 "(transport == ::android::vintf::Transport::TOGGLED &&"
177 " ::android::hardware::details::blockingHalBinderizationEnabled())", [&]() {
Steven Moreland6d7b91c2017-01-24 18:58:07 -0800178 out << "::android::hardware::details::waitForHwService("
179 << interfaceName << "::descriptor" << ", serviceName);\n";
180 }).endl();
Steven Morelandf10af872017-01-25 16:01:56 +0000181 out << "::android::hardware::Return<::android::sp<" << gIBaseFqName.cppName() << ">> ret = \n";
182 out.indent(2, [&] {
183 out << "sm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
184 });
185 out.sIf("ret.isOk()", [&] {
186 out << "iface = " << interfaceName << "::castFrom(ret);\n";
187 out.sIf("iface != nullptr", [&] {
188 out << "return iface;\n";
189 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800190 }).endl();
191 }).endl();
192 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800193
Steven Morelandf10af872017-01-25 16:01:56 +0000194 out.sIf("getStub || "
195 "transport == ::android::vintf::Transport::PASSTHROUGH || "
Steven Moreland15835172017-01-30 16:21:42 -0800196 "(transport == ::android::vintf::Transport::TOGGLED &&"
Steven Morelandbec74ed2017-01-25 17:42:35 -0800197 " !::android::hardware::details::blockingHalBinderizationEnabled()) ||"
Steven Morelandf10af872017-01-25 16:01:56 +0000198 "transport == ::android::vintf::Transport::EMPTY", [&] {
199 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> pm\n";
Steven Morelande3fa5da2017-01-25 07:07:53 +0000200 out.indent(2, [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000201 out << "= ::android::hardware::getPassthroughServiceManager();\n";
Steven Morelande3fa5da2017-01-25 07:07:53 +0000202 });
Steven Morelandf10af872017-01-25 16:01:56 +0000203
204 out.sIf("pm != nullptr", [&] () {
205 out << "::android::hardware::Return<::android::sp<" << gIBaseFqName.cppName() << ">> ret = \n";
206 out.indent(2, [&] {
207 out << "pm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
Steven Moreland2c2dea82017-01-18 17:24:17 -0800208 });
Steven Morelandf10af872017-01-25 16:01:56 +0000209 out.sIf("ret.isOk()", [&] {
210 out << "::android::sp<" << gIBaseFqName.cppName()
211 << "> baseInterface = ret;\n";
212 out.sIf("baseInterface != nullptr", [&]() {
213 out << "iface = new " << fqName.getInterfacePassthroughName()
214 << "(" << interfaceName << "::castFrom(baseInterface));\n";
215 });
216 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800217 }).endl();
218 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800219
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800220 out << "return iface;\n";
221 }).endl().endl();
222
Yifan Hongeefe4f22017-01-04 15:32:42 -0800223 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800224 << "const std::string &serviceName) ";
225 out.block([&] {
226 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
227 out.indent(2, [&] {
228 out << "= ::android::hardware::defaultServiceManager();\n";
229 });
230 out.sIf("sm == nullptr", [&] {
231 out << "return ::android::INVALID_OPERATION;\n";
232 }).endl();
Martijn Coenenbc9f5c92017-03-06 13:04:05 +0100233 out << "::android::hardware::Return<bool> ret = "
234 << "sm->add(serviceName.c_str(), this);\n"
235 << "return ret.isOk() && ret ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800236 }).endl().endl();
237
Yifan Hongeefe4f22017-01-04 15:32:42 -0800238 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800239 out.indent(2, [&] {
240 out << "const std::string &serviceName,\n"
241 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
242 << "&notification) ";
243 });
244 out.block([&] {
245 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
246 out.indent(2, [&] {
247 out << "= ::android::hardware::defaultServiceManager();\n";
248 });
249 out.sIf("sm == nullptr", [&] {
250 out << "return false;\n";
251 }).endl();
252 out << "::android::hardware::Return<bool> success =\n";
253 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800254 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800255 out.indent(2, [&] {
256 out << "serviceName, notification);\n";
257 });
258 });
259 out << "return success.isOk() && success;\n";
260 }).endl().endl();
261}
262
Andreas Huberb82318c2016-08-02 14:45:54 -0700263status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700264
Andreas Huberb82318c2016-08-02 14:45:54 -0700265 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700266 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700267 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700268
269 std::string ifaceName;
270 bool isInterface = true;
271 if (!AST::isInterface(&ifaceName)) {
272 ifaceName = "types";
273 isInterface = false;
274 }
275 path.append(ifaceName);
276 path.append(".h");
277
Andreas Huberd2943e12016-08-05 11:59:31 -0700278 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700279 FILE *file = fopen(path.c_str(), "w");
280
281 if (file == NULL) {
282 return -errno;
283 }
284
285 Formatter out(file);
286
287 const std::string guard = makeHeaderGuard(ifaceName);
288
289 out << "#ifndef " << guard << "\n";
290 out << "#define " << guard << "\n\n";
291
Andreas Huber737080b2016-08-02 15:38:04 -0700292 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700293 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700294 }
295
296 if (!mImportedNames.empty()) {
297 out << "\n";
298 }
299
Steven Moreland0693f312016-11-09 15:06:14 -0800300 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800301 if (isIBase()) {
302 out << "// skipped #include IServiceNotification.h\n\n";
303 } else {
304 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
305 }
Steven Moreland0693f312016-11-09 15:06:14 -0800306 }
307
Yifan Hongc8934042016-11-17 17:10:52 -0800308 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700309 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700310
311 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200312 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700313 }
314
Martijn Coenenaf712c02016-11-16 15:26:27 +0100315 out << "#include <utils/NativeHandle.h>\n";
316 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700317
318 enterLeaveNamespace(out, true /* enter */);
319 out << "\n";
320
321 if (isInterface) {
322 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700323 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700324
325 const Interface *iface = mRootScope->getInterface();
326 const Interface *superType = iface->superType();
327
Steven Moreland40786312016-08-16 10:29:40 -0700328 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800329 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700330 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000331 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700332 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700333 }
334
335 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700336
337 out.indent();
338
Andreas Huber881227d2016-08-02 14:20:21 -0700339 }
340
341 status_t err = emitTypeDeclarations(out);
342
343 if (err != OK) {
344 return err;
345 }
346
347 if (isInterface) {
348 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800349
Yifan Hongc8934042016-11-17 17:10:52 -0800350 out << "virtual bool isRemote() const ";
351 if (!isIBase()) {
352 out << "override ";
353 }
354 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800355
Andreas Huber881227d2016-08-02 14:20:21 -0700356 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700357 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700358
Andreas Huber881227d2016-08-02 14:20:21 -0700359 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800360 const TypedVar *elidedReturn = method->canElideCallback();
361
362 if (elidedReturn == nullptr && returnsValue) {
363 out << "using "
364 << method->name()
365 << "_cb = std::function<void("
366 << Method::GetArgSignature(method->results(),
367 true /* specify namespaces */)
368 << ")>;\n";
369 }
Andreas Huber881227d2016-08-02 14:20:21 -0700370
Andreas Huber3599d922016-08-09 10:42:57 -0700371 method->dumpAnnotations(out);
372
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700373 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700374 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700375 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700376 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700377 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700378 }
379
380 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700381 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700382 << Method::GetArgSignature(method->args(),
383 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700384
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700385 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700386 if (!method->args().empty()) {
387 out << ", ";
388 }
389
Steven Moreland67f67b42016-09-29 08:59:02 -0700390 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700391 }
392
Yifan Hong10fe0b52016-10-19 14:20:17 -0700393 out << ")";
394 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800395 if (!isIBase()) {
396 out << " override";
397 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700398 out << " {\n";
399 out.indent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100400 method->cppImpl(IMPL_HEADER, out);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700401 out.unindent();
402 out << "\n}\n";
403 } else {
404 out << " = 0;\n";
405 }
Andreas Huber881227d2016-08-02 14:20:21 -0700406 }
Steven Moreland40786312016-08-16 10:29:40 -0700407
Yifan Hong3d746092016-12-07 14:26:33 -0800408 out << "// cast static functions\n";
409 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700410
Yifan Hong3d746092016-12-07 14:26:33 -0800411 for (const Interface *superType : iface->typeChain()) {
412 out << "static "
413 << childTypeResult
414 << " castFrom("
415 << superType->getCppArgumentType()
416 << " parent"
417 << ");\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700418 }
419
Steven Morelandd39133b2016-11-11 12:30:08 -0800420 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700421
Yifan Hongc8934042016-11-17 17:10:52 -0800422 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800423 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800424 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800425 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800426 }
Andreas Huber881227d2016-08-02 14:20:21 -0700427 }
428
429 if (isInterface) {
430 out.unindent();
431
Andreas Hubere3f769a2016-10-10 10:54:44 -0700432 out << "};\n\n";
433 }
434
435 err = mRootScope->emitGlobalTypeDeclarations(out);
436
437 if (err != OK) {
438 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700439 }
440
441 out << "\n";
442 enterLeaveNamespace(out, false /* enter */);
443
444 out << "\n#endif // " << guard << "\n";
445
446 return OK;
447}
448
Steven Moreland40786312016-08-16 10:29:40 -0700449status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
450 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800451 bool isInterface = AST::isInterface(&ifaceName);
452 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800453 std::string klassName{};
454
455 if(isInterface) {
456 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800457 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800458 } else {
459 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700460 }
461
Steven Moreland40786312016-08-16 10:29:40 -0700462 std::string path = outputPath;
463 path.append(mCoordinator->convertPackageRootToPath(mPackage));
464 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
465 path.append(klassName + ".h");
466
Yifan Hong244e82d2016-11-11 11:13:57 -0800467 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700468
469 if (file == NULL) {
470 return -errno;
471 }
472
473 Formatter out(file);
474
475 const std::string guard = makeHeaderGuard(klassName);
476
477 out << "#ifndef " << guard << "\n";
478 out << "#define " << guard << "\n\n";
479
Yifan Hong244e82d2016-11-11 11:13:57 -0800480 if (isInterface) {
481 generateCppPackageInclude(out, mPackage, ifaceName);
482 } else {
483 generateCppPackageInclude(out, mPackage, "types");
484 }
Steven Moreland40786312016-08-16 10:29:40 -0700485
Steven Morelandee88eed2016-10-31 17:49:00 -0700486 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700487
488 for (const auto &item : mImportedNames) {
489 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800490 generateCppPackageInclude(out, item, "hwtypes");
491 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800492 generateCppPackageInclude(out, item, item.getInterfaceStubName());
493 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700494 }
Steven Moreland40786312016-08-16 10:29:40 -0700495 }
496
497 out << "\n";
498
Martijn Coenen93915102016-09-01 01:35:52 +0200499 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700500 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100501 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700502
503 out << "\n";
504
505 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700506
Yifan Hong244e82d2016-11-11 11:13:57 -0800507 status_t err = mRootScope->emitGlobalHwDeclarations(out);
508 if (err != OK) {
509 return err;
510 }
Steven Moreland40786312016-08-16 10:29:40 -0700511
512 enterLeaveNamespace(out, false /* enter */);
513
514 out << "\n#endif // " << guard << "\n";
515
516 return OK;
517}
518
Andreas Huber881227d2016-08-02 14:20:21 -0700519status_t AST::emitTypeDeclarations(Formatter &out) const {
520 return mRootScope->emitTypeDeclarations(out);
521}
522
Yifan Hong7a118f52016-12-07 11:21:15 -0800523static void wrapPassthroughArg(Formatter &out,
524 const TypedVar *arg, bool addPrefixToName,
525 std::function<void(void)> handleError) {
526 if (!arg->type().isInterface()) {
527 return;
528 }
529 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
530 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
531 + arg->name();
532 const Interface &iface = static_cast<const Interface &>(arg->type());
533 out << iface.getCppStackType() << " " << wrappedName << ";\n";
534 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
535 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
536 out << wrappedName
537 << " = "
538 << iface.fqName().cppName()
Yifan Hong052425a2017-03-13 17:06:13 -0700539 << "::castFrom(::android::hardware::details::wrapPassthrough("
Yifan Hong7a118f52016-12-07 11:21:15 -0800540 << name << "));\n";
541 out.sIf(wrappedName + " == nullptr", [&] {
542 // Fatal error. Happens when the BsFoo class is not found in the binary
543 // or any dynamic libraries.
544 handleError();
545 }).endl();
546 }).sElse([&] {
547 out << wrappedName << " = " << name << ";\n";
548 }).endl().endl();
549}
550
Steven Moreland69e7c702016-09-09 11:16:32 -0700551status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700552 const Method *method) const {
553 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700554
555 out << " {\n";
556 out.indent();
557
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800558 if (method->isHidlReserved()
559 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
560 method->cppImpl(IMPL_PASSTHROUGH, out);
561 out.unindent();
562 out << "}\n\n";
563 return OK;
564 }
565
Steven Moreland69e7c702016-09-09 11:16:32 -0700566 const bool returnsValue = !method->results().empty();
567 const TypedVar *elidedReturn = method->canElideCallback();
568
Steven Moreland67f67b42016-09-29 08:59:02 -0700569 if (returnsValue && elidedReturn == nullptr) {
570 generateCheckNonNull(out, "_hidl_cb");
571 }
572
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700573 generateCppInstrumentationCall(
574 out,
575 InstrumentationEvent::PASSTHROUGH_ENTRY,
576 method);
577
Yifan Hong7a118f52016-12-07 11:21:15 -0800578
579 for (const auto &arg : method->args()) {
580 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
581 out << "return ::android::hardware::Status::fromExceptionCode(\n";
582 out.indent(2, [&] {
583 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800584 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800585 });
586 });
587 }
588
589 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700590 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700591
592 if (method->isOneway()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800593 out << "addOnewayTask([this, &_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700594 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800595 out << ", "
596 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
597 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700598 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700599 out << "] {\n";
600 out.indent();
601 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700602 }
603
604 out << "mImpl->"
605 << method->name()
606 << "(";
607
608 bool first = true;
609 for (const auto &arg : method->args()) {
610 if (!first) {
611 out << ", ";
612 }
613 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800614 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700615 }
616 if (returnsValue && elidedReturn == nullptr) {
617 if (!method->args().empty()) {
618 out << ", ";
619 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800620 out << "[&](";
621 first = true;
622 for (const auto &arg : method->results()) {
623 if (!first) {
624 out << ", ";
625 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700626
Yifan Hong7a118f52016-12-07 11:21:15 -0800627 out << "const auto &_hidl_out_"
628 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800629
630 first = false;
631 }
632
633 out << ") {\n";
634 out.indent();
635 status_t status = generateCppInstrumentationCall(
636 out,
637 InstrumentationEvent::PASSTHROUGH_EXIT,
638 method);
639 if (status != OK) {
640 return status;
641 }
642
Yifan Hong7a118f52016-12-07 11:21:15 -0800643 for (const auto &arg : method->results()) {
644 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
645 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
646 out.indent(2, [&] {
647 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800648 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800649 });
650 out << "return;\n";
651 });
652 }
653
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800654 out << "_hidl_cb(";
655 first = true;
656 for (const auto &arg : method->results()) {
657 if (!first) {
658 out << ", ";
659 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800660 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800661 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
662 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800663 }
664 out << ");\n";
665 out.unindent();
666 out << "});\n\n";
667 } else {
668 out << ");\n\n";
669 if (elidedReturn != nullptr) {
670 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800671 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800672 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000673 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800674 }
675 status_t status = generateCppInstrumentationCall(
676 out,
677 InstrumentationEvent::PASSTHROUGH_EXIT,
678 method);
679 if (status != OK) {
680 return status;
681 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700682 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700683
684 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700685 out.unindent();
686 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700687 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700688
689 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700690
691 out.unindent();
692 out << "}\n";
693
694 return OK;
695}
696
Yifan Hong068c5522016-10-31 14:07:25 -0700697status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700698
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700699 const Interface *iface = mRootScope->getInterface();
700
Yifan Hong10fe0b52016-10-19 14:20:17 -0700701 const Interface *prevIterface = nullptr;
702 for (const auto &tuple : iface->allMethodsFromRoot()) {
703 const Method *method = tuple.method();
704 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700705
Yifan Hong10fe0b52016-10-19 14:20:17 -0700706 if(prevIterface != superInterface) {
707 if (prevIterface != nullptr) {
708 out << "\n";
709 }
710 out << "// Methods from "
711 << superInterface->fullName()
712 << " follow.\n";
713 prevIterface = superInterface;
714 }
Yifan Hong068c5522016-10-31 14:07:25 -0700715 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700716
Yifan Hong10fe0b52016-10-19 14:20:17 -0700717 if (err != OK) {
718 return err;
719 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700720 }
721
Yifan Hong10fe0b52016-10-19 14:20:17 -0700722 out << "\n";
723
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700724 return OK;
725}
726
Andreas Huberb82318c2016-08-02 14:45:54 -0700727status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700728 std::string ifaceName;
729 if (!AST::isInterface(&ifaceName)) {
730 // types.hal does not get a stub header.
731 return OK;
732 }
733
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700734 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800735 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700736
Andreas Huberb82318c2016-08-02 14:45:54 -0700737 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700738 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700739 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700740 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700741 path.append(".h");
742
Andreas Huberd2943e12016-08-05 11:59:31 -0700743 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700744 FILE *file = fopen(path.c_str(), "w");
745
746 if (file == NULL) {
747 return -errno;
748 }
749
750 Formatter out(file);
751
Steven Moreland40786312016-08-16 10:29:40 -0700752 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700753
754 out << "#ifndef " << guard << "\n";
755 out << "#define " << guard << "\n\n";
756
Yifan Hongeefe4f22017-01-04 15:32:42 -0800757 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700758 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700759
760 enterLeaveNamespace(out, true /* enter */);
761 out << "\n";
762
763 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800764 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100765 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800766 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000767 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100768 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800769 out << " : public "
770 << gIBaseFqName.getInterfaceStubFqName().cppName()
771 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100772 }
Andreas Huber881227d2016-08-02 14:20:21 -0700773
774 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800775 out << "explicit "
776 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700777 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100778 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800779 out << "explicit "
780 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100781 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800782 << " const std::string& HidlInstrumentor_package,"
783 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700784 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700785 out << "::android::status_t onTransact(\n";
786 out.indent();
787 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700788 out << "uint32_t _hidl_code,\n";
789 out << "const ::android::hardware::Parcel &_hidl_data,\n";
790 out << "::android::hardware::Parcel *_hidl_reply,\n";
791 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700792 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700793 out.unindent();
794 out.unindent();
795
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100796 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
797 out.unindent();
798 out << "private:\n";
799 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800800
801 status_t err = generateMethods(out, [&](const Method *method, const Interface *iface) {
802 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
803 return OK;
804 }
805 const bool returnsValue = !method->results().empty();
806 const TypedVar *elidedReturn = method->canElideCallback();
807
808 if (elidedReturn == nullptr && returnsValue) {
809 out << "using " << method->name() << "_cb = "
810 << iface->fqName().cppName()
811 << "::" << method->name() << "_cb;\n";
812 }
813 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800814 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800815 return OK;
816 });
817 if (err != OK) {
818 return err;
819 }
820
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100821 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700822 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700823 out << "};\n\n";
824
825 enterLeaveNamespace(out, false /* enter */);
826
827 out << "\n#endif // " << guard << "\n";
828
829 return OK;
830}
831
Andreas Huberb82318c2016-08-02 14:45:54 -0700832status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700833 std::string ifaceName;
834 if (!AST::isInterface(&ifaceName)) {
835 // types.hal does not get a proxy header.
836 return OK;
837 }
838
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700839 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800840 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700841
Andreas Huberb82318c2016-08-02 14:45:54 -0700842 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700843 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700844 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800845 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700846 path.append(".h");
847
Andreas Huberd2943e12016-08-05 11:59:31 -0700848 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700849 FILE *file = fopen(path.c_str(), "w");
850
851 if (file == NULL) {
852 return -errno;
853 }
854
855 Formatter out(file);
856
Yifan Hongeefe4f22017-01-04 15:32:42 -0800857 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700858
859 out << "#ifndef " << guard << "\n";
860 out << "#define " << guard << "\n\n";
861
Martijn Coenen115d4282016-12-19 05:14:04 +0100862 out << "#include <hidl/HidlTransportSupport.h>\n\n";
863
Andreas Huber881227d2016-08-02 14:20:21 -0700864 std::vector<std::string> packageComponents;
865 getPackageAndVersionComponents(
866 &packageComponents, false /* cpp_compatible */);
867
Yifan Hongeefe4f22017-01-04 15:32:42 -0800868 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700869 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700870
871 enterLeaveNamespace(out, true /* enter */);
872 out << "\n";
873
874 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800875 << proxyName
876 << " : public ::android::hardware::BpInterface<"
877 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000878 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700879
880 out.indent();
881
Yifan Hongeefe4f22017-01-04 15:32:42 -0800882 out << "explicit "
883 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700884 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700885 << "\n\n";
886
Yifan Hong10fe0b52016-10-19 14:20:17 -0700887 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700888
Yifan Hong068c5522016-10-31 14:07:25 -0700889 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
890 method->generateCppSignature(out);
891 out << " override;\n";
892 return OK;
893 });
Steven Moreland9c387612016-09-07 09:54:26 -0700894
895 if (err != OK) {
896 return err;
897 }
Andreas Huber881227d2016-08-02 14:20:21 -0700898
899 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100900 out << "private:\n";
901 out.indent();
902 out << "std::mutex _hidl_mMutex;\n"
903 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
904 << " _hidl_mDeathRecipients;\n";
905 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700906 out << "};\n\n";
907
908 enterLeaveNamespace(out, false /* enter */);
909
910 out << "\n#endif // " << guard << "\n";
911
912 return OK;
913}
914
Andreas Huberb82318c2016-08-02 14:45:54 -0700915status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700916
Andreas Huberb82318c2016-08-02 14:45:54 -0700917 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700918 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700919 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700920
921 std::string ifaceName;
922 std::string baseName;
923
Yifan Hongfe95aa22016-10-19 17:26:45 -0700924 const Interface *iface = nullptr;
925 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700926 if (!AST::isInterface(&ifaceName)) {
927 baseName = "types";
928 isInterface = false;
929 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700930 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700931 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700932 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700933 }
934
935 path.append(baseName);
936
937 if (baseName != "types") {
938 path.append("All");
939 }
940
941 path.append(".cpp");
942
Andreas Huberd2943e12016-08-05 11:59:31 -0700943 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700944 FILE *file = fopen(path.c_str(), "w");
945
946 if (file == NULL) {
947 return -errno;
948 }
949
950 Formatter out(file);
951
Steven Moreland623c0042017-01-13 14:42:29 -0800952 out << "#define LOG_TAG \""
953 << mPackage.string() << "::" << baseName
954 << "\"\n\n";
955
Steven Moreland05cd4232016-11-21 16:01:12 -0800956 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100957 out << "#include <cutils/trace.h>\n";
958 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700959 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700960 // This is a no-op for IServiceManager itself.
961 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
962
Steven Morelandbec74ed2017-01-25 17:42:35 -0800963 // TODO(b/34274385) remove this
964 out << "#include <hidl/LegacySupport.h>\n";
965
Yifan Hongeefe4f22017-01-04 15:32:42 -0800966 generateCppPackageInclude(out, mPackage, iface->getProxyName());
967 generateCppPackageInclude(out, mPackage, iface->getStubName());
968 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700969
970 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700971 generateCppPackageInclude(out,
972 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800973 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700974 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800975
976 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700977 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700978 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800979 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700980 }
981
982 out << "\n";
983
984 enterLeaveNamespace(out, true /* enter */);
985 out << "\n";
986
987 status_t err = generateTypeSource(out, ifaceName);
988
989 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700990 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700991
992 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -0800993 out << "const char* "
994 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -0700995 << "::descriptor(\""
996 << iface->fqName().string()
997 << "\");\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +0100998 out << "__attribute__((constructor))";
999 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001000 out.indent([&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001001 out << "::android::hardware::gBnConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001002 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001003 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001004 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001005 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001006 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001007 out << "return new "
1008 << iface->getStubName()
1009 << "(reinterpret_cast<"
1010 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001011 << " *>(iIntf));\n";
1012 });
Yifan Hongb04de382017-02-06 15:31:52 -08001013 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001014 });
Yifan Hongb04de382017-02-06 15:31:52 -08001015 out << "::android::hardware::gBsConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001016 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001017 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001018 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001019 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -08001020 << gIBaseFqName.cppName()
1021 << "> {\n";
1022 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001023 out << "return new "
1024 << iface->getPassthroughName()
1025 << "(reinterpret_cast<"
1026 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001027 << " *>(iIntf));\n";
1028 });
Yifan Hongb04de382017-02-06 15:31:52 -08001029 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001030 });
Yifan Hong158655a2016-11-08 12:34:07 -08001031 });
Martijn Coenen8adcb652017-02-03 17:37:36 +01001032 out << "};\n\n";
1033 out << "__attribute__((destructor))";
1034 out << "static void static_destructor() {\n";
1035 out.indent([&] {
1036 out << "::android::hardware::gBnConstructorMap.erase("
1037 << iface->localName()
1038 << "::descriptor);\n";
1039 out << "::android::hardware::gBsConstructorMap.erase("
1040 << iface->localName()
1041 << "::descriptor);\n";
1042 });
1043 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001044
Yifan Hongfe95aa22016-10-19 17:26:45 -07001045 err = generateInterfaceSource(out);
1046 }
1047
1048 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001049 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001050 }
1051
1052 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001053 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001054 }
1055
Steven Moreland40786312016-08-16 10:29:40 -07001056 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001057 err = generatePassthroughSource(out);
1058 }
1059
1060 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001061 const Interface *iface = mRootScope->getInterface();
1062
Yifan Hongc8934042016-11-17 17:10:52 -08001063 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001064 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001065 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001066 std::string package = iface->fqName().package()
1067 + iface->fqName().atVersion();
1068
Yifan Hongeefe4f22017-01-04 15:32:42 -08001069 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001070 }
Steven Moreland40786312016-08-16 10:29:40 -07001071 }
1072
Andreas Huber881227d2016-08-02 14:20:21 -07001073 enterLeaveNamespace(out, false /* enter */);
1074
1075 return err;
1076}
1077
Steven Moreland67f67b42016-09-29 08:59:02 -07001078// static
1079void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001080 out.sIf(nonNull + " == nullptr", [&] {
1081 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1082 out.indent(2, [&] {
1083 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1084 });
1085 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001086}
1087
Andreas Huber881227d2016-08-02 14:20:21 -07001088status_t AST::generateTypeSource(
1089 Formatter &out, const std::string &ifaceName) const {
1090 return mRootScope->emitTypeDefinitions(out, ifaceName);
1091}
1092
Andreas Hubere7ff2282016-08-16 13:50:03 -07001093void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001094 Formatter &out,
1095 const std::vector<TypedVar *> &args,
1096 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001097 if (args.empty()) {
1098 return;
1099 }
1100
1101 for (const auto &arg : args) {
1102 const Type &type = arg->type();
1103
Yifan Hong3b320f82016-11-01 15:15:54 -07001104 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001105 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001106 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001107 << ";\n";
1108 }
1109
1110 out << "\n";
1111}
1112
Andreas Huber881227d2016-08-02 14:20:21 -07001113void AST::emitCppReaderWriter(
1114 Formatter &out,
1115 const std::string &parcelObj,
1116 bool parcelObjIsPointer,
1117 const TypedVar *arg,
1118 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001119 Type::ErrorMode mode,
1120 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001121 const Type &type = arg->type();
1122
Andreas Huber881227d2016-08-02 14:20:21 -07001123 type.emitReaderWriter(
1124 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001125 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001126 parcelObj,
1127 parcelObjIsPointer,
1128 isReader,
1129 mode);
1130}
1131
Yifan Hongbf459bc2016-08-23 16:50:37 -07001132void AST::emitCppResolveReferences(
1133 Formatter &out,
1134 const std::string &parcelObj,
1135 bool parcelObjIsPointer,
1136 const TypedVar *arg,
1137 bool isReader,
1138 Type::ErrorMode mode,
1139 bool addPrefixToName) const {
1140 const Type &type = arg->type();
1141 if(type.needsResolveReferences()) {
1142 type.emitResolveReferences(
1143 out,
1144 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1145 isReader, // nameIsPointer
1146 parcelObj,
1147 parcelObjIsPointer,
1148 isReader,
1149 mode);
1150 }
1151}
1152
Yifan Hong068c5522016-10-31 14:07:25 -07001153status_t AST::generateProxyMethodSource(Formatter &out,
1154 const std::string &klassName,
1155 const Method *method,
1156 const Interface *superInterface) const {
1157
1158 method->generateCppSignature(out,
1159 klassName,
1160 true /* specify namespaces */);
1161
1162 const bool returnsValue = !method->results().empty();
1163 const TypedVar *elidedReturn = method->canElideCallback();
1164
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001165 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001166
1167 out.indent();
1168
Martijn Coenen115d4282016-12-19 05:14:04 +01001169 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1170 method->cppImpl(IMPL_PROXY, out);
1171 out.unindent();
1172 out << "}\n\n";
1173 return OK;
1174 }
1175
Yifan Hong068c5522016-10-31 14:07:25 -07001176 if (returnsValue && elidedReturn == nullptr) {
1177 generateCheckNonNull(out, "_hidl_cb");
1178 }
1179
1180 status_t status = generateCppInstrumentationCall(
1181 out,
1182 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001183 method);
1184 if (status != OK) {
1185 return status;
1186 }
1187
1188 out << "::android::hardware::Parcel _hidl_data;\n";
1189 out << "::android::hardware::Parcel _hidl_reply;\n";
1190 out << "::android::status_t _hidl_err;\n";
1191 out << "::android::hardware::Status _hidl_status;\n\n";
1192
1193 declareCppReaderLocals(
1194 out, method->results(), true /* forResults */);
1195
1196 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001197 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001198 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001199 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1200
Martijn Coenenfff73352017-01-04 16:36:31 +01001201 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001202 // First DFS: write all buffers and resolve pointers for parent
1203 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001204 if (arg->type().isInterface()) {
1205 hasInterfaceArgument = true;
1206 }
Yifan Hong068c5522016-10-31 14:07:25 -07001207 emitCppReaderWriter(
1208 out,
1209 "_hidl_data",
1210 false /* parcelObjIsPointer */,
1211 arg,
1212 false /* reader */,
1213 Type::ErrorMode_Goto,
1214 false /* addPrefixToName */);
1215 }
1216
1217 // Second DFS: resolve references.
1218 for (const auto &arg : method->args()) {
1219 emitCppResolveReferences(
1220 out,
1221 "_hidl_data",
1222 false /* parcelObjIsPointer */,
1223 arg,
1224 false /* reader */,
1225 Type::ErrorMode_Goto,
1226 false /* addPrefixToName */);
1227 }
1228
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001229 if (hasInterfaceArgument) {
1230 // Start binder threadpool to handle incoming transactions
1231 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1232 }
Yifan Hong068c5522016-10-31 14:07:25 -07001233 out << "_hidl_err = remote()->transact("
1234 << method->getSerialId()
1235 << " /* "
1236 << method->name()
1237 << " */, _hidl_data, &_hidl_reply";
1238
1239 if (method->isOneway()) {
1240 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1241 }
1242 out << ");\n";
1243
1244 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1245
1246 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001247 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001248 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1249 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1250
1251
1252 // First DFS: write all buffers and resolve pointers for parent
1253 for (const auto &arg : method->results()) {
1254 emitCppReaderWriter(
1255 out,
1256 "_hidl_reply",
1257 false /* parcelObjIsPointer */,
1258 arg,
1259 true /* reader */,
1260 Type::ErrorMode_Goto,
1261 true /* addPrefixToName */);
1262 }
1263
1264 // Second DFS: resolve references.
1265 for (const auto &arg : method->results()) {
1266 emitCppResolveReferences(
1267 out,
1268 "_hidl_reply",
1269 false /* parcelObjIsPointer */,
1270 arg,
1271 true /* reader */,
1272 Type::ErrorMode_Goto,
1273 true /* addPrefixToName */);
1274 }
1275
1276 if (returnsValue && elidedReturn == nullptr) {
1277 out << "_hidl_cb(";
1278
1279 bool first = true;
1280 for (const auto &arg : method->results()) {
1281 if (!first) {
1282 out << ", ";
1283 }
1284
1285 if (arg->type().resultNeedsDeref()) {
1286 out << "*";
1287 }
1288 out << "_hidl_out_" << arg->name();
1289
1290 first = false;
1291 }
1292
1293 out << ");\n\n";
1294 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001295 }
1296 status = generateCppInstrumentationCall(
1297 out,
1298 InstrumentationEvent::CLIENT_API_EXIT,
1299 method);
1300 if (status != OK) {
1301 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001302 }
1303
1304 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001305 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1306 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001307 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001308 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1309 } else {
1310 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1311 out << "return ::android::hardware::Return<void>();\n\n";
1312 }
1313
1314 out.unindent();
1315 out << "_hidl_error:\n";
1316 out.indent();
1317 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1318 out << "return ::android::hardware::Return<";
1319 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001320 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001321 } else {
1322 out << "void";
1323 }
1324 out << ">(_hidl_status);\n";
1325
1326 out.unindent();
1327 out << "}\n\n";
1328 return OK;
1329}
1330
Andreas Huber881227d2016-08-02 14:20:21 -07001331status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001332 Formatter &out, const FQName &fqName) const {
1333 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001334
1335 out << klassName
1336 << "::"
1337 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001338 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001339
1340 out.indent();
1341 out.indent();
1342
1343 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001344 << "<"
1345 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001346 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001347 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001348 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001349 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001350 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001351 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001352
Andreas Huber881227d2016-08-02 14:20:21 -07001353 out.unindent();
1354 out.unindent();
1355 out << "}\n\n";
1356
Yifan Hong068c5522016-10-31 14:07:25 -07001357 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1358 return generateProxyMethodSource(out, klassName, method, superInterface);
1359 });
Andreas Huber881227d2016-08-02 14:20:21 -07001360
Yifan Hong068c5522016-10-31 14:07:25 -07001361 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001362}
1363
1364status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001365 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001366 const Interface *iface) const {
1367 const std::string interfaceName = iface->localName();
1368 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001369
Steven Moreland40786312016-08-16 10:29:40 -07001370 out << klassName
1371 << "::"
1372 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001373 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001374
1375 out.indent();
1376 out.indent();
1377
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001378 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001379 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001380 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001381 out << ": "
1382 << gIBaseFqName.getInterfaceStubFqName().cppName()
1383 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001384 }
1385
1386 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001387 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001388 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001389 << "\") { \n";
1390 out.indent();
1391 out << "_hidl_mImpl = _hidl_impl;\n";
1392 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001393
1394 out.unindent();
1395 out.unindent();
1396 out << "}\n\n";
1397
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001398 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001399 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001400 // class properly.
1401 out << klassName
1402 << "::"
1403 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001404 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1405 << " const std::string &HidlInstrumentor_package,"
1406 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001407
1408 out.indent();
1409 out.indent();
1410
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001411 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001412 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001413 out.indent();
1414 out << "_hidl_mImpl = _hidl_impl;\n";
1415 out.unindent();
1416
1417 out.unindent();
1418 out.unindent();
1419 out << "}\n\n";
1420 }
1421
Yifan Hongbcffce22017-02-01 15:52:06 -08001422 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1423 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1424 return OK;
1425 }
1426 method->generateCppSignature(out, iface->getStubName());
1427 out << " ";
1428 out.block([&] {
1429 method->cppImpl(IMPL_STUB_IMPL, out);
1430 }).endl();
1431 return OK;
1432 });
Steven Moreland60818632017-02-04 00:33:42 -08001433 if (err != OK) {
1434 return err;
1435 }
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001436
Andreas Huber881227d2016-08-02 14:20:21 -07001437 out << "::android::status_t " << klassName << "::onTransact(\n";
1438
1439 out.indent();
1440 out.indent();
1441
Iliyan Malchev549e2592016-08-10 08:59:12 -07001442 out << "uint32_t _hidl_code,\n"
1443 << "const ::android::hardware::Parcel &_hidl_data,\n"
1444 << "::android::hardware::Parcel *_hidl_reply,\n"
1445 << "uint32_t _hidl_flags,\n"
1446 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001447
1448 out.unindent();
1449
Iliyan Malchev549e2592016-08-10 08:59:12 -07001450 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001451 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001452 out.indent();
1453
Yifan Hong10fe0b52016-10-19 14:20:17 -07001454 for (const auto &tuple : iface->allMethodsFromRoot()) {
1455 const Method *method = tuple.method();
1456 const Interface *superInterface = tuple.interface();
1457 out << "case "
1458 << method->getSerialId()
1459 << " /* "
1460 << method->name()
1461 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001462
Yifan Hong10fe0b52016-10-19 14:20:17 -07001463 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001464
Yifan Hong10fe0b52016-10-19 14:20:17 -07001465 status_t err =
1466 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001467
Yifan Hong10fe0b52016-10-19 14:20:17 -07001468 if (err != OK) {
1469 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001470 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001471
1472 out.unindent();
1473 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001474 }
1475
1476 out << "default:\n{\n";
1477 out.indent();
1478
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001479 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001480
1481 out.indent();
1482 out.indent();
1483
Iliyan Malchev549e2592016-08-10 08:59:12 -07001484 out << "_hidl_code, _hidl_data, _hidl_reply, "
1485 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001486
1487 out.unindent();
1488 out.unindent();
1489
1490 out.unindent();
1491 out << "}\n";
1492
1493 out.unindent();
1494 out << "}\n\n";
1495
Yifan Honga018ed52016-12-13 16:35:08 -08001496 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1497 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1498 out.indent(2, [&] {
1499 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1500 out << "_hidl_reply);\n";
1501 });
1502 });
Andreas Huber881227d2016-08-02 14:20:21 -07001503
Iliyan Malchev549e2592016-08-10 08:59:12 -07001504 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001505
1506 out.unindent();
1507 out << "}\n\n";
1508
1509 return OK;
1510}
1511
1512status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001513 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001514 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1515 method->cppImpl(IMPL_STUB, out);
1516 out << "break;\n";
1517 return OK;
1518 }
1519
Yifan Hongeefe4f22017-01-04 15:32:42 -08001520 out << "if (!_hidl_data.enforceInterface("
1521 << iface->fullName()
1522 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001523
Andreas Huber881227d2016-08-02 14:20:21 -07001524 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001525 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001526 out << "break;\n";
1527 out.unindent();
1528 out << "}\n\n";
1529
Andreas Huber5e44a292016-09-27 14:52:39 -07001530 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001531
Yifan Hongbf459bc2016-08-23 16:50:37 -07001532 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001533 for (const auto &arg : method->args()) {
1534 emitCppReaderWriter(
1535 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001536 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001537 false /* parcelObjIsPointer */,
1538 arg,
1539 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001540 Type::ErrorMode_Break,
1541 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001542 }
1543
Yifan Hongbf459bc2016-08-23 16:50:37 -07001544 // Second DFS: resolve references
1545 for (const auto &arg : method->args()) {
1546 emitCppResolveReferences(
1547 out,
1548 "_hidl_data",
1549 false /* parcelObjIsPointer */,
1550 arg,
1551 true /* reader */,
1552 Type::ErrorMode_Break,
1553 false /* addPrefixToName */);
1554 }
1555
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001556 status_t status = generateCppInstrumentationCall(
1557 out,
1558 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001559 method);
1560 if (status != OK) {
1561 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001562 }
1563
Andreas Huber881227d2016-08-02 14:20:21 -07001564 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001565 const TypedVar *elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -08001566 const std::string callee =
1567 (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL))
1568 ? "this" : "_hidl_mImpl";
Andreas Huber881227d2016-08-02 14:20:21 -07001569
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001570 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001571 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001572 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001573 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001574 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001575 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001576 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001577
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001578 bool first = true;
1579 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001580 if (!first) {
1581 out << ", ";
1582 }
1583
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001584 if (arg->type().resultNeedsDeref()) {
1585 out << "*";
1586 }
1587
1588 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001589
1590 first = false;
1591 }
1592
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001593 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001594 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1595 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001596
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001597 elidedReturn->type().emitReaderWriter(
1598 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001599 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001600 "_hidl_reply",
1601 true, /* parcelObjIsPointer */
1602 false, /* isReader */
1603 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001604
Yifan Hongbf459bc2016-08-23 16:50:37 -07001605 emitCppResolveReferences(
1606 out,
1607 "_hidl_reply",
1608 true /* parcelObjIsPointer */,
1609 elidedReturn,
1610 false /* reader */,
1611 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001612 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001613
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001614 status_t status = generateCppInstrumentationCall(
1615 out,
1616 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001617 method);
1618 if (status != OK) {
1619 return status;
1620 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001621
Iliyan Malchev549e2592016-08-10 08:59:12 -07001622 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001623 } else {
1624 if (returnsValue) {
1625 out << "bool _hidl_callbackCalled = false;\n\n";
1626 }
Andreas Huber881227d2016-08-02 14:20:21 -07001627
Yifan Hongcd2ae452017-01-31 14:33:40 -08001628 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001629
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001630 bool first = true;
1631 for (const auto &arg : method->args()) {
1632 if (!first) {
1633 out << ", ";
1634 }
Andreas Huber881227d2016-08-02 14:20:21 -07001635
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001636 if (arg->type().resultNeedsDeref()) {
1637 out << "*";
1638 }
1639
1640 out << arg->name();
1641
1642 first = false;
1643 }
1644
1645 if (returnsValue) {
1646 if (!first) {
1647 out << ", ";
1648 }
1649
1650 out << "[&](";
1651
1652 first = true;
1653 for (const auto &arg : method->results()) {
1654 if (!first) {
1655 out << ", ";
1656 }
1657
Yifan Honga47eef32016-12-12 10:38:54 -08001658 out << "const auto &_hidl_out_" << arg->name();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001659
1660 first = false;
1661 }
1662
1663 out << ") {\n";
1664 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001665 out << "if (_hidl_callbackCalled) {\n";
1666 out.indent();
1667 out << "LOG_ALWAYS_FATAL(\""
1668 << method->name()
1669 << ": _hidl_cb called a second time, but must be called once.\");\n";
1670 out.unindent();
1671 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001672 out << "_hidl_callbackCalled = true;\n\n";
1673
Yifan Hong859e53f2016-11-14 19:08:24 -08001674 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1675 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001676
Yifan Hongbf459bc2016-08-23 16:50:37 -07001677 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001678 for (const auto &arg : method->results()) {
1679 emitCppReaderWriter(
1680 out,
1681 "_hidl_reply",
1682 true /* parcelObjIsPointer */,
1683 arg,
1684 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001685 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001686 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001687 }
1688
Yifan Hongbf459bc2016-08-23 16:50:37 -07001689 // Second DFS: resolve references
1690 for (const auto &arg : method->results()) {
1691 emitCppResolveReferences(
1692 out,
1693 "_hidl_reply",
1694 true /* parcelObjIsPointer */,
1695 arg,
1696 false /* reader */,
1697 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001698 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001699 }
1700
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001701 status_t status = generateCppInstrumentationCall(
1702 out,
1703 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001704 method);
1705 if (status != OK) {
1706 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001707 }
1708
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001709 out << "_hidl_cb(*_hidl_reply);\n";
1710
1711 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001712 out << "});\n\n";
1713 } else {
1714 out << ");\n\n";
1715 status_t status = generateCppInstrumentationCall(
1716 out,
1717 InstrumentationEvent::SERVER_API_EXIT,
1718 method);
1719 if (status != OK) {
1720 return status;
1721 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001722 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001723
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001724 if (returnsValue) {
1725 out << "if (!_hidl_callbackCalled) {\n";
1726 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001727 out << "LOG_ALWAYS_FATAL(\""
1728 << method->name()
1729 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001730 out.unindent();
1731 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001732 } else {
1733 out << "::android::hardware::writeToParcel("
1734 << "::android::hardware::Status::ok(), "
1735 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001736 }
Andreas Huber881227d2016-08-02 14:20:21 -07001737 }
1738
1739 out << "break;\n";
1740
1741 return OK;
1742}
1743
Steven Moreland69e7c702016-09-09 11:16:32 -07001744status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1745 std::string ifaceName;
1746 if (!AST::isInterface(&ifaceName)) {
1747 // types.hal does not get a stub header.
1748 return OK;
1749 }
1750
1751 const Interface *iface = mRootScope->getInterface();
1752
Yifan Hongeefe4f22017-01-04 15:32:42 -08001753 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001754
1755 bool supportOneway = iface->hasOnewayMethods();
1756
1757 std::string path = outputPath;
1758 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1759 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1760 path.append(klassName);
1761 path.append(".h");
1762
1763 CHECK(Coordinator::MakeParentHierarchy(path));
1764 FILE *file = fopen(path.c_str(), "w");
1765
1766 if (file == NULL) {
1767 return -errno;
1768 }
1769
1770 Formatter out(file);
1771
1772 const std::string guard = makeHeaderGuard(klassName);
1773
1774 out << "#ifndef " << guard << "\n";
1775 out << "#define " << guard << "\n\n";
1776
1777 std::vector<std::string> packageComponents;
1778 getPackageAndVersionComponents(
1779 &packageComponents, false /* cpp_compatible */);
1780
Yifan Hongb0949432016-12-15 15:32:24 -08001781 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001782 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001783
1784 generateCppPackageInclude(out, mPackage, ifaceName);
1785 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001786
Yifan Hong7a118f52016-12-07 11:21:15 -08001787 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001788 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001789 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001790 }
1791
1792 enterLeaveNamespace(out, true /* enter */);
1793 out << "\n";
1794
1795 out << "struct "
1796 << klassName
1797 << " : " << ifaceName
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001798 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001799
1800 out.indent();
1801 out << "explicit "
1802 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001803 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001804 << ifaceName
1805 << "> impl);\n";
1806
Yifan Hong068c5522016-10-31 14:07:25 -07001807 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1808 return generatePassthroughMethod(out, method);
1809 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001810
1811 if (err != OK) {
1812 return err;
1813 }
1814
1815 out.unindent();
1816 out << "private:\n";
1817 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001818 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001819
1820 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001821 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001822
1823 out << "\n";
1824
1825 out << "::android::hardware::Return<void> addOnewayTask("
1826 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001827 }
1828
1829 out.unindent();
1830
1831 out << "};\n\n";
1832
1833 enterLeaveNamespace(out, false /* enter */);
1834
1835 out << "\n#endif // " << guard << "\n";
1836
1837 return OK;
1838}
1839
Yifan Hongfe95aa22016-10-19 17:26:45 -07001840status_t AST::generateInterfaceSource(Formatter &out) const {
1841 const Interface *iface = mRootScope->getInterface();
1842
Yifan Hong2d7126b2016-10-20 15:12:57 -07001843 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001844 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001845
Yifan Hong3d746092016-12-07 14:26:33 -08001846 for (const Interface *superType : iface->typeChain()) {
1847 out << "// static \n"
1848 << childTypeResult
Yifan Hongeefe4f22017-01-04 15:32:42 -08001849 << " "
1850 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001851 << "::castFrom("
1852 << superType->getCppArgumentType()
1853 << " parent) {\n";
1854 out.indent();
1855 if (iface == superType) {
1856 out << "return parent;\n";
1857 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001858 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001859 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001860 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001861 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001862 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001863 << ">(\n";
1864 out.indent();
1865 out.indent();
1866 out << "parent, \""
1867 << iface->fqName().string()
1868 << "\");\n";
1869 out.unindent();
1870 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001871 }
Yifan Hong3d746092016-12-07 14:26:33 -08001872 out.unindent();
1873 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001874 }
1875
1876 return OK;
1877}
1878
Steven Moreland69e7c702016-09-09 11:16:32 -07001879status_t AST::generatePassthroughSource(Formatter &out) const {
1880 const Interface *iface = mRootScope->getInterface();
1881
Yifan Hongeefe4f22017-01-04 15:32:42 -08001882 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001883
1884 out << klassName
1885 << "::"
1886 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001887 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001888 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001889 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001890 << mPackage.string()
1891 << "\", \""
1892 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001893 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001894 if (iface->hasOnewayMethods()) {
1895 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001896 out.indent([&] {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001897 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1898 });
1899 }
1900 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001901
1902 if (iface->hasOnewayMethods()) {
1903 out << "::android::hardware::Return<void> "
1904 << klassName
1905 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1906 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001907 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001908 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001909 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1910 out.indent();
1911 out.indent();
1912 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1913 out.unindent();
1914 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001915 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001916 out << "}\n";
1917
Steven Morelandd366c262016-10-11 15:29:10 -07001918 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001919
1920 out.unindent();
1921 out << "}\n\n";
1922
1923
1924 }
1925
1926 return OK;
1927}
1928
Martijn Coenen7b295242016-11-04 16:52:56 +01001929status_t AST::generateCppAtraceCall(Formatter &out,
1930 InstrumentationEvent event,
1931 const Method *method) const {
1932 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001933 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001934 switch (event) {
1935 case SERVER_API_ENTRY:
1936 {
1937 out << "atrace_begin(ATRACE_TAG_HAL, \""
1938 << baseString + "::server\");\n";
1939 break;
1940 }
1941 case CLIENT_API_ENTRY:
1942 {
1943 out << "atrace_begin(ATRACE_TAG_HAL, \""
1944 << baseString + "::client\");\n";
1945 break;
1946 }
1947 case PASSTHROUGH_ENTRY:
1948 {
1949 out << "atrace_begin(ATRACE_TAG_HAL, \""
1950 << baseString + "::passthrough\");\n";
1951 break;
1952 }
1953 case SERVER_API_EXIT:
1954 case CLIENT_API_EXIT:
1955 case PASSTHROUGH_EXIT:
1956 {
1957 out << "atrace_end(ATRACE_TAG_HAL);\n";
1958 break;
1959 }
1960 default:
1961 {
1962 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1963 return UNKNOWN_ERROR;
1964 }
1965 }
1966
1967 return OK;
1968}
1969
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001970status_t AST::generateCppInstrumentationCall(
1971 Formatter &out,
1972 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001973 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001974 status_t err = generateCppAtraceCall(out, event, method);
1975 if (err != OK) {
1976 return err;
1977 }
1978
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001979 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1980 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001981 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001982 std::string event_str = "";
1983 switch (event) {
1984 case SERVER_API_ENTRY:
1985 {
1986 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1987 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001988 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001989 << (arg->type().resultNeedsDeref() ? "" : "&")
1990 << arg->name()
1991 << ");\n";
1992 }
1993 break;
1994 }
1995 case SERVER_API_EXIT:
1996 {
1997 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001998 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001999 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07002000 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002001 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002002 }
2003 break;
2004 }
2005 case CLIENT_API_ENTRY:
2006 {
2007 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2008 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002009 out << "_hidl_args.push_back((void *)&"
2010 << arg->name()
2011 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002012 }
2013 break;
2014 }
2015 case CLIENT_API_EXIT:
2016 {
2017 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2018 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002019 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002020 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002021 << "_hidl_out_"
2022 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002023 << ");\n";
2024 }
2025 break;
2026 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002027 case PASSTHROUGH_ENTRY:
2028 {
2029 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2030 for (const auto &arg : method->args()) {
2031 out << "_hidl_args.push_back((void *)&"
2032 << arg->name()
2033 << ");\n";
2034 }
2035 break;
2036 }
2037 case PASSTHROUGH_EXIT:
2038 {
2039 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002040 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002041 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002042 << arg->name()
2043 << ");\n";
2044 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002045 break;
2046 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002047 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002048 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002049 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002050 return UNKNOWN_ERROR;
2051 }
2052 }
2053
Steven Moreland031ccf12016-10-31 15:54:38 -07002054 const Interface *iface = mRootScope->getInterface();
2055
Steven Moreland1ab31442016-11-03 18:37:51 -07002056 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002057 out.indent();
2058 out << "callback("
2059 << event_str
2060 << ", \""
2061 << mPackage.package()
2062 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002063 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002064 << "\", \""
2065 << iface->localName()
2066 << "\", \""
2067 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002068 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002069 out.unindent();
2070 out << "}\n";
2071 out.unindent();
2072 out << "}\n\n";
2073
2074 return OK;
2075}
2076
Andreas Huber881227d2016-08-02 14:20:21 -07002077} // namespace android