blob: e38873ca3e4b6e826de6e175b644a7849fbf61e7 [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("
Ian Pedowitz2f7abc92017-03-17 20:01:13 +0000159 << "const std::string &serviceName, bool getStub) ";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800160 out.block([&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000161 out << "::android::sp<" << interfaceName << "> iface = nullptr;\n";
Yifan Hongd3b58ed2017-01-30 14:13:10 -0800162 out << "::android::vintf::Transport transport = ::android::hardware::getTransport("
Yifan Hong152866b2017-02-28 15:34:27 -0800163 << interfaceName << "::descriptor, serviceName);\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000164
Ian Pedowitz2f7abc92017-03-17 20:01:13 +0000165 out.sIf("!getStub && "
166 "(transport == ::android::vintf::Transport::HWBINDER || "
167 "transport == ::android::vintf::Transport::TOGGLED || "
168 "transport == ::android::vintf::Transport::EMPTY)", [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000169 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 });
Ian Pedowitz2f7abc92017-03-17 20:01:13 +0000173 out.sIf("sm != nullptr", [&] {
174 // TODO(b/34274385) remove sysprop check
175 out.sIf("transport == ::android::vintf::Transport::HWBINDER ||"
176 "(transport == ::android::vintf::Transport::TOGGLED &&"
177 " ::android::hardware::details::blockingHalBinderizationEnabled())", [&]() {
178 out << "::android::hardware::details::waitForHwService("
179 << interfaceName << "::descriptor" << ", serviceName);\n";
180 }).endl();
181 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();
190 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800191 }).endl();
192 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800193
Ian Pedowitz2f7abc92017-03-17 20:01:13 +0000194 out.sIf("getStub || "
195 "transport == ::android::vintf::Transport::PASSTHROUGH || "
196 "(transport == ::android::vintf::Transport::TOGGLED &&"
197 " !::android::hardware::details::blockingHalBinderizationEnabled()) ||"
198 "transport == ::android::vintf::Transport::EMPTY", [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000199 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";
Ian Pedowitz2f7abc92017-03-17 20:01:13 +0000215 });
Steven Morelandf10af872017-01-25 16:01:56 +0000216 }).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 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700399 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700400 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700401 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700402 }
Steven Moreland40786312016-08-16 10:29:40 -0700403
Yifan Hong3d746092016-12-07 14:26:33 -0800404 out << "// cast static functions\n";
405 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700406
Yifan Hong3d746092016-12-07 14:26:33 -0800407 for (const Interface *superType : iface->typeChain()) {
408 out << "static "
409 << childTypeResult
410 << " castFrom("
411 << superType->getCppArgumentType()
412 << " parent"
413 << ");\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700414 }
415
Steven Morelandd39133b2016-11-11 12:30:08 -0800416 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700417
Yifan Hongc8934042016-11-17 17:10:52 -0800418 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800419 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800420 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800421 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800422 }
Andreas Huber881227d2016-08-02 14:20:21 -0700423 }
424
425 if (isInterface) {
426 out.unindent();
427
Andreas Hubere3f769a2016-10-10 10:54:44 -0700428 out << "};\n\n";
429 }
430
431 err = mRootScope->emitGlobalTypeDeclarations(out);
432
433 if (err != OK) {
434 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700435 }
436
437 out << "\n";
438 enterLeaveNamespace(out, false /* enter */);
439
440 out << "\n#endif // " << guard << "\n";
441
442 return OK;
443}
444
Steven Moreland40786312016-08-16 10:29:40 -0700445status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
446 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800447 bool isInterface = AST::isInterface(&ifaceName);
448 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800449 std::string klassName{};
450
451 if(isInterface) {
452 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800453 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800454 } else {
455 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700456 }
457
Steven Moreland40786312016-08-16 10:29:40 -0700458 std::string path = outputPath;
459 path.append(mCoordinator->convertPackageRootToPath(mPackage));
460 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
461 path.append(klassName + ".h");
462
Yifan Hong244e82d2016-11-11 11:13:57 -0800463 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700464
465 if (file == NULL) {
466 return -errno;
467 }
468
469 Formatter out(file);
470
471 const std::string guard = makeHeaderGuard(klassName);
472
473 out << "#ifndef " << guard << "\n";
474 out << "#define " << guard << "\n\n";
475
Yifan Hong244e82d2016-11-11 11:13:57 -0800476 if (isInterface) {
477 generateCppPackageInclude(out, mPackage, ifaceName);
478 } else {
479 generateCppPackageInclude(out, mPackage, "types");
480 }
Steven Moreland40786312016-08-16 10:29:40 -0700481
Steven Morelandee88eed2016-10-31 17:49:00 -0700482 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700483
484 for (const auto &item : mImportedNames) {
485 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800486 generateCppPackageInclude(out, item, "hwtypes");
487 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800488 generateCppPackageInclude(out, item, item.getInterfaceStubName());
489 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700490 }
Steven Moreland40786312016-08-16 10:29:40 -0700491 }
492
493 out << "\n";
494
Martijn Coenen93915102016-09-01 01:35:52 +0200495 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700496 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100497 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700498
499 out << "\n";
500
501 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700502
Yifan Hong244e82d2016-11-11 11:13:57 -0800503 status_t err = mRootScope->emitGlobalHwDeclarations(out);
504 if (err != OK) {
505 return err;
506 }
Steven Moreland40786312016-08-16 10:29:40 -0700507
508 enterLeaveNamespace(out, false /* enter */);
509
510 out << "\n#endif // " << guard << "\n";
511
512 return OK;
513}
514
Andreas Huber881227d2016-08-02 14:20:21 -0700515status_t AST::emitTypeDeclarations(Formatter &out) const {
516 return mRootScope->emitTypeDeclarations(out);
517}
518
Yifan Hong7a118f52016-12-07 11:21:15 -0800519static void wrapPassthroughArg(Formatter &out,
520 const TypedVar *arg, bool addPrefixToName,
521 std::function<void(void)> handleError) {
522 if (!arg->type().isInterface()) {
523 return;
524 }
525 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
526 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
527 + arg->name();
528 const Interface &iface = static_cast<const Interface &>(arg->type());
529 out << iface.getCppStackType() << " " << wrappedName << ";\n";
530 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
531 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
532 out << wrappedName
533 << " = "
534 << iface.fqName().cppName()
Yifan Hong052425a2017-03-13 17:06:13 -0700535 << "::castFrom(::android::hardware::details::wrapPassthrough("
Yifan Hong7a118f52016-12-07 11:21:15 -0800536 << name << "));\n";
537 out.sIf(wrappedName + " == nullptr", [&] {
538 // Fatal error. Happens when the BsFoo class is not found in the binary
539 // or any dynamic libraries.
540 handleError();
541 }).endl();
542 }).sElse([&] {
543 out << wrappedName << " = " << name << ";\n";
544 }).endl().endl();
545}
546
Steven Moreland69e7c702016-09-09 11:16:32 -0700547status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700548 const Method *method) const {
549 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700550
551 out << " {\n";
552 out.indent();
553
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800554 if (method->isHidlReserved()
555 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
556 method->cppImpl(IMPL_PASSTHROUGH, out);
557 out.unindent();
558 out << "}\n\n";
559 return OK;
560 }
561
Steven Moreland69e7c702016-09-09 11:16:32 -0700562 const bool returnsValue = !method->results().empty();
563 const TypedVar *elidedReturn = method->canElideCallback();
564
Steven Moreland67f67b42016-09-29 08:59:02 -0700565 if (returnsValue && elidedReturn == nullptr) {
566 generateCheckNonNull(out, "_hidl_cb");
567 }
568
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700569 generateCppInstrumentationCall(
570 out,
571 InstrumentationEvent::PASSTHROUGH_ENTRY,
572 method);
573
Yifan Hong7a118f52016-12-07 11:21:15 -0800574
575 for (const auto &arg : method->args()) {
576 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
577 out << "return ::android::hardware::Status::fromExceptionCode(\n";
578 out.indent(2, [&] {
579 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800580 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800581 });
582 });
583 }
584
585 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700586 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700587
588 if (method->isOneway()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800589 out << "addOnewayTask([this, &_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700590 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800591 out << ", "
592 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
593 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700594 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700595 out << "] {\n";
596 out.indent();
597 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700598 }
599
600 out << "mImpl->"
601 << method->name()
602 << "(";
603
604 bool first = true;
605 for (const auto &arg : method->args()) {
606 if (!first) {
607 out << ", ";
608 }
609 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800610 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700611 }
612 if (returnsValue && elidedReturn == nullptr) {
613 if (!method->args().empty()) {
614 out << ", ";
615 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800616 out << "[&](";
617 first = true;
618 for (const auto &arg : method->results()) {
619 if (!first) {
620 out << ", ";
621 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700622
Yifan Hong7a118f52016-12-07 11:21:15 -0800623 out << "const auto &_hidl_out_"
624 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800625
626 first = false;
627 }
628
629 out << ") {\n";
630 out.indent();
631 status_t status = generateCppInstrumentationCall(
632 out,
633 InstrumentationEvent::PASSTHROUGH_EXIT,
634 method);
635 if (status != OK) {
636 return status;
637 }
638
Yifan Hong7a118f52016-12-07 11:21:15 -0800639 for (const auto &arg : method->results()) {
640 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
641 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
642 out.indent(2, [&] {
643 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800644 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800645 });
646 out << "return;\n";
647 });
648 }
649
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800650 out << "_hidl_cb(";
651 first = true;
652 for (const auto &arg : method->results()) {
653 if (!first) {
654 out << ", ";
655 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800656 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800657 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
658 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800659 }
660 out << ");\n";
661 out.unindent();
662 out << "});\n\n";
663 } else {
664 out << ");\n\n";
665 if (elidedReturn != nullptr) {
666 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800667 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800668 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000669 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800670 }
671 status_t status = generateCppInstrumentationCall(
672 out,
673 InstrumentationEvent::PASSTHROUGH_EXIT,
674 method);
675 if (status != OK) {
676 return status;
677 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700678 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700679
680 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700681 out.unindent();
682 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700683 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700684
685 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700686
687 out.unindent();
688 out << "}\n";
689
690 return OK;
691}
692
Yifan Hong068c5522016-10-31 14:07:25 -0700693status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700694
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700695 const Interface *iface = mRootScope->getInterface();
696
Yifan Hong10fe0b52016-10-19 14:20:17 -0700697 const Interface *prevIterface = nullptr;
698 for (const auto &tuple : iface->allMethodsFromRoot()) {
699 const Method *method = tuple.method();
700 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700701
Yifan Hong10fe0b52016-10-19 14:20:17 -0700702 if(prevIterface != superInterface) {
703 if (prevIterface != nullptr) {
704 out << "\n";
705 }
706 out << "// Methods from "
707 << superInterface->fullName()
708 << " follow.\n";
709 prevIterface = superInterface;
710 }
Yifan Hong068c5522016-10-31 14:07:25 -0700711 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700712
Yifan Hong10fe0b52016-10-19 14:20:17 -0700713 if (err != OK) {
714 return err;
715 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700716 }
717
Yifan Hong10fe0b52016-10-19 14:20:17 -0700718 out << "\n";
719
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700720 return OK;
721}
722
Andreas Huberb82318c2016-08-02 14:45:54 -0700723status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700724 std::string ifaceName;
725 if (!AST::isInterface(&ifaceName)) {
726 // types.hal does not get a stub header.
727 return OK;
728 }
729
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700730 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800731 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700732
Andreas Huberb82318c2016-08-02 14:45:54 -0700733 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700734 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700735 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700736 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700737 path.append(".h");
738
Andreas Huberd2943e12016-08-05 11:59:31 -0700739 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700740 FILE *file = fopen(path.c_str(), "w");
741
742 if (file == NULL) {
743 return -errno;
744 }
745
746 Formatter out(file);
747
Steven Moreland40786312016-08-16 10:29:40 -0700748 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700749
750 out << "#ifndef " << guard << "\n";
751 out << "#define " << guard << "\n\n";
752
Yifan Hongeefe4f22017-01-04 15:32:42 -0800753 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700754 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700755
756 enterLeaveNamespace(out, true /* enter */);
757 out << "\n";
758
759 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800760 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100761 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800762 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000763 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100764 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800765 out << " : public "
766 << gIBaseFqName.getInterfaceStubFqName().cppName()
767 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100768 }
Andreas Huber881227d2016-08-02 14:20:21 -0700769
770 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800771 out << "explicit "
772 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700773 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100774 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800775 out << "explicit "
776 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100777 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800778 << " const std::string& HidlInstrumentor_package,"
779 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700780 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700781 out << "::android::status_t onTransact(\n";
782 out.indent();
783 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700784 out << "uint32_t _hidl_code,\n";
785 out << "const ::android::hardware::Parcel &_hidl_data,\n";
786 out << "::android::hardware::Parcel *_hidl_reply,\n";
787 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700788 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700789 out.unindent();
790 out.unindent();
791
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100792 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
793 out.unindent();
794 out << "private:\n";
795 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800796
797 status_t err = generateMethods(out, [&](const Method *method, const Interface *iface) {
798 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
799 return OK;
800 }
801 const bool returnsValue = !method->results().empty();
802 const TypedVar *elidedReturn = method->canElideCallback();
803
804 if (elidedReturn == nullptr && returnsValue) {
805 out << "using " << method->name() << "_cb = "
806 << iface->fqName().cppName()
807 << "::" << method->name() << "_cb;\n";
808 }
809 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800810 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800811 return OK;
812 });
813 if (err != OK) {
814 return err;
815 }
816
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100817 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700818 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700819 out << "};\n\n";
820
821 enterLeaveNamespace(out, false /* enter */);
822
823 out << "\n#endif // " << guard << "\n";
824
825 return OK;
826}
827
Andreas Huberb82318c2016-08-02 14:45:54 -0700828status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700829 std::string ifaceName;
830 if (!AST::isInterface(&ifaceName)) {
831 // types.hal does not get a proxy header.
832 return OK;
833 }
834
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700835 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800836 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700837
Andreas Huberb82318c2016-08-02 14:45:54 -0700838 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700839 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700840 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800841 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700842 path.append(".h");
843
Andreas Huberd2943e12016-08-05 11:59:31 -0700844 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700845 FILE *file = fopen(path.c_str(), "w");
846
847 if (file == NULL) {
848 return -errno;
849 }
850
851 Formatter out(file);
852
Yifan Hongeefe4f22017-01-04 15:32:42 -0800853 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700854
855 out << "#ifndef " << guard << "\n";
856 out << "#define " << guard << "\n\n";
857
Martijn Coenen115d4282016-12-19 05:14:04 +0100858 out << "#include <hidl/HidlTransportSupport.h>\n\n";
859
Andreas Huber881227d2016-08-02 14:20:21 -0700860 std::vector<std::string> packageComponents;
861 getPackageAndVersionComponents(
862 &packageComponents, false /* cpp_compatible */);
863
Yifan Hongeefe4f22017-01-04 15:32:42 -0800864 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700865 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700866
867 enterLeaveNamespace(out, true /* enter */);
868 out << "\n";
869
870 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800871 << proxyName
872 << " : public ::android::hardware::BpInterface<"
873 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000874 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700875
876 out.indent();
877
Yifan Hongeefe4f22017-01-04 15:32:42 -0800878 out << "explicit "
879 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700880 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700881 << "\n\n";
882
Yifan Hong10fe0b52016-10-19 14:20:17 -0700883 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700884
Yifan Hong068c5522016-10-31 14:07:25 -0700885 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
886 method->generateCppSignature(out);
887 out << " override;\n";
888 return OK;
889 });
Steven Moreland9c387612016-09-07 09:54:26 -0700890
891 if (err != OK) {
892 return err;
893 }
Andreas Huber881227d2016-08-02 14:20:21 -0700894
895 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100896 out << "private:\n";
897 out.indent();
898 out << "std::mutex _hidl_mMutex;\n"
899 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
900 << " _hidl_mDeathRecipients;\n";
901 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700902 out << "};\n\n";
903
904 enterLeaveNamespace(out, false /* enter */);
905
906 out << "\n#endif // " << guard << "\n";
907
908 return OK;
909}
910
Andreas Huberb82318c2016-08-02 14:45:54 -0700911status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700912
Andreas Huberb82318c2016-08-02 14:45:54 -0700913 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700914 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700915 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700916
917 std::string ifaceName;
918 std::string baseName;
919
Yifan Hongfe95aa22016-10-19 17:26:45 -0700920 const Interface *iface = nullptr;
921 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700922 if (!AST::isInterface(&ifaceName)) {
923 baseName = "types";
924 isInterface = false;
925 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700926 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700927 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700928 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700929 }
930
931 path.append(baseName);
932
933 if (baseName != "types") {
934 path.append("All");
935 }
936
937 path.append(".cpp");
938
Andreas Huberd2943e12016-08-05 11:59:31 -0700939 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700940 FILE *file = fopen(path.c_str(), "w");
941
942 if (file == NULL) {
943 return -errno;
944 }
945
946 Formatter out(file);
947
Steven Moreland623c0042017-01-13 14:42:29 -0800948 out << "#define LOG_TAG \""
949 << mPackage.string() << "::" << baseName
950 << "\"\n\n";
951
Steven Moreland05cd4232016-11-21 16:01:12 -0800952 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100953 out << "#include <cutils/trace.h>\n";
954 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700955 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700956 // This is a no-op for IServiceManager itself.
957 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
958
Steven Morelandbec74ed2017-01-25 17:42:35 -0800959 // TODO(b/34274385) remove this
960 out << "#include <hidl/LegacySupport.h>\n";
961
Yifan Hongeefe4f22017-01-04 15:32:42 -0800962 generateCppPackageInclude(out, mPackage, iface->getProxyName());
963 generateCppPackageInclude(out, mPackage, iface->getStubName());
964 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700965
966 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700967 generateCppPackageInclude(out,
968 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800969 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700970 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800971
972 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700973 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700974 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800975 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700976 }
977
978 out << "\n";
979
980 enterLeaveNamespace(out, true /* enter */);
981 out << "\n";
982
983 status_t err = generateTypeSource(out, ifaceName);
984
985 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700986 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700987
988 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -0800989 out << "const char* "
990 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -0700991 << "::descriptor(\""
992 << iface->fqName().string()
993 << "\");\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +0100994 out << "__attribute__((constructor))";
995 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800996 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -0700997 out << "::android::hardware::details::gBnConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -0800998 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -0800999 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001000 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001001 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001002 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001003 out << "return new "
1004 << iface->getStubName()
1005 << "(reinterpret_cast<"
1006 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001007 << " *>(iIntf));\n";
1008 });
Yifan Hongb04de382017-02-06 15:31:52 -08001009 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001010 });
Yifan Honga159f3b2017-03-16 14:53:51 -07001011 out << "::android::hardware::details::gBsConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001012 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001013 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001014 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001015 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -08001016 << gIBaseFqName.cppName()
1017 << "> {\n";
1018 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001019 out << "return new "
1020 << iface->getPassthroughName()
1021 << "(reinterpret_cast<"
1022 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001023 << " *>(iIntf));\n";
1024 });
Yifan Hongb04de382017-02-06 15:31:52 -08001025 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001026 });
Yifan Hong158655a2016-11-08 12:34:07 -08001027 });
Martijn Coenen8adcb652017-02-03 17:37:36 +01001028 out << "};\n\n";
1029 out << "__attribute__((destructor))";
1030 out << "static void static_destructor() {\n";
1031 out.indent([&] {
Yifan Honga159f3b2017-03-16 14:53:51 -07001032 out << "::android::hardware::details::gBnConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001033 << iface->localName()
1034 << "::descriptor);\n";
Yifan Honga159f3b2017-03-16 14:53:51 -07001035 out << "::android::hardware::details::gBsConstructorMap.erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +01001036 << iface->localName()
1037 << "::descriptor);\n";
1038 });
1039 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001040
Yifan Hongfe95aa22016-10-19 17:26:45 -07001041 err = generateInterfaceSource(out);
1042 }
1043
1044 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001045 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001046 }
1047
1048 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001049 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001050 }
1051
Steven Moreland40786312016-08-16 10:29:40 -07001052 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001053 err = generatePassthroughSource(out);
1054 }
1055
1056 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001057 const Interface *iface = mRootScope->getInterface();
1058
Yifan Hongc8934042016-11-17 17:10:52 -08001059 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001060 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001061 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001062 std::string package = iface->fqName().package()
1063 + iface->fqName().atVersion();
1064
Yifan Hongeefe4f22017-01-04 15:32:42 -08001065 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001066 }
Steven Moreland40786312016-08-16 10:29:40 -07001067 }
1068
Andreas Huber881227d2016-08-02 14:20:21 -07001069 enterLeaveNamespace(out, false /* enter */);
1070
1071 return err;
1072}
1073
Steven Moreland67f67b42016-09-29 08:59:02 -07001074// static
1075void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001076 out.sIf(nonNull + " == nullptr", [&] {
1077 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1078 out.indent(2, [&] {
1079 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1080 });
1081 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001082}
1083
Andreas Huber881227d2016-08-02 14:20:21 -07001084status_t AST::generateTypeSource(
1085 Formatter &out, const std::string &ifaceName) const {
1086 return mRootScope->emitTypeDefinitions(out, ifaceName);
1087}
1088
Andreas Hubere7ff2282016-08-16 13:50:03 -07001089void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001090 Formatter &out,
1091 const std::vector<TypedVar *> &args,
1092 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001093 if (args.empty()) {
1094 return;
1095 }
1096
1097 for (const auto &arg : args) {
1098 const Type &type = arg->type();
1099
Yifan Hong3b320f82016-11-01 15:15:54 -07001100 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001101 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001102 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001103 << ";\n";
1104 }
1105
1106 out << "\n";
1107}
1108
Andreas Huber881227d2016-08-02 14:20:21 -07001109void AST::emitCppReaderWriter(
1110 Formatter &out,
1111 const std::string &parcelObj,
1112 bool parcelObjIsPointer,
1113 const TypedVar *arg,
1114 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001115 Type::ErrorMode mode,
1116 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001117 const Type &type = arg->type();
1118
Andreas Huber881227d2016-08-02 14:20:21 -07001119 type.emitReaderWriter(
1120 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001121 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001122 parcelObj,
1123 parcelObjIsPointer,
1124 isReader,
1125 mode);
1126}
1127
Yifan Hongbf459bc2016-08-23 16:50:37 -07001128void AST::emitCppResolveReferences(
1129 Formatter &out,
1130 const std::string &parcelObj,
1131 bool parcelObjIsPointer,
1132 const TypedVar *arg,
1133 bool isReader,
1134 Type::ErrorMode mode,
1135 bool addPrefixToName) const {
1136 const Type &type = arg->type();
1137 if(type.needsResolveReferences()) {
1138 type.emitResolveReferences(
1139 out,
1140 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1141 isReader, // nameIsPointer
1142 parcelObj,
1143 parcelObjIsPointer,
1144 isReader,
1145 mode);
1146 }
1147}
1148
Yifan Hong068c5522016-10-31 14:07:25 -07001149status_t AST::generateProxyMethodSource(Formatter &out,
1150 const std::string &klassName,
1151 const Method *method,
1152 const Interface *superInterface) const {
1153
1154 method->generateCppSignature(out,
1155 klassName,
1156 true /* specify namespaces */);
1157
1158 const bool returnsValue = !method->results().empty();
1159 const TypedVar *elidedReturn = method->canElideCallback();
1160
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001161 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001162
1163 out.indent();
1164
Martijn Coenen115d4282016-12-19 05:14:04 +01001165 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1166 method->cppImpl(IMPL_PROXY, out);
1167 out.unindent();
1168 out << "}\n\n";
1169 return OK;
1170 }
1171
Yifan Hong068c5522016-10-31 14:07:25 -07001172 if (returnsValue && elidedReturn == nullptr) {
1173 generateCheckNonNull(out, "_hidl_cb");
1174 }
1175
1176 status_t status = generateCppInstrumentationCall(
1177 out,
1178 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001179 method);
1180 if (status != OK) {
1181 return status;
1182 }
1183
1184 out << "::android::hardware::Parcel _hidl_data;\n";
1185 out << "::android::hardware::Parcel _hidl_reply;\n";
1186 out << "::android::status_t _hidl_err;\n";
1187 out << "::android::hardware::Status _hidl_status;\n\n";
1188
1189 declareCppReaderLocals(
1190 out, method->results(), true /* forResults */);
1191
1192 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001193 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001194 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001195 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1196
Martijn Coenenfff73352017-01-04 16:36:31 +01001197 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001198 // First DFS: write all buffers and resolve pointers for parent
1199 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001200 if (arg->type().isInterface()) {
1201 hasInterfaceArgument = true;
1202 }
Yifan Hong068c5522016-10-31 14:07:25 -07001203 emitCppReaderWriter(
1204 out,
1205 "_hidl_data",
1206 false /* parcelObjIsPointer */,
1207 arg,
1208 false /* reader */,
1209 Type::ErrorMode_Goto,
1210 false /* addPrefixToName */);
1211 }
1212
1213 // Second DFS: resolve references.
1214 for (const auto &arg : method->args()) {
1215 emitCppResolveReferences(
1216 out,
1217 "_hidl_data",
1218 false /* parcelObjIsPointer */,
1219 arg,
1220 false /* reader */,
1221 Type::ErrorMode_Goto,
1222 false /* addPrefixToName */);
1223 }
1224
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001225 if (hasInterfaceArgument) {
1226 // Start binder threadpool to handle incoming transactions
1227 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1228 }
Yifan Hong068c5522016-10-31 14:07:25 -07001229 out << "_hidl_err = remote()->transact("
1230 << method->getSerialId()
1231 << " /* "
1232 << method->name()
1233 << " */, _hidl_data, &_hidl_reply";
1234
1235 if (method->isOneway()) {
1236 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1237 }
1238 out << ");\n";
1239
1240 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1241
1242 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001243 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001244 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1245 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1246
1247
1248 // First DFS: write all buffers and resolve pointers for parent
1249 for (const auto &arg : method->results()) {
1250 emitCppReaderWriter(
1251 out,
1252 "_hidl_reply",
1253 false /* parcelObjIsPointer */,
1254 arg,
1255 true /* reader */,
1256 Type::ErrorMode_Goto,
1257 true /* addPrefixToName */);
1258 }
1259
1260 // Second DFS: resolve references.
1261 for (const auto &arg : method->results()) {
1262 emitCppResolveReferences(
1263 out,
1264 "_hidl_reply",
1265 false /* parcelObjIsPointer */,
1266 arg,
1267 true /* reader */,
1268 Type::ErrorMode_Goto,
1269 true /* addPrefixToName */);
1270 }
1271
1272 if (returnsValue && elidedReturn == nullptr) {
1273 out << "_hidl_cb(";
1274
1275 bool first = true;
1276 for (const auto &arg : method->results()) {
1277 if (!first) {
1278 out << ", ";
1279 }
1280
1281 if (arg->type().resultNeedsDeref()) {
1282 out << "*";
1283 }
1284 out << "_hidl_out_" << arg->name();
1285
1286 first = false;
1287 }
1288
1289 out << ");\n\n";
1290 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001291 }
1292 status = generateCppInstrumentationCall(
1293 out,
1294 InstrumentationEvent::CLIENT_API_EXIT,
1295 method);
1296 if (status != OK) {
1297 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001298 }
1299
1300 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001301 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1302 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001303 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001304 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1305 } else {
1306 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1307 out << "return ::android::hardware::Return<void>();\n\n";
1308 }
1309
1310 out.unindent();
1311 out << "_hidl_error:\n";
1312 out.indent();
1313 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1314 out << "return ::android::hardware::Return<";
1315 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001316 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001317 } else {
1318 out << "void";
1319 }
1320 out << ">(_hidl_status);\n";
1321
1322 out.unindent();
1323 out << "}\n\n";
1324 return OK;
1325}
1326
Andreas Huber881227d2016-08-02 14:20:21 -07001327status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001328 Formatter &out, const FQName &fqName) const {
1329 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001330
1331 out << klassName
1332 << "::"
1333 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001334 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001335
1336 out.indent();
1337 out.indent();
1338
1339 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001340 << "<"
1341 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001342 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001343 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001344 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001345 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001346 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001347 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001348
Andreas Huber881227d2016-08-02 14:20:21 -07001349 out.unindent();
1350 out.unindent();
1351 out << "}\n\n";
1352
Yifan Hong068c5522016-10-31 14:07:25 -07001353 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1354 return generateProxyMethodSource(out, klassName, method, superInterface);
1355 });
Andreas Huber881227d2016-08-02 14:20:21 -07001356
Yifan Hong068c5522016-10-31 14:07:25 -07001357 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001358}
1359
1360status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001361 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001362 const Interface *iface) const {
1363 const std::string interfaceName = iface->localName();
1364 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001365
Steven Moreland40786312016-08-16 10:29:40 -07001366 out << klassName
1367 << "::"
1368 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001369 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001370
1371 out.indent();
1372 out.indent();
1373
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001374 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001375 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001376 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001377 out << ": "
1378 << gIBaseFqName.getInterfaceStubFqName().cppName()
1379 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001380 }
1381
1382 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001383 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001384 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001385 << "\") { \n";
1386 out.indent();
1387 out << "_hidl_mImpl = _hidl_impl;\n";
1388 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001389
1390 out.unindent();
1391 out.unindent();
1392 out << "}\n\n";
1393
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001394 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001395 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001396 // class properly.
1397 out << klassName
1398 << "::"
1399 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001400 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1401 << " const std::string &HidlInstrumentor_package,"
1402 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001403
1404 out.indent();
1405 out.indent();
1406
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001407 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001408 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001409 out.indent();
1410 out << "_hidl_mImpl = _hidl_impl;\n";
1411 out.unindent();
1412
1413 out.unindent();
1414 out.unindent();
1415 out << "}\n\n";
1416 }
1417
Yifan Hongbcffce22017-02-01 15:52:06 -08001418 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1419 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1420 return OK;
1421 }
1422 method->generateCppSignature(out, iface->getStubName());
1423 out << " ";
1424 out.block([&] {
1425 method->cppImpl(IMPL_STUB_IMPL, out);
1426 }).endl();
1427 return OK;
1428 });
Steven Moreland60818632017-02-04 00:33:42 -08001429 if (err != OK) {
1430 return err;
1431 }
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001432
Andreas Huber881227d2016-08-02 14:20:21 -07001433 out << "::android::status_t " << klassName << "::onTransact(\n";
1434
1435 out.indent();
1436 out.indent();
1437
Iliyan Malchev549e2592016-08-10 08:59:12 -07001438 out << "uint32_t _hidl_code,\n"
1439 << "const ::android::hardware::Parcel &_hidl_data,\n"
1440 << "::android::hardware::Parcel *_hidl_reply,\n"
1441 << "uint32_t _hidl_flags,\n"
1442 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001443
1444 out.unindent();
1445
Iliyan Malchev549e2592016-08-10 08:59:12 -07001446 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001447 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001448 out.indent();
1449
Yifan Hong10fe0b52016-10-19 14:20:17 -07001450 for (const auto &tuple : iface->allMethodsFromRoot()) {
1451 const Method *method = tuple.method();
1452 const Interface *superInterface = tuple.interface();
1453 out << "case "
1454 << method->getSerialId()
1455 << " /* "
1456 << method->name()
1457 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001458
Yifan Hong10fe0b52016-10-19 14:20:17 -07001459 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001460
Yifan Hong10fe0b52016-10-19 14:20:17 -07001461 status_t err =
1462 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001463
Yifan Hong10fe0b52016-10-19 14:20:17 -07001464 if (err != OK) {
1465 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001466 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001467
1468 out.unindent();
1469 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001470 }
1471
1472 out << "default:\n{\n";
1473 out.indent();
1474
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001475 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001476
1477 out.indent();
1478 out.indent();
1479
Iliyan Malchev549e2592016-08-10 08:59:12 -07001480 out << "_hidl_code, _hidl_data, _hidl_reply, "
1481 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001482
1483 out.unindent();
1484 out.unindent();
1485
1486 out.unindent();
1487 out << "}\n";
1488
1489 out.unindent();
1490 out << "}\n\n";
1491
Yifan Honga018ed52016-12-13 16:35:08 -08001492 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1493 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1494 out.indent(2, [&] {
1495 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1496 out << "_hidl_reply);\n";
1497 });
1498 });
Andreas Huber881227d2016-08-02 14:20:21 -07001499
Iliyan Malchev549e2592016-08-10 08:59:12 -07001500 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001501
1502 out.unindent();
1503 out << "}\n\n";
1504
1505 return OK;
1506}
1507
1508status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001509 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001510 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1511 method->cppImpl(IMPL_STUB, out);
1512 out << "break;\n";
1513 return OK;
1514 }
1515
Yifan Hongeefe4f22017-01-04 15:32:42 -08001516 out << "if (!_hidl_data.enforceInterface("
1517 << iface->fullName()
1518 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001519
Andreas Huber881227d2016-08-02 14:20:21 -07001520 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001521 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001522 out << "break;\n";
1523 out.unindent();
1524 out << "}\n\n";
1525
Andreas Huber5e44a292016-09-27 14:52:39 -07001526 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001527
Yifan Hongbf459bc2016-08-23 16:50:37 -07001528 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001529 for (const auto &arg : method->args()) {
1530 emitCppReaderWriter(
1531 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001532 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001533 false /* parcelObjIsPointer */,
1534 arg,
1535 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001536 Type::ErrorMode_Break,
1537 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001538 }
1539
Yifan Hongbf459bc2016-08-23 16:50:37 -07001540 // Second DFS: resolve references
1541 for (const auto &arg : method->args()) {
1542 emitCppResolveReferences(
1543 out,
1544 "_hidl_data",
1545 false /* parcelObjIsPointer */,
1546 arg,
1547 true /* reader */,
1548 Type::ErrorMode_Break,
1549 false /* addPrefixToName */);
1550 }
1551
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001552 status_t status = generateCppInstrumentationCall(
1553 out,
1554 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001555 method);
1556 if (status != OK) {
1557 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001558 }
1559
Andreas Huber881227d2016-08-02 14:20:21 -07001560 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001561 const TypedVar *elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -08001562 const std::string callee =
1563 (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL))
1564 ? "this" : "_hidl_mImpl";
Andreas Huber881227d2016-08-02 14:20:21 -07001565
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001566 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001567 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001568 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001569 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001570 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001571 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001572 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001573
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001574 bool first = true;
1575 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001576 if (!first) {
1577 out << ", ";
1578 }
1579
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001580 if (arg->type().resultNeedsDeref()) {
1581 out << "*";
1582 }
1583
1584 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001585
1586 first = false;
1587 }
1588
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001589 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001590 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1591 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001592
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001593 elidedReturn->type().emitReaderWriter(
1594 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001595 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001596 "_hidl_reply",
1597 true, /* parcelObjIsPointer */
1598 false, /* isReader */
1599 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001600
Yifan Hongbf459bc2016-08-23 16:50:37 -07001601 emitCppResolveReferences(
1602 out,
1603 "_hidl_reply",
1604 true /* parcelObjIsPointer */,
1605 elidedReturn,
1606 false /* reader */,
1607 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001608 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001609
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001610 status_t status = generateCppInstrumentationCall(
1611 out,
1612 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001613 method);
1614 if (status != OK) {
1615 return status;
1616 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001617
Iliyan Malchev549e2592016-08-10 08:59:12 -07001618 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001619 } else {
1620 if (returnsValue) {
1621 out << "bool _hidl_callbackCalled = false;\n\n";
1622 }
Andreas Huber881227d2016-08-02 14:20:21 -07001623
Yifan Hongcd2ae452017-01-31 14:33:40 -08001624 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001625
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001626 bool first = true;
1627 for (const auto &arg : method->args()) {
1628 if (!first) {
1629 out << ", ";
1630 }
Andreas Huber881227d2016-08-02 14:20:21 -07001631
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001632 if (arg->type().resultNeedsDeref()) {
1633 out << "*";
1634 }
1635
1636 out << arg->name();
1637
1638 first = false;
1639 }
1640
1641 if (returnsValue) {
1642 if (!first) {
1643 out << ", ";
1644 }
1645
1646 out << "[&](";
1647
1648 first = true;
1649 for (const auto &arg : method->results()) {
1650 if (!first) {
1651 out << ", ";
1652 }
1653
Yifan Honga47eef32016-12-12 10:38:54 -08001654 out << "const auto &_hidl_out_" << arg->name();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001655
1656 first = false;
1657 }
1658
1659 out << ") {\n";
1660 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001661 out << "if (_hidl_callbackCalled) {\n";
1662 out.indent();
1663 out << "LOG_ALWAYS_FATAL(\""
1664 << method->name()
1665 << ": _hidl_cb called a second time, but must be called once.\");\n";
1666 out.unindent();
1667 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001668 out << "_hidl_callbackCalled = true;\n\n";
1669
Yifan Hong859e53f2016-11-14 19:08:24 -08001670 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1671 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001672
Yifan Hongbf459bc2016-08-23 16:50:37 -07001673 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001674 for (const auto &arg : method->results()) {
1675 emitCppReaderWriter(
1676 out,
1677 "_hidl_reply",
1678 true /* parcelObjIsPointer */,
1679 arg,
1680 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001681 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001682 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001683 }
1684
Yifan Hongbf459bc2016-08-23 16:50:37 -07001685 // Second DFS: resolve references
1686 for (const auto &arg : method->results()) {
1687 emitCppResolveReferences(
1688 out,
1689 "_hidl_reply",
1690 true /* parcelObjIsPointer */,
1691 arg,
1692 false /* reader */,
1693 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001694 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001695 }
1696
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001697 status_t status = generateCppInstrumentationCall(
1698 out,
1699 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001700 method);
1701 if (status != OK) {
1702 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001703 }
1704
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001705 out << "_hidl_cb(*_hidl_reply);\n";
1706
1707 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001708 out << "});\n\n";
1709 } else {
1710 out << ");\n\n";
1711 status_t status = generateCppInstrumentationCall(
1712 out,
1713 InstrumentationEvent::SERVER_API_EXIT,
1714 method);
1715 if (status != OK) {
1716 return status;
1717 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001718 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001719
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001720 if (returnsValue) {
1721 out << "if (!_hidl_callbackCalled) {\n";
1722 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001723 out << "LOG_ALWAYS_FATAL(\""
1724 << method->name()
1725 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001726 out.unindent();
1727 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001728 } else {
1729 out << "::android::hardware::writeToParcel("
1730 << "::android::hardware::Status::ok(), "
1731 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001732 }
Andreas Huber881227d2016-08-02 14:20:21 -07001733 }
1734
1735 out << "break;\n";
1736
1737 return OK;
1738}
1739
Steven Moreland69e7c702016-09-09 11:16:32 -07001740status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1741 std::string ifaceName;
1742 if (!AST::isInterface(&ifaceName)) {
1743 // types.hal does not get a stub header.
1744 return OK;
1745 }
1746
1747 const Interface *iface = mRootScope->getInterface();
1748
Yifan Hongeefe4f22017-01-04 15:32:42 -08001749 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001750
1751 bool supportOneway = iface->hasOnewayMethods();
1752
1753 std::string path = outputPath;
1754 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1755 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1756 path.append(klassName);
1757 path.append(".h");
1758
1759 CHECK(Coordinator::MakeParentHierarchy(path));
1760 FILE *file = fopen(path.c_str(), "w");
1761
1762 if (file == NULL) {
1763 return -errno;
1764 }
1765
1766 Formatter out(file);
1767
1768 const std::string guard = makeHeaderGuard(klassName);
1769
1770 out << "#ifndef " << guard << "\n";
1771 out << "#define " << guard << "\n\n";
1772
1773 std::vector<std::string> packageComponents;
1774 getPackageAndVersionComponents(
1775 &packageComponents, false /* cpp_compatible */);
1776
Yifan Hongb0949432016-12-15 15:32:24 -08001777 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001778 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001779
1780 generateCppPackageInclude(out, mPackage, ifaceName);
1781 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001782
Yifan Hong7a118f52016-12-07 11:21:15 -08001783 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001784 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001785 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001786 }
1787
1788 enterLeaveNamespace(out, true /* enter */);
1789 out << "\n";
1790
1791 out << "struct "
1792 << klassName
1793 << " : " << ifaceName
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001794 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001795
1796 out.indent();
1797 out << "explicit "
1798 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001799 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001800 << ifaceName
1801 << "> impl);\n";
1802
Yifan Hong068c5522016-10-31 14:07:25 -07001803 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1804 return generatePassthroughMethod(out, method);
1805 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001806
1807 if (err != OK) {
1808 return err;
1809 }
1810
1811 out.unindent();
1812 out << "private:\n";
1813 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001814 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001815
1816 if (supportOneway) {
Yifan Hongef91d362017-03-20 17:18:13 -07001817 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001818
1819 out << "\n";
1820
1821 out << "::android::hardware::Return<void> addOnewayTask("
1822 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001823 }
1824
1825 out.unindent();
1826
1827 out << "};\n\n";
1828
1829 enterLeaveNamespace(out, false /* enter */);
1830
1831 out << "\n#endif // " << guard << "\n";
1832
1833 return OK;
1834}
1835
Yifan Hongfe95aa22016-10-19 17:26:45 -07001836status_t AST::generateInterfaceSource(Formatter &out) const {
1837 const Interface *iface = mRootScope->getInterface();
1838
Yifan Hong2d7126b2016-10-20 15:12:57 -07001839 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001840 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001841
Steven Morelandd4b068a2017-03-20 06:30:51 -07001842 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1843 bool reserved = method->isHidlReserved();
1844
1845 if (!reserved) {
1846 out << "// no default implementation for: ";
1847 }
1848 method->generateCppSignature(out, iface->localName());
1849 if (reserved) {
1850 out.block([&]() {
1851 method->cppImpl(IMPL_HEADER, out);
1852 }).endl();
1853 }
1854
1855 out << "\n";
1856
1857 return OK;
1858 });
1859 if (err != OK) {
1860 return err;
1861 }
1862
Yifan Hong3d746092016-12-07 14:26:33 -08001863 for (const Interface *superType : iface->typeChain()) {
1864 out << "// static \n"
1865 << childTypeResult
Yifan Hongeefe4f22017-01-04 15:32:42 -08001866 << " "
1867 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001868 << "::castFrom("
1869 << superType->getCppArgumentType()
1870 << " parent) {\n";
1871 out.indent();
1872 if (iface == superType) {
1873 out << "return parent;\n";
1874 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001875 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001876 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001877 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001878 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001879 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001880 << ">(\n";
1881 out.indent();
1882 out.indent();
1883 out << "parent, \""
1884 << iface->fqName().string()
1885 << "\");\n";
1886 out.unindent();
1887 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001888 }
Yifan Hong3d746092016-12-07 14:26:33 -08001889 out.unindent();
1890 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001891 }
1892
1893 return OK;
1894}
1895
Steven Moreland69e7c702016-09-09 11:16:32 -07001896status_t AST::generatePassthroughSource(Formatter &out) const {
1897 const Interface *iface = mRootScope->getInterface();
1898
Yifan Hongeefe4f22017-01-04 15:32:42 -08001899 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001900
1901 out << klassName
1902 << "::"
1903 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001904 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001905 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001906 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001907 << mPackage.string()
1908 << "\", \""
1909 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001910 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001911 if (iface->hasOnewayMethods()) {
1912 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001913 out.indent([&] {
Yifan Hongf01dad42017-03-20 19:03:11 -07001914 out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001915 });
1916 }
1917 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001918
1919 if (iface->hasOnewayMethods()) {
1920 out << "::android::hardware::Return<void> "
1921 << klassName
1922 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1923 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001924 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001925 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001926 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1927 out.indent();
1928 out.indent();
1929 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1930 out.unindent();
1931 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001932 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001933 out << "}\n";
1934
Steven Morelandd366c262016-10-11 15:29:10 -07001935 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001936
1937 out.unindent();
1938 out << "}\n\n";
1939
1940
1941 }
1942
1943 return OK;
1944}
1945
Martijn Coenen7b295242016-11-04 16:52:56 +01001946status_t AST::generateCppAtraceCall(Formatter &out,
1947 InstrumentationEvent event,
1948 const Method *method) const {
1949 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001950 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001951 switch (event) {
1952 case SERVER_API_ENTRY:
1953 {
1954 out << "atrace_begin(ATRACE_TAG_HAL, \""
1955 << baseString + "::server\");\n";
1956 break;
1957 }
1958 case CLIENT_API_ENTRY:
1959 {
1960 out << "atrace_begin(ATRACE_TAG_HAL, \""
1961 << baseString + "::client\");\n";
1962 break;
1963 }
1964 case PASSTHROUGH_ENTRY:
1965 {
1966 out << "atrace_begin(ATRACE_TAG_HAL, \""
1967 << baseString + "::passthrough\");\n";
1968 break;
1969 }
1970 case SERVER_API_EXIT:
1971 case CLIENT_API_EXIT:
1972 case PASSTHROUGH_EXIT:
1973 {
1974 out << "atrace_end(ATRACE_TAG_HAL);\n";
1975 break;
1976 }
1977 default:
1978 {
1979 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1980 return UNKNOWN_ERROR;
1981 }
1982 }
1983
1984 return OK;
1985}
1986
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001987status_t AST::generateCppInstrumentationCall(
1988 Formatter &out,
1989 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001990 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001991 status_t err = generateCppAtraceCall(out, event, method);
1992 if (err != OK) {
1993 return err;
1994 }
1995
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001996 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1997 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001998 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001999 std::string event_str = "";
2000 switch (event) {
2001 case SERVER_API_ENTRY:
2002 {
2003 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
2004 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002005 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002006 << (arg->type().resultNeedsDeref() ? "" : "&")
2007 << arg->name()
2008 << ");\n";
2009 }
2010 break;
2011 }
2012 case SERVER_API_EXIT:
2013 {
2014 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07002015 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002016 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07002017 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002018 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002019 }
2020 break;
2021 }
2022 case CLIENT_API_ENTRY:
2023 {
2024 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2025 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002026 out << "_hidl_args.push_back((void *)&"
2027 << arg->name()
2028 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002029 }
2030 break;
2031 }
2032 case CLIENT_API_EXIT:
2033 {
2034 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2035 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002036 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002037 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002038 << "_hidl_out_"
2039 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002040 << ");\n";
2041 }
2042 break;
2043 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002044 case PASSTHROUGH_ENTRY:
2045 {
2046 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2047 for (const auto &arg : method->args()) {
2048 out << "_hidl_args.push_back((void *)&"
2049 << arg->name()
2050 << ");\n";
2051 }
2052 break;
2053 }
2054 case PASSTHROUGH_EXIT:
2055 {
2056 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002057 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002058 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002059 << arg->name()
2060 << ");\n";
2061 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002062 break;
2063 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002064 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002065 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002066 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002067 return UNKNOWN_ERROR;
2068 }
2069 }
2070
Steven Moreland031ccf12016-10-31 15:54:38 -07002071 const Interface *iface = mRootScope->getInterface();
2072
Steven Moreland1ab31442016-11-03 18:37:51 -07002073 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002074 out.indent();
2075 out << "callback("
2076 << event_str
2077 << ", \""
2078 << mPackage.package()
2079 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002080 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002081 << "\", \""
2082 << iface->localName()
2083 << "\", \""
2084 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002085 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002086 out.unindent();
2087 out << "}\n";
2088 out.unindent();
2089 out << "}\n\n";
2090
2091 return OK;
2092}
2093
Andreas Huber881227d2016-08-02 14:20:21 -07002094} // namespace android