blob: 45edd44888d4e7ec2fca9025016bc084388a556c [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([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800161 out << "::android::sp<" << interfaceName << "> iface;\n"
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800162 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
163 out.indent(2, [&] {
164 out << "= ::android::hardware::defaultServiceManager();\n";
165 });
166 out.sIf("sm != nullptr && !getStub", [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800167 out << "::android::hardware::Return<::android::sp<" << gIBaseFqName.cppName() << ">> ret = \n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800168 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800169 out << "sm->get(\"" << package << "::" << interfaceName << "\", serviceName.c_str());\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800170 });
Steven Morelandcd00b9b2016-12-29 10:34:03 -0800171 out.sIf("ret.isOk()", [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800172 out << "iface = " << interfaceName << "::castFrom(ret);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800173 out.sIf("iface != nullptr", [&] {
174 out << "return iface;\n";
175 }).endl();
176 }).endl();
177 }).endl();
178 out << "const int dlMode = RTLD_LAZY;\n";
179 out << "void *handle = nullptr;\n";
180 for (const auto &path : std::vector<std::string>({
181 "HAL_LIBRARY_PATH_ODM", "HAL_LIBRARY_PATH_VENDOR", "HAL_LIBRARY_PATH_SYSTEM"
182 })) {
183 out.sIf("handle == nullptr", [&] {
184 out << "handle = dlopen("
185 << path << " \"" << package << "-impl.so\", dlMode);\n";
186 }).endl();
187 }
188 out.sIf("handle == nullptr", [&] {
189 out << "return iface;\n";
190 }).endl();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800191 out << "" << interfaceName << "* (*generator)(const char* name);\n"
192 << "*(void **)(&generator) = dlsym(handle, \"HIDL_FETCH_" << interfaceName << "\");\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800193 out.sIf("generator", [&] {
194 out << "iface = (*generator)(serviceName.c_str());\n";
195 out.sIf("iface != nullptr", [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800196 out << "iface = new " << fqName.getInterfacePassthroughName() << "(iface);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800197 }).endl();
198 }).endl();
199 out << "return iface;\n";
200 }).endl().endl();
201
Yifan Hongeefe4f22017-01-04 15:32:42 -0800202 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800203 << "const std::string &serviceName) ";
204 out.block([&] {
205 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
206 out.indent(2, [&] {
207 out << "= ::android::hardware::defaultServiceManager();\n";
208 });
209 out.sIf("sm == nullptr", [&] {
210 out << "return ::android::INVALID_OPERATION;\n";
211 }).endl();
212 out << "bool success = false;\n"
213 << "::android::hardware::Return<void> ret =\n";
214 out.indent(2, [&] {
215 out << "this->interfaceChain("
216 << "[&success, &sm, &serviceName, this](const auto &chain) ";
217 out.block([&] {
218 out << "::android::hardware::Return<bool> addRet = "
219 << "sm->add(chain, serviceName.c_str(), this);\n";
220 out << "success = addRet.isOk() && addRet;\n";
221 });
222 out << ");\n";
Steven Morelandcd00b9b2016-12-29 10:34:03 -0800223 out << "success = success && ret.isOk();\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800224 });
225 out << "return success ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
226 }).endl().endl();
227
Yifan Hongeefe4f22017-01-04 15:32:42 -0800228 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800229 out.indent(2, [&] {
230 out << "const std::string &serviceName,\n"
231 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
232 << "&notification) ";
233 });
234 out.block([&] {
235 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
236 out.indent(2, [&] {
237 out << "= ::android::hardware::defaultServiceManager();\n";
238 });
239 out.sIf("sm == nullptr", [&] {
240 out << "return false;\n";
241 }).endl();
242 out << "::android::hardware::Return<bool> success =\n";
243 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800244 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800245 out.indent(2, [&] {
246 out << "serviceName, notification);\n";
247 });
248 });
249 out << "return success.isOk() && success;\n";
250 }).endl().endl();
251}
252
Andreas Huberb82318c2016-08-02 14:45:54 -0700253status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700254
Andreas Huberb82318c2016-08-02 14:45:54 -0700255 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700256 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700257 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700258
259 std::string ifaceName;
260 bool isInterface = true;
261 if (!AST::isInterface(&ifaceName)) {
262 ifaceName = "types";
263 isInterface = false;
264 }
265 path.append(ifaceName);
266 path.append(".h");
267
Andreas Huberd2943e12016-08-05 11:59:31 -0700268 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700269 FILE *file = fopen(path.c_str(), "w");
270
271 if (file == NULL) {
272 return -errno;
273 }
274
275 Formatter out(file);
276
277 const std::string guard = makeHeaderGuard(ifaceName);
278
279 out << "#ifndef " << guard << "\n";
280 out << "#define " << guard << "\n\n";
281
Andreas Huber737080b2016-08-02 15:38:04 -0700282 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700283 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700284 }
285
286 if (!mImportedNames.empty()) {
287 out << "\n";
288 }
289
Steven Moreland0693f312016-11-09 15:06:14 -0800290 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800291 if (isIBase()) {
292 out << "// skipped #include IServiceNotification.h\n\n";
293 } else {
294 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
295 }
Steven Moreland0693f312016-11-09 15:06:14 -0800296 }
297
Yifan Hongc8934042016-11-17 17:10:52 -0800298 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700299 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700300
301 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200302 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700303 }
304
Martijn Coenenaf712c02016-11-16 15:26:27 +0100305 out << "#include <utils/NativeHandle.h>\n";
306 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700307
308 enterLeaveNamespace(out, true /* enter */);
309 out << "\n";
310
311 if (isInterface) {
312 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700313 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700314
315 const Interface *iface = mRootScope->getInterface();
316 const Interface *superType = iface->superType();
317
Steven Moreland40786312016-08-16 10:29:40 -0700318 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800319 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700320 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000321 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700322 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700323 }
324
325 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700326
327 out.indent();
328
Andreas Huber881227d2016-08-02 14:20:21 -0700329 }
330
331 status_t err = emitTypeDeclarations(out);
332
333 if (err != OK) {
334 return err;
335 }
336
337 if (isInterface) {
338 const Interface *iface = mRootScope->getInterface();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700339 const Interface *superType = iface->superType();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800340
Yifan Hongc8934042016-11-17 17:10:52 -0800341 out << "virtual bool isRemote() const ";
342 if (!isIBase()) {
343 out << "override ";
344 }
345 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800346
Andreas Huber881227d2016-08-02 14:20:21 -0700347 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700348 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700349
Andreas Huber881227d2016-08-02 14:20:21 -0700350 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800351 const TypedVar *elidedReturn = method->canElideCallback();
352
353 if (elidedReturn == nullptr && returnsValue) {
354 out << "using "
355 << method->name()
356 << "_cb = std::function<void("
357 << Method::GetArgSignature(method->results(),
358 true /* specify namespaces */)
359 << ")>;\n";
360 }
Andreas Huber881227d2016-08-02 14:20:21 -0700361
Andreas Huber3599d922016-08-09 10:42:57 -0700362 method->dumpAnnotations(out);
363
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700364 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700365 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700366 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700367 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700368 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700369 }
370
371 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700372 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700373 << Method::GetArgSignature(method->args(),
374 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700375
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700376 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700377 if (!method->args().empty()) {
378 out << ", ";
379 }
380
Steven Moreland67f67b42016-09-29 08:59:02 -0700381 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700382 }
383
Yifan Hong10fe0b52016-10-19 14:20:17 -0700384 out << ")";
385 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800386 if (!isIBase()) {
387 out << " override";
388 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700389 out << " {\n";
390 out.indent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100391 method->cppImpl(IMPL_HEADER, out);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700392 out.unindent();
393 out << "\n}\n";
394 } else {
395 out << " = 0;\n";
396 }
Andreas Huber881227d2016-08-02 14:20:21 -0700397 }
Steven Moreland40786312016-08-16 10:29:40 -0700398
Yifan Hong3d746092016-12-07 14:26:33 -0800399 out << "// cast static functions\n";
400 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700401
Yifan Hong3d746092016-12-07 14:26:33 -0800402 for (const Interface *superType : iface->typeChain()) {
403 out << "static "
404 << childTypeResult
405 << " castFrom("
406 << superType->getCppArgumentType()
407 << " parent"
408 << ");\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700409 }
410
Steven Morelandd39133b2016-11-11 12:30:08 -0800411 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700412
Yifan Hongc8934042016-11-17 17:10:52 -0800413 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800414 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800415 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800416 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800417 }
Yifan Hong158655a2016-11-08 12:34:07 -0800418
419 out << "private: static int hidlStaticBlock;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700420 }
421
422 if (isInterface) {
423 out.unindent();
424
Andreas Hubere3f769a2016-10-10 10:54:44 -0700425 out << "};\n\n";
426 }
427
428 err = mRootScope->emitGlobalTypeDeclarations(out);
429
430 if (err != OK) {
431 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700432 }
433
434 out << "\n";
435 enterLeaveNamespace(out, false /* enter */);
436
437 out << "\n#endif // " << guard << "\n";
438
439 return OK;
440}
441
Steven Moreland40786312016-08-16 10:29:40 -0700442status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
443 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800444 bool isInterface = AST::isInterface(&ifaceName);
445 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800446 std::string klassName{};
447
448 if(isInterface) {
449 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800450 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800451 } else {
452 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700453 }
454
Steven Moreland40786312016-08-16 10:29:40 -0700455 std::string path = outputPath;
456 path.append(mCoordinator->convertPackageRootToPath(mPackage));
457 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
458 path.append(klassName + ".h");
459
Yifan Hong244e82d2016-11-11 11:13:57 -0800460 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700461
462 if (file == NULL) {
463 return -errno;
464 }
465
466 Formatter out(file);
467
468 const std::string guard = makeHeaderGuard(klassName);
469
470 out << "#ifndef " << guard << "\n";
471 out << "#define " << guard << "\n\n";
472
Yifan Hong244e82d2016-11-11 11:13:57 -0800473 if (isInterface) {
474 generateCppPackageInclude(out, mPackage, ifaceName);
475 } else {
476 generateCppPackageInclude(out, mPackage, "types");
477 }
Steven Moreland40786312016-08-16 10:29:40 -0700478
Steven Morelandee88eed2016-10-31 17:49:00 -0700479 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700480
481 for (const auto &item : mImportedNames) {
482 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800483 generateCppPackageInclude(out, item, "hwtypes");
484 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800485 generateCppPackageInclude(out, item, item.getInterfaceStubName());
486 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700487 }
Steven Moreland40786312016-08-16 10:29:40 -0700488 }
489
490 out << "\n";
491
Martijn Coenen93915102016-09-01 01:35:52 +0200492 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700493 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100494 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700495
496 out << "\n";
497
498 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700499
Yifan Hong244e82d2016-11-11 11:13:57 -0800500 status_t err = mRootScope->emitGlobalHwDeclarations(out);
501 if (err != OK) {
502 return err;
503 }
Steven Moreland40786312016-08-16 10:29:40 -0700504
505 enterLeaveNamespace(out, false /* enter */);
506
507 out << "\n#endif // " << guard << "\n";
508
509 return OK;
510}
511
Andreas Huber881227d2016-08-02 14:20:21 -0700512status_t AST::emitTypeDeclarations(Formatter &out) const {
513 return mRootScope->emitTypeDeclarations(out);
514}
515
Yifan Hong7a118f52016-12-07 11:21:15 -0800516static void wrapPassthroughArg(Formatter &out,
517 const TypedVar *arg, bool addPrefixToName,
518 std::function<void(void)> handleError) {
519 if (!arg->type().isInterface()) {
520 return;
521 }
522 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
523 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
524 + arg->name();
525 const Interface &iface = static_cast<const Interface &>(arg->type());
526 out << iface.getCppStackType() << " " << wrappedName << ";\n";
527 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
528 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
529 out << wrappedName
530 << " = "
531 << iface.fqName().cppName()
532 << "::castFrom(::android::hardware::wrapPassthrough("
533 << name << "));\n";
534 out.sIf(wrappedName + " == nullptr", [&] {
535 // Fatal error. Happens when the BsFoo class is not found in the binary
536 // or any dynamic libraries.
537 handleError();
538 }).endl();
539 }).sElse([&] {
540 out << wrappedName << " = " << name << ";\n";
541 }).endl().endl();
542}
543
Steven Moreland69e7c702016-09-09 11:16:32 -0700544status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700545 const Method *method) const {
546 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700547
548 out << " {\n";
549 out.indent();
550
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800551 if (method->isHidlReserved()
552 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
553 method->cppImpl(IMPL_PASSTHROUGH, out);
554 out.unindent();
555 out << "}\n\n";
556 return OK;
557 }
558
Steven Moreland69e7c702016-09-09 11:16:32 -0700559 const bool returnsValue = !method->results().empty();
560 const TypedVar *elidedReturn = method->canElideCallback();
561
Steven Moreland67f67b42016-09-29 08:59:02 -0700562 if (returnsValue && elidedReturn == nullptr) {
563 generateCheckNonNull(out, "_hidl_cb");
564 }
565
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700566 generateCppInstrumentationCall(
567 out,
568 InstrumentationEvent::PASSTHROUGH_ENTRY,
569 method);
570
Yifan Hong7a118f52016-12-07 11:21:15 -0800571
572 for (const auto &arg : method->args()) {
573 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
574 out << "return ::android::hardware::Status::fromExceptionCode(\n";
575 out.indent(2, [&] {
576 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800577 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800578 });
579 });
580 }
581
582 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700583 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700584
585 if (method->isOneway()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800586 out << "addOnewayTask([this, &_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700587 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800588 out << ", "
589 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
590 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700591 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700592 out << "] {\n";
593 out.indent();
594 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700595 }
596
597 out << "mImpl->"
598 << method->name()
599 << "(";
600
601 bool first = true;
602 for (const auto &arg : method->args()) {
603 if (!first) {
604 out << ", ";
605 }
606 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800607 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700608 }
609 if (returnsValue && elidedReturn == nullptr) {
610 if (!method->args().empty()) {
611 out << ", ";
612 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800613 out << "[&](";
614 first = true;
615 for (const auto &arg : method->results()) {
616 if (!first) {
617 out << ", ";
618 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700619
Yifan Hong7a118f52016-12-07 11:21:15 -0800620 out << "const auto &_hidl_out_"
621 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800622
623 first = false;
624 }
625
626 out << ") {\n";
627 out.indent();
628 status_t status = generateCppInstrumentationCall(
629 out,
630 InstrumentationEvent::PASSTHROUGH_EXIT,
631 method);
632 if (status != OK) {
633 return status;
634 }
635
Yifan Hong7a118f52016-12-07 11:21:15 -0800636 for (const auto &arg : method->results()) {
637 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
638 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
639 out.indent(2, [&] {
640 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800641 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800642 });
643 out << "return;\n";
644 });
645 }
646
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800647 out << "_hidl_cb(";
648 first = true;
649 for (const auto &arg : method->results()) {
650 if (!first) {
651 out << ", ";
652 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800653 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800654 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
655 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800656 }
657 out << ");\n";
658 out.unindent();
659 out << "});\n\n";
660 } else {
661 out << ");\n\n";
662 if (elidedReturn != nullptr) {
663 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800664 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800665 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000666 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800667 }
668 status_t status = generateCppInstrumentationCall(
669 out,
670 InstrumentationEvent::PASSTHROUGH_EXIT,
671 method);
672 if (status != OK) {
673 return status;
674 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700675 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700676
677 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700678 out.unindent();
679 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700680 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700681
682 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700683
684 out.unindent();
685 out << "}\n";
686
687 return OK;
688}
689
Yifan Hong068c5522016-10-31 14:07:25 -0700690status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700691
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700692 const Interface *iface = mRootScope->getInterface();
693
Yifan Hong10fe0b52016-10-19 14:20:17 -0700694 const Interface *prevIterface = nullptr;
695 for (const auto &tuple : iface->allMethodsFromRoot()) {
696 const Method *method = tuple.method();
697 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700698
Yifan Hong10fe0b52016-10-19 14:20:17 -0700699 if(prevIterface != superInterface) {
700 if (prevIterface != nullptr) {
701 out << "\n";
702 }
703 out << "// Methods from "
704 << superInterface->fullName()
705 << " follow.\n";
706 prevIterface = superInterface;
707 }
Yifan Hong068c5522016-10-31 14:07:25 -0700708 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700709
Yifan Hong10fe0b52016-10-19 14:20:17 -0700710 if (err != OK) {
711 return err;
712 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700713 }
714
Yifan Hong10fe0b52016-10-19 14:20:17 -0700715 out << "\n";
716
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700717 return OK;
718}
719
Andreas Huberb82318c2016-08-02 14:45:54 -0700720status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700721 std::string ifaceName;
722 if (!AST::isInterface(&ifaceName)) {
723 // types.hal does not get a stub header.
724 return OK;
725 }
726
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700727 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800728 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700729
Andreas Huberb82318c2016-08-02 14:45:54 -0700730 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700731 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700732 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700733 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700734 path.append(".h");
735
Andreas Huberd2943e12016-08-05 11:59:31 -0700736 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700737 FILE *file = fopen(path.c_str(), "w");
738
739 if (file == NULL) {
740 return -errno;
741 }
742
743 Formatter out(file);
744
Steven Moreland40786312016-08-16 10:29:40 -0700745 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700746
747 out << "#ifndef " << guard << "\n";
748 out << "#define " << guard << "\n\n";
749
Yifan Hongeefe4f22017-01-04 15:32:42 -0800750 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700751 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700752
753 enterLeaveNamespace(out, true /* enter */);
754 out << "\n";
755
756 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800757 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100758 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800759 out << " : public ::android::hardware::BHwBinder";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100760 out << ", public ::android::hardware::HidlInstrumentor {\n";
761 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800762 out << " : public "
763 << gIBaseFqName.getInterfaceStubFqName().cppName()
764 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100765 }
Andreas Huber881227d2016-08-02 14:20:21 -0700766
767 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800768 out << "explicit "
769 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700770 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100771 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800772 out << "explicit "
773 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100774 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
775 << " const std::string& prefix);"
Steven Moreland40786312016-08-16 10:29:40 -0700776 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700777 out << "::android::status_t onTransact(\n";
778 out.indent();
779 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700780 out << "uint32_t _hidl_code,\n";
781 out << "const ::android::hardware::Parcel &_hidl_data,\n";
782 out << "::android::hardware::Parcel *_hidl_reply,\n";
783 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700784 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700785 out.unindent();
786 out.unindent();
787
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100788 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
789 out.unindent();
790 out << "private:\n";
791 out.indent();
792 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700793 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700794 out << "};\n\n";
795
796 enterLeaveNamespace(out, false /* enter */);
797
798 out << "\n#endif // " << guard << "\n";
799
800 return OK;
801}
802
Andreas Huberb82318c2016-08-02 14:45:54 -0700803status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700804 std::string ifaceName;
805 if (!AST::isInterface(&ifaceName)) {
806 // types.hal does not get a proxy header.
807 return OK;
808 }
809
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700810 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800811 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700812
Andreas Huberb82318c2016-08-02 14:45:54 -0700813 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700814 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700815 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800816 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700817 path.append(".h");
818
Andreas Huberd2943e12016-08-05 11:59:31 -0700819 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700820 FILE *file = fopen(path.c_str(), "w");
821
822 if (file == NULL) {
823 return -errno;
824 }
825
826 Formatter out(file);
827
Yifan Hongeefe4f22017-01-04 15:32:42 -0800828 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700829
830 out << "#ifndef " << guard << "\n";
831 out << "#define " << guard << "\n\n";
832
Martijn Coenen115d4282016-12-19 05:14:04 +0100833 out << "#include <hidl/HidlTransportSupport.h>\n\n";
834
Andreas Huber881227d2016-08-02 14:20:21 -0700835 std::vector<std::string> packageComponents;
836 getPackageAndVersionComponents(
837 &packageComponents, false /* cpp_compatible */);
838
Yifan Hongeefe4f22017-01-04 15:32:42 -0800839 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700840 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700841
842 enterLeaveNamespace(out, true /* enter */);
843 out << "\n";
844
845 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800846 << proxyName
847 << " : public ::android::hardware::BpInterface<"
848 << iface->localName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700849 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700850
851 out.indent();
852
Yifan Hongeefe4f22017-01-04 15:32:42 -0800853 out << "explicit "
854 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700855 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700856 << "\n\n";
857
Yifan Hong10fe0b52016-10-19 14:20:17 -0700858 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700859
Yifan Hong068c5522016-10-31 14:07:25 -0700860 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
861 method->generateCppSignature(out);
862 out << " override;\n";
863 return OK;
864 });
Steven Moreland9c387612016-09-07 09:54:26 -0700865
866 if (err != OK) {
867 return err;
868 }
Andreas Huber881227d2016-08-02 14:20:21 -0700869
870 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100871 out << "private:\n";
872 out.indent();
873 out << "std::mutex _hidl_mMutex;\n"
874 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
875 << " _hidl_mDeathRecipients;\n";
876 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700877 out << "};\n\n";
878
879 enterLeaveNamespace(out, false /* enter */);
880
881 out << "\n#endif // " << guard << "\n";
882
883 return OK;
884}
885
Andreas Huberb82318c2016-08-02 14:45:54 -0700886status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700887
Andreas Huberb82318c2016-08-02 14:45:54 -0700888 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700889 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700890 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700891
892 std::string ifaceName;
893 std::string baseName;
894
Yifan Hongfe95aa22016-10-19 17:26:45 -0700895 const Interface *iface = nullptr;
896 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700897 if (!AST::isInterface(&ifaceName)) {
898 baseName = "types";
899 isInterface = false;
900 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700901 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700902 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700903 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700904 }
905
906 path.append(baseName);
907
908 if (baseName != "types") {
909 path.append("All");
910 }
911
912 path.append(".cpp");
913
Andreas Huberd2943e12016-08-05 11:59:31 -0700914 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700915 FILE *file = fopen(path.c_str(), "w");
916
917 if (file == NULL) {
918 return -errno;
919 }
920
921 Formatter out(file);
922
Steven Moreland623c0042017-01-13 14:42:29 -0800923 out << "#define LOG_TAG \""
924 << mPackage.string() << "::" << baseName
925 << "\"\n\n";
926
Steven Moreland05cd4232016-11-21 16:01:12 -0800927 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100928 out << "#include <cutils/trace.h>\n";
929 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700930 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700931 // This is a no-op for IServiceManager itself.
932 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
933
Yifan Hongeefe4f22017-01-04 15:32:42 -0800934 generateCppPackageInclude(out, mPackage, iface->getProxyName());
935 generateCppPackageInclude(out, mPackage, iface->getStubName());
936 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700937
938 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700939 generateCppPackageInclude(out,
940 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800941 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700942 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800943
944 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700945 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700946 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800947 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700948 }
949
950 out << "\n";
951
952 enterLeaveNamespace(out, true /* enter */);
953 out << "\n";
954
955 status_t err = generateTypeSource(out, ifaceName);
956
957 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700958 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700959
960 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -0800961 out << "const char* "
962 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -0700963 << "::descriptor(\""
964 << iface->fqName().string()
965 << "\");\n\n";
966
Yifan Hongeefe4f22017-01-04 15:32:42 -0800967 out << "int "
968 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -0800969 << "::hidlStaticBlock = []() -> int {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800970 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800971 out << "::android::hardware::gBnConstructorMap["
972 << iface->localName()
Steven Morelandd39133b2016-11-11 12:30:08 -0800973 << "::descriptor]\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800974 out.indent(2, [&] {
Yifan Hong158655a2016-11-08 12:34:07 -0800975 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800976 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800977 out << "return new "
978 << iface->getStubName()
979 << "(reinterpret_cast<"
980 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -0800981 << " *>(iIntf));\n";
982 });
983 out << "};\n";
984 });
Yifan Hongeefe4f22017-01-04 15:32:42 -0800985 out << "::android::hardware::gBsConstructorMap["
986 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -0800987 << "::descriptor]\n";
988 out.indent(2, [&] {
989 out << "= [](void *iIntf) -> ::android::sp<"
990 << gIBaseFqName.cppName()
991 << "> {\n";
992 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800993 out << "return new "
994 << iface->getPassthroughName()
995 << "(reinterpret_cast<"
996 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -0800997 << " *>(iIntf));\n";
998 });
999 out << "};\n";
1000 });
Yifan Hong158655a2016-11-08 12:34:07 -08001001 out << "return 1;\n";
1002 });
1003 out << "}();\n\n";
1004
Yifan Hongfe95aa22016-10-19 17:26:45 -07001005 err = generateInterfaceSource(out);
1006 }
1007
1008 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001009 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001010 }
1011
1012 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001013 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001014 }
1015
Steven Moreland40786312016-08-16 10:29:40 -07001016 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001017 err = generatePassthroughSource(out);
1018 }
1019
1020 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001021 const Interface *iface = mRootScope->getInterface();
1022
Yifan Hongc8934042016-11-17 17:10:52 -08001023 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001024 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001025 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001026 std::string package = iface->fqName().package()
1027 + iface->fqName().atVersion();
1028
Yifan Hongeefe4f22017-01-04 15:32:42 -08001029 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001030 }
Steven Moreland40786312016-08-16 10:29:40 -07001031 }
1032
Andreas Huber881227d2016-08-02 14:20:21 -07001033 enterLeaveNamespace(out, false /* enter */);
1034
1035 return err;
1036}
1037
Steven Moreland67f67b42016-09-29 08:59:02 -07001038// static
1039void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001040 out.sIf(nonNull + " == nullptr", [&] {
1041 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1042 out.indent(2, [&] {
1043 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1044 });
1045 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001046}
1047
Andreas Huber881227d2016-08-02 14:20:21 -07001048status_t AST::generateTypeSource(
1049 Formatter &out, const std::string &ifaceName) const {
1050 return mRootScope->emitTypeDefinitions(out, ifaceName);
1051}
1052
Andreas Hubere7ff2282016-08-16 13:50:03 -07001053void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001054 Formatter &out,
1055 const std::vector<TypedVar *> &args,
1056 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001057 if (args.empty()) {
1058 return;
1059 }
1060
1061 for (const auto &arg : args) {
1062 const Type &type = arg->type();
1063
Yifan Hong3b320f82016-11-01 15:15:54 -07001064 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001065 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001066 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001067 << ";\n";
1068 }
1069
1070 out << "\n";
1071}
1072
Andreas Huber881227d2016-08-02 14:20:21 -07001073void AST::emitCppReaderWriter(
1074 Formatter &out,
1075 const std::string &parcelObj,
1076 bool parcelObjIsPointer,
1077 const TypedVar *arg,
1078 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001079 Type::ErrorMode mode,
1080 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001081 const Type &type = arg->type();
1082
Andreas Huber881227d2016-08-02 14:20:21 -07001083 type.emitReaderWriter(
1084 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001085 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001086 parcelObj,
1087 parcelObjIsPointer,
1088 isReader,
1089 mode);
1090}
1091
Yifan Hongbf459bc2016-08-23 16:50:37 -07001092void AST::emitCppResolveReferences(
1093 Formatter &out,
1094 const std::string &parcelObj,
1095 bool parcelObjIsPointer,
1096 const TypedVar *arg,
1097 bool isReader,
1098 Type::ErrorMode mode,
1099 bool addPrefixToName) const {
1100 const Type &type = arg->type();
1101 if(type.needsResolveReferences()) {
1102 type.emitResolveReferences(
1103 out,
1104 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1105 isReader, // nameIsPointer
1106 parcelObj,
1107 parcelObjIsPointer,
1108 isReader,
1109 mode);
1110 }
1111}
1112
Yifan Hong068c5522016-10-31 14:07:25 -07001113status_t AST::generateProxyMethodSource(Formatter &out,
1114 const std::string &klassName,
1115 const Method *method,
1116 const Interface *superInterface) const {
1117
1118 method->generateCppSignature(out,
1119 klassName,
1120 true /* specify namespaces */);
1121
1122 const bool returnsValue = !method->results().empty();
1123 const TypedVar *elidedReturn = method->canElideCallback();
1124
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001125 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001126
1127 out.indent();
1128
Martijn Coenen115d4282016-12-19 05:14:04 +01001129 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1130 method->cppImpl(IMPL_PROXY, out);
1131 out.unindent();
1132 out << "}\n\n";
1133 return OK;
1134 }
1135
Yifan Hong068c5522016-10-31 14:07:25 -07001136 if (returnsValue && elidedReturn == nullptr) {
1137 generateCheckNonNull(out, "_hidl_cb");
1138 }
1139
1140 status_t status = generateCppInstrumentationCall(
1141 out,
1142 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001143 method);
1144 if (status != OK) {
1145 return status;
1146 }
1147
1148 out << "::android::hardware::Parcel _hidl_data;\n";
1149 out << "::android::hardware::Parcel _hidl_reply;\n";
1150 out << "::android::status_t _hidl_err;\n";
1151 out << "::android::hardware::Status _hidl_status;\n\n";
1152
1153 declareCppReaderLocals(
1154 out, method->results(), true /* forResults */);
1155
1156 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001157 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001158 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001159 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1160
Martijn Coenenfff73352017-01-04 16:36:31 +01001161 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001162 // First DFS: write all buffers and resolve pointers for parent
1163 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001164 if (arg->type().isInterface()) {
1165 hasInterfaceArgument = true;
1166 }
Yifan Hong068c5522016-10-31 14:07:25 -07001167 emitCppReaderWriter(
1168 out,
1169 "_hidl_data",
1170 false /* parcelObjIsPointer */,
1171 arg,
1172 false /* reader */,
1173 Type::ErrorMode_Goto,
1174 false /* addPrefixToName */);
1175 }
1176
1177 // Second DFS: resolve references.
1178 for (const auto &arg : method->args()) {
1179 emitCppResolveReferences(
1180 out,
1181 "_hidl_data",
1182 false /* parcelObjIsPointer */,
1183 arg,
1184 false /* reader */,
1185 Type::ErrorMode_Goto,
1186 false /* addPrefixToName */);
1187 }
1188
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001189 if (hasInterfaceArgument) {
1190 // Start binder threadpool to handle incoming transactions
1191 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1192 }
Yifan Hong068c5522016-10-31 14:07:25 -07001193 out << "_hidl_err = remote()->transact("
1194 << method->getSerialId()
1195 << " /* "
1196 << method->name()
1197 << " */, _hidl_data, &_hidl_reply";
1198
1199 if (method->isOneway()) {
1200 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1201 }
1202 out << ");\n";
1203
1204 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1205
1206 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001207 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001208 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1209 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1210
1211
1212 // First DFS: write all buffers and resolve pointers for parent
1213 for (const auto &arg : method->results()) {
1214 emitCppReaderWriter(
1215 out,
1216 "_hidl_reply",
1217 false /* parcelObjIsPointer */,
1218 arg,
1219 true /* reader */,
1220 Type::ErrorMode_Goto,
1221 true /* addPrefixToName */);
1222 }
1223
1224 // Second DFS: resolve references.
1225 for (const auto &arg : method->results()) {
1226 emitCppResolveReferences(
1227 out,
1228 "_hidl_reply",
1229 false /* parcelObjIsPointer */,
1230 arg,
1231 true /* reader */,
1232 Type::ErrorMode_Goto,
1233 true /* addPrefixToName */);
1234 }
1235
1236 if (returnsValue && elidedReturn == nullptr) {
1237 out << "_hidl_cb(";
1238
1239 bool first = true;
1240 for (const auto &arg : method->results()) {
1241 if (!first) {
1242 out << ", ";
1243 }
1244
1245 if (arg->type().resultNeedsDeref()) {
1246 out << "*";
1247 }
1248 out << "_hidl_out_" << arg->name();
1249
1250 first = false;
1251 }
1252
1253 out << ");\n\n";
1254 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001255 }
1256 status = generateCppInstrumentationCall(
1257 out,
1258 InstrumentationEvent::CLIENT_API_EXIT,
1259 method);
1260 if (status != OK) {
1261 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001262 }
1263
1264 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001265 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1266 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001267 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001268 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1269 } else {
1270 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1271 out << "return ::android::hardware::Return<void>();\n\n";
1272 }
1273
1274 out.unindent();
1275 out << "_hidl_error:\n";
1276 out.indent();
1277 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1278 out << "return ::android::hardware::Return<";
1279 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001280 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001281 } else {
1282 out << "void";
1283 }
1284 out << ">(_hidl_status);\n";
1285
1286 out.unindent();
1287 out << "}\n\n";
1288 return OK;
1289}
1290
Andreas Huber881227d2016-08-02 14:20:21 -07001291status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001292 Formatter &out, const FQName &fqName) const {
1293 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001294
1295 out << klassName
1296 << "::"
1297 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001298 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001299
1300 out.indent();
1301 out.indent();
1302
1303 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001304 << "<"
1305 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001306 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001307 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001308 << mPackage.string()
Yifan Hongeefe4f22017-01-04 15:32:42 -08001309 << "::"
1310 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001311 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001312
Andreas Huber881227d2016-08-02 14:20:21 -07001313 out.unindent();
1314 out.unindent();
1315 out << "}\n\n";
1316
Yifan Hong068c5522016-10-31 14:07:25 -07001317 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1318 return generateProxyMethodSource(out, klassName, method, superInterface);
1319 });
Andreas Huber881227d2016-08-02 14:20:21 -07001320
Yifan Hong068c5522016-10-31 14:07:25 -07001321 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001322}
1323
1324status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001325 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001326 const Interface *iface) const {
1327 const std::string interfaceName = iface->localName();
1328 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001329
Steven Moreland40786312016-08-16 10:29:40 -07001330 out << klassName
1331 << "::"
1332 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001333 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001334
1335 out.indent();
1336 out.indent();
1337
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001338 if (iface->isIBase()) {
1339 out << ": ::android::hardware::HidlInstrumentor(\"";
1340 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001341 out << ": "
1342 << gIBaseFqName.getInterfaceStubFqName().cppName()
1343 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001344 }
1345
1346 out << mPackage.string()
Yifan Hongeefe4f22017-01-04 15:32:42 -08001347 << "::"
1348 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001349 << "\") { \n";
1350 out.indent();
1351 out << "_hidl_mImpl = _hidl_impl;\n";
1352 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001353
1354 out.unindent();
1355 out.unindent();
1356 out << "}\n\n";
1357
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001358 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001359 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001360 // class properly.
1361 out << klassName
1362 << "::"
1363 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001364 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl,"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001365 << " const std::string &prefix)\n";
1366
1367 out.indent();
1368 out.indent();
1369
1370 out << ": ::android::hardware::HidlInstrumentor(prefix) { \n";
1371 out.indent();
1372 out << "_hidl_mImpl = _hidl_impl;\n";
1373 out.unindent();
1374
1375 out.unindent();
1376 out.unindent();
1377 out << "}\n\n";
1378 }
1379
1380
Andreas Huber881227d2016-08-02 14:20:21 -07001381 out << "::android::status_t " << klassName << "::onTransact(\n";
1382
1383 out.indent();
1384 out.indent();
1385
Iliyan Malchev549e2592016-08-10 08:59:12 -07001386 out << "uint32_t _hidl_code,\n"
1387 << "const ::android::hardware::Parcel &_hidl_data,\n"
1388 << "::android::hardware::Parcel *_hidl_reply,\n"
1389 << "uint32_t _hidl_flags,\n"
1390 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001391
1392 out.unindent();
1393
Iliyan Malchev549e2592016-08-10 08:59:12 -07001394 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001395 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001396 out.indent();
1397
Yifan Hong10fe0b52016-10-19 14:20:17 -07001398 for (const auto &tuple : iface->allMethodsFromRoot()) {
1399 const Method *method = tuple.method();
1400 const Interface *superInterface = tuple.interface();
1401 out << "case "
1402 << method->getSerialId()
1403 << " /* "
1404 << method->name()
1405 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001406
Yifan Hong10fe0b52016-10-19 14:20:17 -07001407 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001408
Yifan Hong10fe0b52016-10-19 14:20:17 -07001409 status_t err =
1410 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001411
Yifan Hong10fe0b52016-10-19 14:20:17 -07001412 if (err != OK) {
1413 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001414 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001415
1416 out.unindent();
1417 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001418 }
1419
1420 out << "default:\n{\n";
1421 out.indent();
1422
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001423 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001424
1425 out.indent();
1426 out.indent();
1427
Iliyan Malchev549e2592016-08-10 08:59:12 -07001428 out << "_hidl_code, _hidl_data, _hidl_reply, "
1429 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001430
1431 out.unindent();
1432 out.unindent();
1433
1434 out.unindent();
1435 out << "}\n";
1436
1437 out.unindent();
1438 out << "}\n\n";
1439
Yifan Honga018ed52016-12-13 16:35:08 -08001440 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1441 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1442 out.indent(2, [&] {
1443 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1444 out << "_hidl_reply);\n";
1445 });
1446 });
Andreas Huber881227d2016-08-02 14:20:21 -07001447
Iliyan Malchev549e2592016-08-10 08:59:12 -07001448 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001449
1450 out.unindent();
1451 out << "}\n\n";
1452
1453 return OK;
1454}
1455
1456status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001457 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001458 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1459 method->cppImpl(IMPL_STUB, out);
1460 out << "break;\n";
1461 return OK;
1462 }
1463
Yifan Hongeefe4f22017-01-04 15:32:42 -08001464 out << "if (!_hidl_data.enforceInterface("
1465 << iface->fullName()
1466 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001467
Andreas Huber881227d2016-08-02 14:20:21 -07001468 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001469 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001470 out << "break;\n";
1471 out.unindent();
1472 out << "}\n\n";
1473
Andreas Huber5e44a292016-09-27 14:52:39 -07001474 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001475
Yifan Hongbf459bc2016-08-23 16:50:37 -07001476 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001477 for (const auto &arg : method->args()) {
1478 emitCppReaderWriter(
1479 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001480 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001481 false /* parcelObjIsPointer */,
1482 arg,
1483 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001484 Type::ErrorMode_Break,
1485 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001486 }
1487
Yifan Hongbf459bc2016-08-23 16:50:37 -07001488 // Second DFS: resolve references
1489 for (const auto &arg : method->args()) {
1490 emitCppResolveReferences(
1491 out,
1492 "_hidl_data",
1493 false /* parcelObjIsPointer */,
1494 arg,
1495 true /* reader */,
1496 Type::ErrorMode_Break,
1497 false /* addPrefixToName */);
1498 }
1499
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001500 status_t status = generateCppInstrumentationCall(
1501 out,
1502 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001503 method);
1504 if (status != OK) {
1505 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001506 }
1507
Andreas Huber881227d2016-08-02 14:20:21 -07001508 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001509 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001510
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001511 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001512 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001513 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001514 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001515 << " = "
1516 << "_hidl_mImpl->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001517 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001518
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001519 bool first = true;
1520 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001521 if (!first) {
1522 out << ", ";
1523 }
1524
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001525 if (arg->type().resultNeedsDeref()) {
1526 out << "*";
1527 }
1528
1529 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001530
1531 first = false;
1532 }
1533
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001534 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001535 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1536 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001537
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001538 elidedReturn->type().emitReaderWriter(
1539 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001540 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001541 "_hidl_reply",
1542 true, /* parcelObjIsPointer */
1543 false, /* isReader */
1544 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001545
Yifan Hongbf459bc2016-08-23 16:50:37 -07001546 emitCppResolveReferences(
1547 out,
1548 "_hidl_reply",
1549 true /* parcelObjIsPointer */,
1550 elidedReturn,
1551 false /* reader */,
1552 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001553 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001554
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001555 status_t status = generateCppInstrumentationCall(
1556 out,
1557 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001558 method);
1559 if (status != OK) {
1560 return status;
1561 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001562
Iliyan Malchev549e2592016-08-10 08:59:12 -07001563 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001564 } else {
1565 if (returnsValue) {
1566 out << "bool _hidl_callbackCalled = false;\n\n";
1567 }
Andreas Huber881227d2016-08-02 14:20:21 -07001568
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001569 out << "_hidl_mImpl->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001570
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001571 bool first = true;
1572 for (const auto &arg : method->args()) {
1573 if (!first) {
1574 out << ", ";
1575 }
Andreas Huber881227d2016-08-02 14:20:21 -07001576
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001577 if (arg->type().resultNeedsDeref()) {
1578 out << "*";
1579 }
1580
1581 out << arg->name();
1582
1583 first = false;
1584 }
1585
1586 if (returnsValue) {
1587 if (!first) {
1588 out << ", ";
1589 }
1590
1591 out << "[&](";
1592
1593 first = true;
1594 for (const auto &arg : method->results()) {
1595 if (!first) {
1596 out << ", ";
1597 }
1598
Yifan Honga47eef32016-12-12 10:38:54 -08001599 out << "const auto &_hidl_out_" << arg->name();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001600
1601 first = false;
1602 }
1603
1604 out << ") {\n";
1605 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001606 out << "if (_hidl_callbackCalled) {\n";
1607 out.indent();
1608 out << "LOG_ALWAYS_FATAL(\""
1609 << method->name()
1610 << ": _hidl_cb called a second time, but must be called once.\");\n";
1611 out.unindent();
1612 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001613 out << "_hidl_callbackCalled = true;\n\n";
1614
Yifan Hong859e53f2016-11-14 19:08:24 -08001615 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1616 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001617
Yifan Hongbf459bc2016-08-23 16:50:37 -07001618 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001619 for (const auto &arg : method->results()) {
1620 emitCppReaderWriter(
1621 out,
1622 "_hidl_reply",
1623 true /* parcelObjIsPointer */,
1624 arg,
1625 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001626 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001627 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001628 }
1629
Yifan Hongbf459bc2016-08-23 16:50:37 -07001630 // Second DFS: resolve references
1631 for (const auto &arg : method->results()) {
1632 emitCppResolveReferences(
1633 out,
1634 "_hidl_reply",
1635 true /* parcelObjIsPointer */,
1636 arg,
1637 false /* reader */,
1638 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001639 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001640 }
1641
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001642 status_t status = generateCppInstrumentationCall(
1643 out,
1644 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001645 method);
1646 if (status != OK) {
1647 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001648 }
1649
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001650 out << "_hidl_cb(*_hidl_reply);\n";
1651
1652 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001653 out << "});\n\n";
1654 } else {
1655 out << ");\n\n";
1656 status_t status = generateCppInstrumentationCall(
1657 out,
1658 InstrumentationEvent::SERVER_API_EXIT,
1659 method);
1660 if (status != OK) {
1661 return status;
1662 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001663 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001664
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001665 if (returnsValue) {
1666 out << "if (!_hidl_callbackCalled) {\n";
1667 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001668 out << "LOG_ALWAYS_FATAL(\""
1669 << method->name()
1670 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001671 out.unindent();
1672 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001673 } else {
1674 out << "::android::hardware::writeToParcel("
1675 << "::android::hardware::Status::ok(), "
1676 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001677 }
Andreas Huber881227d2016-08-02 14:20:21 -07001678 }
1679
1680 out << "break;\n";
1681
1682 return OK;
1683}
1684
Steven Moreland69e7c702016-09-09 11:16:32 -07001685status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1686 std::string ifaceName;
1687 if (!AST::isInterface(&ifaceName)) {
1688 // types.hal does not get a stub header.
1689 return OK;
1690 }
1691
1692 const Interface *iface = mRootScope->getInterface();
1693
Yifan Hongeefe4f22017-01-04 15:32:42 -08001694 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001695
1696 bool supportOneway = iface->hasOnewayMethods();
1697
1698 std::string path = outputPath;
1699 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1700 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1701 path.append(klassName);
1702 path.append(".h");
1703
1704 CHECK(Coordinator::MakeParentHierarchy(path));
1705 FILE *file = fopen(path.c_str(), "w");
1706
1707 if (file == NULL) {
1708 return -errno;
1709 }
1710
1711 Formatter out(file);
1712
1713 const std::string guard = makeHeaderGuard(klassName);
1714
1715 out << "#ifndef " << guard << "\n";
1716 out << "#define " << guard << "\n\n";
1717
1718 std::vector<std::string> packageComponents;
1719 getPackageAndVersionComponents(
1720 &packageComponents, false /* cpp_compatible */);
1721
Yifan Hongb0949432016-12-15 15:32:24 -08001722 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001723 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001724
1725 generateCppPackageInclude(out, mPackage, ifaceName);
1726 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001727
Yifan Hong7a118f52016-12-07 11:21:15 -08001728 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001729 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001730 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001731 }
1732
1733 enterLeaveNamespace(out, true /* enter */);
1734 out << "\n";
1735
1736 out << "struct "
1737 << klassName
1738 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001739 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001740
1741 out.indent();
1742 out << "explicit "
1743 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001744 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001745 << ifaceName
1746 << "> impl);\n";
1747
Yifan Hong068c5522016-10-31 14:07:25 -07001748 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1749 return generatePassthroughMethod(out, method);
1750 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001751
1752 if (err != OK) {
1753 return err;
1754 }
1755
1756 out.unindent();
1757 out << "private:\n";
1758 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001759 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001760
1761 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001762 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001763
1764 out << "\n";
1765
1766 out << "::android::hardware::Return<void> addOnewayTask("
1767 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001768 }
1769
1770 out.unindent();
1771
1772 out << "};\n\n";
1773
1774 enterLeaveNamespace(out, false /* enter */);
1775
1776 out << "\n#endif // " << guard << "\n";
1777
1778 return OK;
1779}
1780
Yifan Hongfe95aa22016-10-19 17:26:45 -07001781status_t AST::generateInterfaceSource(Formatter &out) const {
1782 const Interface *iface = mRootScope->getInterface();
1783
Yifan Hong2d7126b2016-10-20 15:12:57 -07001784 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001785 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001786
Yifan Hong3d746092016-12-07 14:26:33 -08001787 for (const Interface *superType : iface->typeChain()) {
1788 out << "// static \n"
1789 << childTypeResult
Yifan Hongeefe4f22017-01-04 15:32:42 -08001790 << " "
1791 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001792 << "::castFrom("
1793 << superType->getCppArgumentType()
1794 << " parent) {\n";
1795 out.indent();
1796 if (iface == superType) {
1797 out << "return parent;\n";
1798 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001799 out << "return ::android::hardware::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001800 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001801 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001802 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001803 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001804 << ">(\n";
1805 out.indent();
1806 out.indent();
1807 out << "parent, \""
1808 << iface->fqName().string()
1809 << "\");\n";
1810 out.unindent();
1811 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001812 }
Yifan Hong3d746092016-12-07 14:26:33 -08001813 out.unindent();
1814 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001815 }
1816
1817 return OK;
1818}
1819
Steven Moreland69e7c702016-09-09 11:16:32 -07001820status_t AST::generatePassthroughSource(Formatter &out) const {
1821 const Interface *iface = mRootScope->getInterface();
1822
Yifan Hongeefe4f22017-01-04 15:32:42 -08001823 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001824
1825 out << klassName
1826 << "::"
1827 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001828 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001829 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001830 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001831 << iface->fqName().string()
1832 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001833 if (iface->hasOnewayMethods()) {
1834 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001835 out.indent([&] {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001836 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1837 });
1838 }
1839 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001840
1841 if (iface->hasOnewayMethods()) {
1842 out << "::android::hardware::Return<void> "
1843 << klassName
1844 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1845 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001846 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001847 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001848 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1849 out.indent();
1850 out.indent();
1851 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1852 out.unindent();
1853 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001854 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001855 out << "}\n";
1856
Steven Morelandd366c262016-10-11 15:29:10 -07001857 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001858
1859 out.unindent();
1860 out << "}\n\n";
1861
1862
1863 }
1864
1865 return OK;
1866}
1867
Martijn Coenen7b295242016-11-04 16:52:56 +01001868status_t AST::generateCppAtraceCall(Formatter &out,
1869 InstrumentationEvent event,
1870 const Method *method) const {
1871 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001872 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001873 switch (event) {
1874 case SERVER_API_ENTRY:
1875 {
1876 out << "atrace_begin(ATRACE_TAG_HAL, \""
1877 << baseString + "::server\");\n";
1878 break;
1879 }
1880 case CLIENT_API_ENTRY:
1881 {
1882 out << "atrace_begin(ATRACE_TAG_HAL, \""
1883 << baseString + "::client\");\n";
1884 break;
1885 }
1886 case PASSTHROUGH_ENTRY:
1887 {
1888 out << "atrace_begin(ATRACE_TAG_HAL, \""
1889 << baseString + "::passthrough\");\n";
1890 break;
1891 }
1892 case SERVER_API_EXIT:
1893 case CLIENT_API_EXIT:
1894 case PASSTHROUGH_EXIT:
1895 {
1896 out << "atrace_end(ATRACE_TAG_HAL);\n";
1897 break;
1898 }
1899 default:
1900 {
1901 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1902 return UNKNOWN_ERROR;
1903 }
1904 }
1905
1906 return OK;
1907}
1908
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001909status_t AST::generateCppInstrumentationCall(
1910 Formatter &out,
1911 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001912 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001913 status_t err = generateCppAtraceCall(out, event, method);
1914 if (err != OK) {
1915 return err;
1916 }
1917
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001918 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1919 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001920 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001921 std::string event_str = "";
1922 switch (event) {
1923 case SERVER_API_ENTRY:
1924 {
1925 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1926 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001927 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001928 << (arg->type().resultNeedsDeref() ? "" : "&")
1929 << arg->name()
1930 << ");\n";
1931 }
1932 break;
1933 }
1934 case SERVER_API_EXIT:
1935 {
1936 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001937 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001938 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001939 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001940 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001941 }
1942 break;
1943 }
1944 case CLIENT_API_ENTRY:
1945 {
1946 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1947 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001948 out << "_hidl_args.push_back((void *)&"
1949 << arg->name()
1950 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001951 }
1952 break;
1953 }
1954 case CLIENT_API_EXIT:
1955 {
1956 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1957 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001958 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001959 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001960 << "_hidl_out_"
1961 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001962 << ");\n";
1963 }
1964 break;
1965 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001966 case PASSTHROUGH_ENTRY:
1967 {
1968 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1969 for (const auto &arg : method->args()) {
1970 out << "_hidl_args.push_back((void *)&"
1971 << arg->name()
1972 << ");\n";
1973 }
1974 break;
1975 }
1976 case PASSTHROUGH_EXIT:
1977 {
1978 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001979 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001980 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001981 << arg->name()
1982 << ");\n";
1983 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001984 break;
1985 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001986 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001987 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001988 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001989 return UNKNOWN_ERROR;
1990 }
1991 }
1992
Steven Moreland031ccf12016-10-31 15:54:38 -07001993 const Interface *iface = mRootScope->getInterface();
1994
Steven Moreland1ab31442016-11-03 18:37:51 -07001995 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001996 out.indent();
1997 out << "callback("
1998 << event_str
1999 << ", \""
2000 << mPackage.package()
2001 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002002 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002003 << "\", \""
2004 << iface->localName()
2005 << "\", \""
2006 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002007 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002008 out.unindent();
2009 out << "}\n";
2010 out.unindent();
2011 out << "}\n\n";
2012
2013 return OK;
2014}
2015
Andreas Huber881227d2016-08-02 14:20:21 -07002016} // namespace android