blob: eb5325bcdfefd311159ed9069c1e9040f415c7f1 [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()) {
759 out << " : public ::android::hardware::BBinder";
760 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 Moreland05cd4232016-11-21 16:01:12 -0800923 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100924 out << "#include <cutils/trace.h>\n";
925 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700926 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700927 // This is a no-op for IServiceManager itself.
928 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
929
Yifan Hongeefe4f22017-01-04 15:32:42 -0800930 generateCppPackageInclude(out, mPackage, iface->getProxyName());
931 generateCppPackageInclude(out, mPackage, iface->getStubName());
932 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700933
934 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700935 generateCppPackageInclude(out,
936 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800937 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700938 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800939
940 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700941 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700942 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800943 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700944 }
945
946 out << "\n";
947
948 enterLeaveNamespace(out, true /* enter */);
949 out << "\n";
950
951 status_t err = generateTypeSource(out, ifaceName);
952
953 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700954 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700955
956 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -0800957 out << "const char* "
958 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -0700959 << "::descriptor(\""
960 << iface->fqName().string()
961 << "\");\n\n";
962
Yifan Hongeefe4f22017-01-04 15:32:42 -0800963 out << "int "
964 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -0800965 << "::hidlStaticBlock = []() -> int {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800966 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800967 out << "::android::hardware::gBnConstructorMap["
968 << iface->localName()
Steven Morelandd39133b2016-11-11 12:30:08 -0800969 << "::descriptor]\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800970 out.indent(2, [&] {
Yifan Hong158655a2016-11-08 12:34:07 -0800971 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800972 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800973 out << "return new "
974 << iface->getStubName()
975 << "(reinterpret_cast<"
976 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -0800977 << " *>(iIntf));\n";
978 });
979 out << "};\n";
980 });
Yifan Hongeefe4f22017-01-04 15:32:42 -0800981 out << "::android::hardware::gBsConstructorMap["
982 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -0800983 << "::descriptor]\n";
984 out.indent(2, [&] {
985 out << "= [](void *iIntf) -> ::android::sp<"
986 << gIBaseFqName.cppName()
987 << "> {\n";
988 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800989 out << "return new "
990 << iface->getPassthroughName()
991 << "(reinterpret_cast<"
992 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -0800993 << " *>(iIntf));\n";
994 });
995 out << "};\n";
996 });
Yifan Hong158655a2016-11-08 12:34:07 -0800997 out << "return 1;\n";
998 });
999 out << "}();\n\n";
1000
Yifan Hongfe95aa22016-10-19 17:26:45 -07001001 err = generateInterfaceSource(out);
1002 }
1003
1004 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001005 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001006 }
1007
1008 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001009 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001010 }
1011
Steven Moreland40786312016-08-16 10:29:40 -07001012 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001013 err = generatePassthroughSource(out);
1014 }
1015
1016 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001017 const Interface *iface = mRootScope->getInterface();
1018
Yifan Hongc8934042016-11-17 17:10:52 -08001019 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001020 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001021 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001022 std::string package = iface->fqName().package()
1023 + iface->fqName().atVersion();
1024
Yifan Hongeefe4f22017-01-04 15:32:42 -08001025 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001026 }
Steven Moreland40786312016-08-16 10:29:40 -07001027 }
1028
Andreas Huber881227d2016-08-02 14:20:21 -07001029 enterLeaveNamespace(out, false /* enter */);
1030
1031 return err;
1032}
1033
Steven Moreland67f67b42016-09-29 08:59:02 -07001034// static
1035void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001036 out.sIf(nonNull + " == nullptr", [&] {
1037 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1038 out.indent(2, [&] {
1039 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1040 });
1041 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001042}
1043
Andreas Huber881227d2016-08-02 14:20:21 -07001044status_t AST::generateTypeSource(
1045 Formatter &out, const std::string &ifaceName) const {
1046 return mRootScope->emitTypeDefinitions(out, ifaceName);
1047}
1048
Andreas Hubere7ff2282016-08-16 13:50:03 -07001049void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001050 Formatter &out,
1051 const std::vector<TypedVar *> &args,
1052 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001053 if (args.empty()) {
1054 return;
1055 }
1056
1057 for (const auto &arg : args) {
1058 const Type &type = arg->type();
1059
Yifan Hong3b320f82016-11-01 15:15:54 -07001060 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001061 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001062 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001063 << ";\n";
1064 }
1065
1066 out << "\n";
1067}
1068
Andreas Huber881227d2016-08-02 14:20:21 -07001069void AST::emitCppReaderWriter(
1070 Formatter &out,
1071 const std::string &parcelObj,
1072 bool parcelObjIsPointer,
1073 const TypedVar *arg,
1074 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001075 Type::ErrorMode mode,
1076 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001077 const Type &type = arg->type();
1078
Andreas Huber881227d2016-08-02 14:20:21 -07001079 type.emitReaderWriter(
1080 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001081 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001082 parcelObj,
1083 parcelObjIsPointer,
1084 isReader,
1085 mode);
1086}
1087
Yifan Hongbf459bc2016-08-23 16:50:37 -07001088void AST::emitCppResolveReferences(
1089 Formatter &out,
1090 const std::string &parcelObj,
1091 bool parcelObjIsPointer,
1092 const TypedVar *arg,
1093 bool isReader,
1094 Type::ErrorMode mode,
1095 bool addPrefixToName) const {
1096 const Type &type = arg->type();
1097 if(type.needsResolveReferences()) {
1098 type.emitResolveReferences(
1099 out,
1100 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1101 isReader, // nameIsPointer
1102 parcelObj,
1103 parcelObjIsPointer,
1104 isReader,
1105 mode);
1106 }
1107}
1108
Yifan Hong068c5522016-10-31 14:07:25 -07001109status_t AST::generateProxyMethodSource(Formatter &out,
1110 const std::string &klassName,
1111 const Method *method,
1112 const Interface *superInterface) const {
1113
1114 method->generateCppSignature(out,
1115 klassName,
1116 true /* specify namespaces */);
1117
1118 const bool returnsValue = !method->results().empty();
1119 const TypedVar *elidedReturn = method->canElideCallback();
1120
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001121 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001122
1123 out.indent();
1124
Martijn Coenen115d4282016-12-19 05:14:04 +01001125 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1126 method->cppImpl(IMPL_PROXY, out);
1127 out.unindent();
1128 out << "}\n\n";
1129 return OK;
1130 }
1131
Yifan Hong068c5522016-10-31 14:07:25 -07001132 if (returnsValue && elidedReturn == nullptr) {
1133 generateCheckNonNull(out, "_hidl_cb");
1134 }
1135
1136 status_t status = generateCppInstrumentationCall(
1137 out,
1138 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001139 method);
1140 if (status != OK) {
1141 return status;
1142 }
1143
1144 out << "::android::hardware::Parcel _hidl_data;\n";
1145 out << "::android::hardware::Parcel _hidl_reply;\n";
1146 out << "::android::status_t _hidl_err;\n";
1147 out << "::android::hardware::Status _hidl_status;\n\n";
1148
1149 declareCppReaderLocals(
1150 out, method->results(), true /* forResults */);
1151
1152 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001153 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001154 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001155 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1156
Martijn Coenenfff73352017-01-04 16:36:31 +01001157 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001158 // First DFS: write all buffers and resolve pointers for parent
1159 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001160 if (arg->type().isInterface()) {
1161 hasInterfaceArgument = true;
1162 }
Yifan Hong068c5522016-10-31 14:07:25 -07001163 emitCppReaderWriter(
1164 out,
1165 "_hidl_data",
1166 false /* parcelObjIsPointer */,
1167 arg,
1168 false /* reader */,
1169 Type::ErrorMode_Goto,
1170 false /* addPrefixToName */);
1171 }
1172
1173 // Second DFS: resolve references.
1174 for (const auto &arg : method->args()) {
1175 emitCppResolveReferences(
1176 out,
1177 "_hidl_data",
1178 false /* parcelObjIsPointer */,
1179 arg,
1180 false /* reader */,
1181 Type::ErrorMode_Goto,
1182 false /* addPrefixToName */);
1183 }
1184
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001185 if (hasInterfaceArgument) {
1186 // Start binder threadpool to handle incoming transactions
1187 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1188 }
Yifan Hong068c5522016-10-31 14:07:25 -07001189 out << "_hidl_err = remote()->transact("
1190 << method->getSerialId()
1191 << " /* "
1192 << method->name()
1193 << " */, _hidl_data, &_hidl_reply";
1194
1195 if (method->isOneway()) {
1196 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1197 }
1198 out << ");\n";
1199
1200 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1201
1202 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001203 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001204 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1205 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1206
1207
1208 // First DFS: write all buffers and resolve pointers for parent
1209 for (const auto &arg : method->results()) {
1210 emitCppReaderWriter(
1211 out,
1212 "_hidl_reply",
1213 false /* parcelObjIsPointer */,
1214 arg,
1215 true /* reader */,
1216 Type::ErrorMode_Goto,
1217 true /* addPrefixToName */);
1218 }
1219
1220 // Second DFS: resolve references.
1221 for (const auto &arg : method->results()) {
1222 emitCppResolveReferences(
1223 out,
1224 "_hidl_reply",
1225 false /* parcelObjIsPointer */,
1226 arg,
1227 true /* reader */,
1228 Type::ErrorMode_Goto,
1229 true /* addPrefixToName */);
1230 }
1231
1232 if (returnsValue && elidedReturn == nullptr) {
1233 out << "_hidl_cb(";
1234
1235 bool first = true;
1236 for (const auto &arg : method->results()) {
1237 if (!first) {
1238 out << ", ";
1239 }
1240
1241 if (arg->type().resultNeedsDeref()) {
1242 out << "*";
1243 }
1244 out << "_hidl_out_" << arg->name();
1245
1246 first = false;
1247 }
1248
1249 out << ");\n\n";
1250 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001251 }
1252 status = generateCppInstrumentationCall(
1253 out,
1254 InstrumentationEvent::CLIENT_API_EXIT,
1255 method);
1256 if (status != OK) {
1257 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001258 }
1259
1260 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001261 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1262 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001263 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001264 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1265 } else {
1266 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1267 out << "return ::android::hardware::Return<void>();\n\n";
1268 }
1269
1270 out.unindent();
1271 out << "_hidl_error:\n";
1272 out.indent();
1273 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1274 out << "return ::android::hardware::Return<";
1275 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001276 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001277 } else {
1278 out << "void";
1279 }
1280 out << ">(_hidl_status);\n";
1281
1282 out.unindent();
1283 out << "}\n\n";
1284 return OK;
1285}
1286
Andreas Huber881227d2016-08-02 14:20:21 -07001287status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001288 Formatter &out, const FQName &fqName) const {
1289 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001290
1291 out << klassName
1292 << "::"
1293 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001294 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001295
1296 out.indent();
1297 out.indent();
1298
1299 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001300 << "<"
1301 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001302 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001303 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001304 << mPackage.string()
Yifan Hongeefe4f22017-01-04 15:32:42 -08001305 << "::"
1306 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001307 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001308
Andreas Huber881227d2016-08-02 14:20:21 -07001309 out.unindent();
1310 out.unindent();
1311 out << "}\n\n";
1312
Yifan Hong068c5522016-10-31 14:07:25 -07001313 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1314 return generateProxyMethodSource(out, klassName, method, superInterface);
1315 });
Andreas Huber881227d2016-08-02 14:20:21 -07001316
Yifan Hong068c5522016-10-31 14:07:25 -07001317 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001318}
1319
1320status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001321 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001322 const Interface *iface) const {
1323 const std::string interfaceName = iface->localName();
1324 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001325
Steven Moreland40786312016-08-16 10:29:40 -07001326 out << klassName
1327 << "::"
1328 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001329 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001330
1331 out.indent();
1332 out.indent();
1333
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001334 if (iface->isIBase()) {
1335 out << ": ::android::hardware::HidlInstrumentor(\"";
1336 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001337 out << ": "
1338 << gIBaseFqName.getInterfaceStubFqName().cppName()
1339 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001340 }
1341
1342 out << mPackage.string()
Yifan Hongeefe4f22017-01-04 15:32:42 -08001343 << "::"
1344 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001345 << "\") { \n";
1346 out.indent();
1347 out << "_hidl_mImpl = _hidl_impl;\n";
1348 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001349
1350 out.unindent();
1351 out.unindent();
1352 out << "}\n\n";
1353
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001354 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001355 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001356 // class properly.
1357 out << klassName
1358 << "::"
1359 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001360 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl,"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001361 << " const std::string &prefix)\n";
1362
1363 out.indent();
1364 out.indent();
1365
1366 out << ": ::android::hardware::HidlInstrumentor(prefix) { \n";
1367 out.indent();
1368 out << "_hidl_mImpl = _hidl_impl;\n";
1369 out.unindent();
1370
1371 out.unindent();
1372 out.unindent();
1373 out << "}\n\n";
1374 }
1375
1376
Andreas Huber881227d2016-08-02 14:20:21 -07001377 out << "::android::status_t " << klassName << "::onTransact(\n";
1378
1379 out.indent();
1380 out.indent();
1381
Iliyan Malchev549e2592016-08-10 08:59:12 -07001382 out << "uint32_t _hidl_code,\n"
1383 << "const ::android::hardware::Parcel &_hidl_data,\n"
1384 << "::android::hardware::Parcel *_hidl_reply,\n"
1385 << "uint32_t _hidl_flags,\n"
1386 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001387
1388 out.unindent();
1389
Iliyan Malchev549e2592016-08-10 08:59:12 -07001390 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001391 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001392 out.indent();
1393
Yifan Hong10fe0b52016-10-19 14:20:17 -07001394 for (const auto &tuple : iface->allMethodsFromRoot()) {
1395 const Method *method = tuple.method();
1396 const Interface *superInterface = tuple.interface();
1397 out << "case "
1398 << method->getSerialId()
1399 << " /* "
1400 << method->name()
1401 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001402
Yifan Hong10fe0b52016-10-19 14:20:17 -07001403 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001404
Yifan Hong10fe0b52016-10-19 14:20:17 -07001405 status_t err =
1406 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001407
Yifan Hong10fe0b52016-10-19 14:20:17 -07001408 if (err != OK) {
1409 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001410 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001411
1412 out.unindent();
1413 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001414 }
1415
1416 out << "default:\n{\n";
1417 out.indent();
1418
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001419 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001420
1421 out.indent();
1422 out.indent();
1423
Iliyan Malchev549e2592016-08-10 08:59:12 -07001424 out << "_hidl_code, _hidl_data, _hidl_reply, "
1425 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001426
1427 out.unindent();
1428 out.unindent();
1429
1430 out.unindent();
1431 out << "}\n";
1432
1433 out.unindent();
1434 out << "}\n\n";
1435
Yifan Honga018ed52016-12-13 16:35:08 -08001436 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1437 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1438 out.indent(2, [&] {
1439 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1440 out << "_hidl_reply);\n";
1441 });
1442 });
Andreas Huber881227d2016-08-02 14:20:21 -07001443
Iliyan Malchev549e2592016-08-10 08:59:12 -07001444 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001445
1446 out.unindent();
1447 out << "}\n\n";
1448
1449 return OK;
1450}
1451
1452status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001453 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001454 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1455 method->cppImpl(IMPL_STUB, out);
1456 out << "break;\n";
1457 return OK;
1458 }
1459
Yifan Hongeefe4f22017-01-04 15:32:42 -08001460 out << "if (!_hidl_data.enforceInterface("
1461 << iface->fullName()
1462 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001463
Andreas Huber881227d2016-08-02 14:20:21 -07001464 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001465 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001466 out << "break;\n";
1467 out.unindent();
1468 out << "}\n\n";
1469
Andreas Huber5e44a292016-09-27 14:52:39 -07001470 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001471
Yifan Hongbf459bc2016-08-23 16:50:37 -07001472 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001473 for (const auto &arg : method->args()) {
1474 emitCppReaderWriter(
1475 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001476 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001477 false /* parcelObjIsPointer */,
1478 arg,
1479 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001480 Type::ErrorMode_Break,
1481 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001482 }
1483
Yifan Hongbf459bc2016-08-23 16:50:37 -07001484 // Second DFS: resolve references
1485 for (const auto &arg : method->args()) {
1486 emitCppResolveReferences(
1487 out,
1488 "_hidl_data",
1489 false /* parcelObjIsPointer */,
1490 arg,
1491 true /* reader */,
1492 Type::ErrorMode_Break,
1493 false /* addPrefixToName */);
1494 }
1495
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001496 status_t status = generateCppInstrumentationCall(
1497 out,
1498 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001499 method);
1500 if (status != OK) {
1501 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001502 }
1503
Andreas Huber881227d2016-08-02 14:20:21 -07001504 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001505 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001506
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001507 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001508 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001509 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001510 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001511 << " = "
1512 << "_hidl_mImpl->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001513 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001514
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001515 bool first = true;
1516 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001517 if (!first) {
1518 out << ", ";
1519 }
1520
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001521 if (arg->type().resultNeedsDeref()) {
1522 out << "*";
1523 }
1524
1525 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001526
1527 first = false;
1528 }
1529
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001530 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001531 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1532 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001533
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001534 elidedReturn->type().emitReaderWriter(
1535 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001536 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001537 "_hidl_reply",
1538 true, /* parcelObjIsPointer */
1539 false, /* isReader */
1540 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001541
Yifan Hongbf459bc2016-08-23 16:50:37 -07001542 emitCppResolveReferences(
1543 out,
1544 "_hidl_reply",
1545 true /* parcelObjIsPointer */,
1546 elidedReturn,
1547 false /* reader */,
1548 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001549 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001550
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001551 status_t status = generateCppInstrumentationCall(
1552 out,
1553 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001554 method);
1555 if (status != OK) {
1556 return status;
1557 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001558
Iliyan Malchev549e2592016-08-10 08:59:12 -07001559 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001560 } else {
1561 if (returnsValue) {
1562 out << "bool _hidl_callbackCalled = false;\n\n";
1563 }
Andreas Huber881227d2016-08-02 14:20:21 -07001564
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001565 out << "_hidl_mImpl->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001566
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001567 bool first = true;
1568 for (const auto &arg : method->args()) {
1569 if (!first) {
1570 out << ", ";
1571 }
Andreas Huber881227d2016-08-02 14:20:21 -07001572
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001573 if (arg->type().resultNeedsDeref()) {
1574 out << "*";
1575 }
1576
1577 out << arg->name();
1578
1579 first = false;
1580 }
1581
1582 if (returnsValue) {
1583 if (!first) {
1584 out << ", ";
1585 }
1586
1587 out << "[&](";
1588
1589 first = true;
1590 for (const auto &arg : method->results()) {
1591 if (!first) {
1592 out << ", ";
1593 }
1594
Yifan Honga47eef32016-12-12 10:38:54 -08001595 out << "const auto &_hidl_out_" << arg->name();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001596
1597 first = false;
1598 }
1599
1600 out << ") {\n";
1601 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001602 out << "if (_hidl_callbackCalled) {\n";
1603 out.indent();
1604 out << "LOG_ALWAYS_FATAL(\""
1605 << method->name()
1606 << ": _hidl_cb called a second time, but must be called once.\");\n";
1607 out.unindent();
1608 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001609 out << "_hidl_callbackCalled = true;\n\n";
1610
Yifan Hong859e53f2016-11-14 19:08:24 -08001611 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1612 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001613
Yifan Hongbf459bc2016-08-23 16:50:37 -07001614 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001615 for (const auto &arg : method->results()) {
1616 emitCppReaderWriter(
1617 out,
1618 "_hidl_reply",
1619 true /* parcelObjIsPointer */,
1620 arg,
1621 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001622 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001623 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001624 }
1625
Yifan Hongbf459bc2016-08-23 16:50:37 -07001626 // Second DFS: resolve references
1627 for (const auto &arg : method->results()) {
1628 emitCppResolveReferences(
1629 out,
1630 "_hidl_reply",
1631 true /* parcelObjIsPointer */,
1632 arg,
1633 false /* reader */,
1634 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001635 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001636 }
1637
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001638 status_t status = generateCppInstrumentationCall(
1639 out,
1640 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001641 method);
1642 if (status != OK) {
1643 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001644 }
1645
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001646 out << "_hidl_cb(*_hidl_reply);\n";
1647
1648 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001649 out << "});\n\n";
1650 } else {
1651 out << ");\n\n";
1652 status_t status = generateCppInstrumentationCall(
1653 out,
1654 InstrumentationEvent::SERVER_API_EXIT,
1655 method);
1656 if (status != OK) {
1657 return status;
1658 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001659 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001660
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001661 if (returnsValue) {
1662 out << "if (!_hidl_callbackCalled) {\n";
1663 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001664 out << "LOG_ALWAYS_FATAL(\""
1665 << method->name()
1666 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001667 out.unindent();
1668 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001669 } else {
1670 out << "::android::hardware::writeToParcel("
1671 << "::android::hardware::Status::ok(), "
1672 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001673 }
Andreas Huber881227d2016-08-02 14:20:21 -07001674 }
1675
1676 out << "break;\n";
1677
1678 return OK;
1679}
1680
Steven Moreland69e7c702016-09-09 11:16:32 -07001681status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1682 std::string ifaceName;
1683 if (!AST::isInterface(&ifaceName)) {
1684 // types.hal does not get a stub header.
1685 return OK;
1686 }
1687
1688 const Interface *iface = mRootScope->getInterface();
1689
Yifan Hongeefe4f22017-01-04 15:32:42 -08001690 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001691
1692 bool supportOneway = iface->hasOnewayMethods();
1693
1694 std::string path = outputPath;
1695 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1696 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1697 path.append(klassName);
1698 path.append(".h");
1699
1700 CHECK(Coordinator::MakeParentHierarchy(path));
1701 FILE *file = fopen(path.c_str(), "w");
1702
1703 if (file == NULL) {
1704 return -errno;
1705 }
1706
1707 Formatter out(file);
1708
1709 const std::string guard = makeHeaderGuard(klassName);
1710
1711 out << "#ifndef " << guard << "\n";
1712 out << "#define " << guard << "\n\n";
1713
1714 std::vector<std::string> packageComponents;
1715 getPackageAndVersionComponents(
1716 &packageComponents, false /* cpp_compatible */);
1717
Yifan Hongb0949432016-12-15 15:32:24 -08001718 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001719 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001720
1721 generateCppPackageInclude(out, mPackage, ifaceName);
1722 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001723
Yifan Hong7a118f52016-12-07 11:21:15 -08001724 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001725 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001726 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001727 }
1728
1729 enterLeaveNamespace(out, true /* enter */);
1730 out << "\n";
1731
1732 out << "struct "
1733 << klassName
1734 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001735 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001736
1737 out.indent();
1738 out << "explicit "
1739 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001740 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001741 << ifaceName
1742 << "> impl);\n";
1743
Yifan Hong068c5522016-10-31 14:07:25 -07001744 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1745 return generatePassthroughMethod(out, method);
1746 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001747
1748 if (err != OK) {
1749 return err;
1750 }
1751
1752 out.unindent();
1753 out << "private:\n";
1754 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001755 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001756
1757 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001758 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001759
1760 out << "\n";
1761
1762 out << "::android::hardware::Return<void> addOnewayTask("
1763 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001764 }
1765
1766 out.unindent();
1767
1768 out << "};\n\n";
1769
1770 enterLeaveNamespace(out, false /* enter */);
1771
1772 out << "\n#endif // " << guard << "\n";
1773
1774 return OK;
1775}
1776
Yifan Hongfe95aa22016-10-19 17:26:45 -07001777status_t AST::generateInterfaceSource(Formatter &out) const {
1778 const Interface *iface = mRootScope->getInterface();
1779
Yifan Hong2d7126b2016-10-20 15:12:57 -07001780 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001781 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001782
Yifan Hong3d746092016-12-07 14:26:33 -08001783 for (const Interface *superType : iface->typeChain()) {
1784 out << "// static \n"
1785 << childTypeResult
Yifan Hongeefe4f22017-01-04 15:32:42 -08001786 << " "
1787 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001788 << "::castFrom("
1789 << superType->getCppArgumentType()
1790 << " parent) {\n";
1791 out.indent();
1792 if (iface == superType) {
1793 out << "return parent;\n";
1794 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001795 out << "return ::android::hardware::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001796 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001797 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001798 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001799 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001800 << ">(\n";
1801 out.indent();
1802 out.indent();
1803 out << "parent, \""
1804 << iface->fqName().string()
1805 << "\");\n";
1806 out.unindent();
1807 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001808 }
Yifan Hong3d746092016-12-07 14:26:33 -08001809 out.unindent();
1810 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001811 }
1812
1813 return OK;
1814}
1815
Steven Moreland69e7c702016-09-09 11:16:32 -07001816status_t AST::generatePassthroughSource(Formatter &out) const {
1817 const Interface *iface = mRootScope->getInterface();
1818
Yifan Hongeefe4f22017-01-04 15:32:42 -08001819 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001820
1821 out << klassName
1822 << "::"
1823 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001824 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001825 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001826 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001827 << iface->fqName().string()
1828 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001829 if (iface->hasOnewayMethods()) {
1830 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001831 out.indent([&] {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001832 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1833 });
1834 }
1835 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001836
1837 if (iface->hasOnewayMethods()) {
1838 out << "::android::hardware::Return<void> "
1839 << klassName
1840 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1841 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001842 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001843 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001844 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1845 out.indent();
1846 out.indent();
1847 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1848 out.unindent();
1849 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001850 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001851 out << "}\n";
1852
Steven Morelandd366c262016-10-11 15:29:10 -07001853 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001854
1855 out.unindent();
1856 out << "}\n\n";
1857
1858
1859 }
1860
1861 return OK;
1862}
1863
Martijn Coenen7b295242016-11-04 16:52:56 +01001864status_t AST::generateCppAtraceCall(Formatter &out,
1865 InstrumentationEvent event,
1866 const Method *method) const {
1867 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001868 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001869 switch (event) {
1870 case SERVER_API_ENTRY:
1871 {
1872 out << "atrace_begin(ATRACE_TAG_HAL, \""
1873 << baseString + "::server\");\n";
1874 break;
1875 }
1876 case CLIENT_API_ENTRY:
1877 {
1878 out << "atrace_begin(ATRACE_TAG_HAL, \""
1879 << baseString + "::client\");\n";
1880 break;
1881 }
1882 case PASSTHROUGH_ENTRY:
1883 {
1884 out << "atrace_begin(ATRACE_TAG_HAL, \""
1885 << baseString + "::passthrough\");\n";
1886 break;
1887 }
1888 case SERVER_API_EXIT:
1889 case CLIENT_API_EXIT:
1890 case PASSTHROUGH_EXIT:
1891 {
1892 out << "atrace_end(ATRACE_TAG_HAL);\n";
1893 break;
1894 }
1895 default:
1896 {
1897 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1898 return UNKNOWN_ERROR;
1899 }
1900 }
1901
1902 return OK;
1903}
1904
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001905status_t AST::generateCppInstrumentationCall(
1906 Formatter &out,
1907 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001908 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001909 status_t err = generateCppAtraceCall(out, event, method);
1910 if (err != OK) {
1911 return err;
1912 }
1913
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001914 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1915 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001916 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001917 std::string event_str = "";
1918 switch (event) {
1919 case SERVER_API_ENTRY:
1920 {
1921 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1922 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001923 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001924 << (arg->type().resultNeedsDeref() ? "" : "&")
1925 << arg->name()
1926 << ");\n";
1927 }
1928 break;
1929 }
1930 case SERVER_API_EXIT:
1931 {
1932 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001933 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001934 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001935 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001936 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001937 }
1938 break;
1939 }
1940 case CLIENT_API_ENTRY:
1941 {
1942 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1943 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001944 out << "_hidl_args.push_back((void *)&"
1945 << arg->name()
1946 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001947 }
1948 break;
1949 }
1950 case CLIENT_API_EXIT:
1951 {
1952 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1953 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001954 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001955 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001956 << "_hidl_out_"
1957 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001958 << ");\n";
1959 }
1960 break;
1961 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001962 case PASSTHROUGH_ENTRY:
1963 {
1964 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1965 for (const auto &arg : method->args()) {
1966 out << "_hidl_args.push_back((void *)&"
1967 << arg->name()
1968 << ");\n";
1969 }
1970 break;
1971 }
1972 case PASSTHROUGH_EXIT:
1973 {
1974 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001975 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001976 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001977 << arg->name()
1978 << ");\n";
1979 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001980 break;
1981 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001982 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001983 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001984 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001985 return UNKNOWN_ERROR;
1986 }
1987 }
1988
Steven Moreland031ccf12016-10-31 15:54:38 -07001989 const Interface *iface = mRootScope->getInterface();
1990
Steven Moreland1ab31442016-11-03 18:37:51 -07001991 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001992 out.indent();
1993 out << "callback("
1994 << event_str
1995 << ", \""
1996 << mPackage.package()
1997 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07001998 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001999 << "\", \""
2000 << iface->localName()
2001 << "\", \""
2002 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002003 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002004 out.unindent();
2005 out << "}\n";
2006 out.unindent();
2007 out << "}\n\n";
2008
2009 return OK;
2010}
2011
Andreas Huber881227d2016-08-02 14:20:21 -07002012} // namespace android