blob: adde77de7d2c45e8ce46dda37b17165d513a69a0 [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("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800130 << "const std::string &serviceName, bool getStub=false);\n";
131 out << "::android::status_t registerAsService(const std::string &serviceName);\n";
132 out << "static bool registerForNotifications(\n";
133 out.indent(2, [&] {
134 out << "const std::string &serviceName,\n"
135 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
136 << "&notification);\n";
137 });
138
139}
140
141static void implementServiceManagerInteractions(Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -0800142 const FQName &fqName, const std::string &package) {
143
144 const std::string interfaceName = fqName.getInterfaceName();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800145
146 out << "// static\n"
Yifan Hongeefe4f22017-01-04 15:32:42 -0800147 << "::android::sp<" << interfaceName << "> " << interfaceName << "::getService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800148 << "const std::string &serviceName, bool getStub) ";
149 out.block([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800150 out << "::android::sp<" << interfaceName << "> iface;\n"
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800151 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
152 out.indent(2, [&] {
153 out << "= ::android::hardware::defaultServiceManager();\n";
154 });
155 out.sIf("sm != nullptr && !getStub", [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800156 out << "::android::hardware::Return<::android::sp<" << gIBaseFqName.cppName() << ">> ret = \n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800157 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800158 out << "sm->get(\"" << package << "::" << interfaceName << "\", serviceName.c_str());\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800159 });
Steven Morelandcd00b9b2016-12-29 10:34:03 -0800160 out.sIf("ret.isOk()", [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800161 out << "iface = " << interfaceName << "::castFrom(ret);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800162 out.sIf("iface != nullptr", [&] {
163 out << "return iface;\n";
164 }).endl();
165 }).endl();
166 }).endl();
167 out << "const int dlMode = RTLD_LAZY;\n";
168 out << "void *handle = nullptr;\n";
169 for (const auto &path : std::vector<std::string>({
170 "HAL_LIBRARY_PATH_ODM", "HAL_LIBRARY_PATH_VENDOR", "HAL_LIBRARY_PATH_SYSTEM"
171 })) {
172 out.sIf("handle == nullptr", [&] {
173 out << "handle = dlopen("
174 << path << " \"" << package << "-impl.so\", dlMode);\n";
175 }).endl();
176 }
177 out.sIf("handle == nullptr", [&] {
178 out << "return iface;\n";
179 }).endl();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800180 out << "" << interfaceName << "* (*generator)(const char* name);\n"
181 << "*(void **)(&generator) = dlsym(handle, \"HIDL_FETCH_" << interfaceName << "\");\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800182 out.sIf("generator", [&] {
183 out << "iface = (*generator)(serviceName.c_str());\n";
184 out.sIf("iface != nullptr", [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800185 out << "iface = new " << fqName.getInterfacePassthroughName() << "(iface);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800186 }).endl();
187 }).endl();
188 out << "return iface;\n";
189 }).endl().endl();
190
Yifan Hongeefe4f22017-01-04 15:32:42 -0800191 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800192 << "const std::string &serviceName) ";
193 out.block([&] {
194 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
195 out.indent(2, [&] {
196 out << "= ::android::hardware::defaultServiceManager();\n";
197 });
198 out.sIf("sm == nullptr", [&] {
199 out << "return ::android::INVALID_OPERATION;\n";
200 }).endl();
201 out << "bool success = false;\n"
202 << "::android::hardware::Return<void> ret =\n";
203 out.indent(2, [&] {
204 out << "this->interfaceChain("
205 << "[&success, &sm, &serviceName, this](const auto &chain) ";
206 out.block([&] {
207 out << "::android::hardware::Return<bool> addRet = "
208 << "sm->add(chain, serviceName.c_str(), this);\n";
209 out << "success = addRet.isOk() && addRet;\n";
210 });
211 out << ");\n";
Steven Morelandcd00b9b2016-12-29 10:34:03 -0800212 out << "success = success && ret.isOk();\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800213 });
214 out << "return success ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
215 }).endl().endl();
216
Yifan Hongeefe4f22017-01-04 15:32:42 -0800217 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800218 out.indent(2, [&] {
219 out << "const std::string &serviceName,\n"
220 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
221 << "&notification) ";
222 });
223 out.block([&] {
224 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
225 out.indent(2, [&] {
226 out << "= ::android::hardware::defaultServiceManager();\n";
227 });
228 out.sIf("sm == nullptr", [&] {
229 out << "return false;\n";
230 }).endl();
231 out << "::android::hardware::Return<bool> success =\n";
232 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800233 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800234 out.indent(2, [&] {
235 out << "serviceName, notification);\n";
236 });
237 });
238 out << "return success.isOk() && success;\n";
239 }).endl().endl();
240}
241
Andreas Huberb82318c2016-08-02 14:45:54 -0700242status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700243
Andreas Huberb82318c2016-08-02 14:45:54 -0700244 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700245 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700246 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700247
248 std::string ifaceName;
249 bool isInterface = true;
250 if (!AST::isInterface(&ifaceName)) {
251 ifaceName = "types";
252 isInterface = false;
253 }
254 path.append(ifaceName);
255 path.append(".h");
256
Andreas Huberd2943e12016-08-05 11:59:31 -0700257 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700258 FILE *file = fopen(path.c_str(), "w");
259
260 if (file == NULL) {
261 return -errno;
262 }
263
264 Formatter out(file);
265
266 const std::string guard = makeHeaderGuard(ifaceName);
267
268 out << "#ifndef " << guard << "\n";
269 out << "#define " << guard << "\n\n";
270
Andreas Huber737080b2016-08-02 15:38:04 -0700271 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700272 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700273 }
274
275 if (!mImportedNames.empty()) {
276 out << "\n";
277 }
278
Steven Moreland0693f312016-11-09 15:06:14 -0800279 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800280 if (isIBase()) {
281 out << "// skipped #include IServiceNotification.h\n\n";
282 } else {
283 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
284 }
Steven Moreland0693f312016-11-09 15:06:14 -0800285 }
286
Yifan Hongc8934042016-11-17 17:10:52 -0800287 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700288 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700289
290 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200291 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700292 }
293
Martijn Coenenaf712c02016-11-16 15:26:27 +0100294 out << "#include <utils/NativeHandle.h>\n";
295 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700296
297 enterLeaveNamespace(out, true /* enter */);
298 out << "\n";
299
300 if (isInterface) {
301 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700302 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700303
304 const Interface *iface = mRootScope->getInterface();
305 const Interface *superType = iface->superType();
306
Steven Moreland40786312016-08-16 10:29:40 -0700307 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800308 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700309 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000310 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700311 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700312 }
313
314 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700315
316 out.indent();
317
Andreas Huber881227d2016-08-02 14:20:21 -0700318 }
319
320 status_t err = emitTypeDeclarations(out);
321
322 if (err != OK) {
323 return err;
324 }
325
326 if (isInterface) {
327 const Interface *iface = mRootScope->getInterface();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700328 const Interface *superType = iface->superType();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800329
Yifan Hongc8934042016-11-17 17:10:52 -0800330 out << "virtual bool isRemote() const ";
331 if (!isIBase()) {
332 out << "override ";
333 }
334 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800335
Andreas Huber881227d2016-08-02 14:20:21 -0700336 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700337 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700338
Andreas Huber881227d2016-08-02 14:20:21 -0700339 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800340 const TypedVar *elidedReturn = method->canElideCallback();
341
342 if (elidedReturn == nullptr && returnsValue) {
343 out << "using "
344 << method->name()
345 << "_cb = std::function<void("
346 << Method::GetArgSignature(method->results(),
347 true /* specify namespaces */)
348 << ")>;\n";
349 }
Andreas Huber881227d2016-08-02 14:20:21 -0700350
Andreas Huber3599d922016-08-09 10:42:57 -0700351 method->dumpAnnotations(out);
352
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700353 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700354 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700355 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700356 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700357 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700358 }
359
360 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700361 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700362 << Method::GetArgSignature(method->args(),
363 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700364
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700365 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700366 if (!method->args().empty()) {
367 out << ", ";
368 }
369
Steven Moreland67f67b42016-09-29 08:59:02 -0700370 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700371 }
372
Yifan Hong10fe0b52016-10-19 14:20:17 -0700373 out << ")";
374 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800375 if (!isIBase()) {
376 out << " override";
377 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700378 out << " {\n";
379 out.indent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100380 method->cppImpl(IMPL_HEADER, out);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700381 out.unindent();
382 out << "\n}\n";
383 } else {
384 out << " = 0;\n";
385 }
Andreas Huber881227d2016-08-02 14:20:21 -0700386 }
Steven Moreland40786312016-08-16 10:29:40 -0700387
Yifan Hong3d746092016-12-07 14:26:33 -0800388 out << "// cast static functions\n";
389 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700390
Yifan Hong3d746092016-12-07 14:26:33 -0800391 for (const Interface *superType : iface->typeChain()) {
392 out << "static "
393 << childTypeResult
394 << " castFrom("
395 << superType->getCppArgumentType()
396 << " parent"
397 << ");\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700398 }
399
Steven Morelandd39133b2016-11-11 12:30:08 -0800400 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700401
Yifan Hongc8934042016-11-17 17:10:52 -0800402 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800403 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800404 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800405 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800406 }
Yifan Hong158655a2016-11-08 12:34:07 -0800407
408 out << "private: static int hidlStaticBlock;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700409 }
410
411 if (isInterface) {
412 out.unindent();
413
Andreas Hubere3f769a2016-10-10 10:54:44 -0700414 out << "};\n\n";
415 }
416
417 err = mRootScope->emitGlobalTypeDeclarations(out);
418
419 if (err != OK) {
420 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700421 }
422
423 out << "\n";
424 enterLeaveNamespace(out, false /* enter */);
425
426 out << "\n#endif // " << guard << "\n";
427
428 return OK;
429}
430
Steven Moreland40786312016-08-16 10:29:40 -0700431status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
432 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800433 bool isInterface = AST::isInterface(&ifaceName);
434 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800435 std::string klassName{};
436
437 if(isInterface) {
438 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800439 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800440 } else {
441 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700442 }
443
Steven Moreland40786312016-08-16 10:29:40 -0700444 std::string path = outputPath;
445 path.append(mCoordinator->convertPackageRootToPath(mPackage));
446 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
447 path.append(klassName + ".h");
448
Yifan Hong244e82d2016-11-11 11:13:57 -0800449 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700450
451 if (file == NULL) {
452 return -errno;
453 }
454
455 Formatter out(file);
456
457 const std::string guard = makeHeaderGuard(klassName);
458
459 out << "#ifndef " << guard << "\n";
460 out << "#define " << guard << "\n\n";
461
Yifan Hong244e82d2016-11-11 11:13:57 -0800462 if (isInterface) {
463 generateCppPackageInclude(out, mPackage, ifaceName);
464 } else {
465 generateCppPackageInclude(out, mPackage, "types");
466 }
Steven Moreland40786312016-08-16 10:29:40 -0700467
Steven Morelandee88eed2016-10-31 17:49:00 -0700468 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700469
470 for (const auto &item : mImportedNames) {
471 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800472 generateCppPackageInclude(out, item, "hwtypes");
473 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800474 generateCppPackageInclude(out, item, item.getInterfaceStubName());
475 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700476 }
Steven Moreland40786312016-08-16 10:29:40 -0700477 }
478
479 out << "\n";
480
Martijn Coenen93915102016-09-01 01:35:52 +0200481 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700482 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100483 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700484
485 out << "\n";
486
487 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700488
Yifan Hong244e82d2016-11-11 11:13:57 -0800489 status_t err = mRootScope->emitGlobalHwDeclarations(out);
490 if (err != OK) {
491 return err;
492 }
Steven Moreland40786312016-08-16 10:29:40 -0700493
494 enterLeaveNamespace(out, false /* enter */);
495
496 out << "\n#endif // " << guard << "\n";
497
498 return OK;
499}
500
Andreas Huber881227d2016-08-02 14:20:21 -0700501status_t AST::emitTypeDeclarations(Formatter &out) const {
502 return mRootScope->emitTypeDeclarations(out);
503}
504
Yifan Hong7a118f52016-12-07 11:21:15 -0800505static void wrapPassthroughArg(Formatter &out,
506 const TypedVar *arg, bool addPrefixToName,
507 std::function<void(void)> handleError) {
508 if (!arg->type().isInterface()) {
509 return;
510 }
511 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
512 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
513 + arg->name();
514 const Interface &iface = static_cast<const Interface &>(arg->type());
515 out << iface.getCppStackType() << " " << wrappedName << ";\n";
516 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
517 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
518 out << wrappedName
519 << " = "
520 << iface.fqName().cppName()
521 << "::castFrom(::android::hardware::wrapPassthrough("
522 << name << "));\n";
523 out.sIf(wrappedName + " == nullptr", [&] {
524 // Fatal error. Happens when the BsFoo class is not found in the binary
525 // or any dynamic libraries.
526 handleError();
527 }).endl();
528 }).sElse([&] {
529 out << wrappedName << " = " << name << ";\n";
530 }).endl().endl();
531}
532
Steven Moreland69e7c702016-09-09 11:16:32 -0700533status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700534 const Method *method) const {
535 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700536
537 out << " {\n";
538 out.indent();
539
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800540 if (method->isHidlReserved()
541 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
542 method->cppImpl(IMPL_PASSTHROUGH, out);
543 out.unindent();
544 out << "}\n\n";
545 return OK;
546 }
547
Steven Moreland69e7c702016-09-09 11:16:32 -0700548 const bool returnsValue = !method->results().empty();
549 const TypedVar *elidedReturn = method->canElideCallback();
550
Steven Moreland67f67b42016-09-29 08:59:02 -0700551 if (returnsValue && elidedReturn == nullptr) {
552 generateCheckNonNull(out, "_hidl_cb");
553 }
554
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700555 generateCppInstrumentationCall(
556 out,
557 InstrumentationEvent::PASSTHROUGH_ENTRY,
558 method);
559
Yifan Hong7a118f52016-12-07 11:21:15 -0800560
561 for (const auto &arg : method->args()) {
562 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
563 out << "return ::android::hardware::Status::fromExceptionCode(\n";
564 out.indent(2, [&] {
565 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800566 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800567 });
568 });
569 }
570
571 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700572 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700573
574 if (method->isOneway()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800575 out << "addOnewayTask([this, &_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700576 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800577 out << ", "
578 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
579 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700580 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700581 out << "] {\n";
582 out.indent();
583 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700584 }
585
586 out << "mImpl->"
587 << method->name()
588 << "(";
589
590 bool first = true;
591 for (const auto &arg : method->args()) {
592 if (!first) {
593 out << ", ";
594 }
595 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800596 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700597 }
598 if (returnsValue && elidedReturn == nullptr) {
599 if (!method->args().empty()) {
600 out << ", ";
601 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800602 out << "[&](";
603 first = true;
604 for (const auto &arg : method->results()) {
605 if (!first) {
606 out << ", ";
607 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700608
Yifan Hong7a118f52016-12-07 11:21:15 -0800609 out << "const auto &_hidl_out_"
610 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800611
612 first = false;
613 }
614
615 out << ") {\n";
616 out.indent();
617 status_t status = generateCppInstrumentationCall(
618 out,
619 InstrumentationEvent::PASSTHROUGH_EXIT,
620 method);
621 if (status != OK) {
622 return status;
623 }
624
Yifan Hong7a118f52016-12-07 11:21:15 -0800625 for (const auto &arg : method->results()) {
626 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
627 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
628 out.indent(2, [&] {
629 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800630 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800631 });
632 out << "return;\n";
633 });
634 }
635
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800636 out << "_hidl_cb(";
637 first = true;
638 for (const auto &arg : method->results()) {
639 if (!first) {
640 out << ", ";
641 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800642 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800643 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
644 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800645 }
646 out << ");\n";
647 out.unindent();
648 out << "});\n\n";
649 } else {
650 out << ");\n\n";
651 if (elidedReturn != nullptr) {
652 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800653 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800654 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000655 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800656 }
657 status_t status = generateCppInstrumentationCall(
658 out,
659 InstrumentationEvent::PASSTHROUGH_EXIT,
660 method);
661 if (status != OK) {
662 return status;
663 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700664 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700665
666 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700667 out.unindent();
668 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700669 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700670
671 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700672
673 out.unindent();
674 out << "}\n";
675
676 return OK;
677}
678
Yifan Hong068c5522016-10-31 14:07:25 -0700679status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700680
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700681 const Interface *iface = mRootScope->getInterface();
682
Yifan Hong10fe0b52016-10-19 14:20:17 -0700683 const Interface *prevIterface = nullptr;
684 for (const auto &tuple : iface->allMethodsFromRoot()) {
685 const Method *method = tuple.method();
686 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700687
Yifan Hong10fe0b52016-10-19 14:20:17 -0700688 if(prevIterface != superInterface) {
689 if (prevIterface != nullptr) {
690 out << "\n";
691 }
692 out << "// Methods from "
693 << superInterface->fullName()
694 << " follow.\n";
695 prevIterface = superInterface;
696 }
Yifan Hong068c5522016-10-31 14:07:25 -0700697 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700698
Yifan Hong10fe0b52016-10-19 14:20:17 -0700699 if (err != OK) {
700 return err;
701 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700702 }
703
Yifan Hong10fe0b52016-10-19 14:20:17 -0700704 out << "\n";
705
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700706 return OK;
707}
708
Andreas Huberb82318c2016-08-02 14:45:54 -0700709status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700710 std::string ifaceName;
711 if (!AST::isInterface(&ifaceName)) {
712 // types.hal does not get a stub header.
713 return OK;
714 }
715
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700716 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800717 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700718
Andreas Huberb82318c2016-08-02 14:45:54 -0700719 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700720 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700721 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700722 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700723 path.append(".h");
724
Andreas Huberd2943e12016-08-05 11:59:31 -0700725 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700726 FILE *file = fopen(path.c_str(), "w");
727
728 if (file == NULL) {
729 return -errno;
730 }
731
732 Formatter out(file);
733
Steven Moreland40786312016-08-16 10:29:40 -0700734 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700735
736 out << "#ifndef " << guard << "\n";
737 out << "#define " << guard << "\n\n";
738
Yifan Hongeefe4f22017-01-04 15:32:42 -0800739 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700740 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700741
742 enterLeaveNamespace(out, true /* enter */);
743 out << "\n";
744
745 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800746 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100747 if (iface->isIBase()) {
748 out << " : public ::android::hardware::BBinder";
749 out << ", public ::android::hardware::HidlInstrumentor {\n";
750 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800751 out << " : public "
752 << gIBaseFqName.getInterfaceStubFqName().cppName()
753 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100754 }
Andreas Huber881227d2016-08-02 14:20:21 -0700755
756 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800757 out << "explicit "
758 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700759 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100760 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800761 out << "explicit "
762 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100763 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
764 << " const std::string& prefix);"
Steven Moreland40786312016-08-16 10:29:40 -0700765 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700766 out << "::android::status_t onTransact(\n";
767 out.indent();
768 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700769 out << "uint32_t _hidl_code,\n";
770 out << "const ::android::hardware::Parcel &_hidl_data,\n";
771 out << "::android::hardware::Parcel *_hidl_reply,\n";
772 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700773 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700774 out.unindent();
775 out.unindent();
776
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100777 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
778 out.unindent();
779 out << "private:\n";
780 out.indent();
781 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700782 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700783 out << "};\n\n";
784
785 enterLeaveNamespace(out, false /* enter */);
786
787 out << "\n#endif // " << guard << "\n";
788
789 return OK;
790}
791
Andreas Huberb82318c2016-08-02 14:45:54 -0700792status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700793 std::string ifaceName;
794 if (!AST::isInterface(&ifaceName)) {
795 // types.hal does not get a proxy header.
796 return OK;
797 }
798
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700799 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800800 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700801
Andreas Huberb82318c2016-08-02 14:45:54 -0700802 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700803 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700804 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800805 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700806 path.append(".h");
807
Andreas Huberd2943e12016-08-05 11:59:31 -0700808 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700809 FILE *file = fopen(path.c_str(), "w");
810
811 if (file == NULL) {
812 return -errno;
813 }
814
815 Formatter out(file);
816
Yifan Hongeefe4f22017-01-04 15:32:42 -0800817 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700818
819 out << "#ifndef " << guard << "\n";
820 out << "#define " << guard << "\n\n";
821
Martijn Coenen115d4282016-12-19 05:14:04 +0100822 out << "#include <hidl/HidlTransportSupport.h>\n\n";
823
Andreas Huber881227d2016-08-02 14:20:21 -0700824 std::vector<std::string> packageComponents;
825 getPackageAndVersionComponents(
826 &packageComponents, false /* cpp_compatible */);
827
Yifan Hongeefe4f22017-01-04 15:32:42 -0800828 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700829 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700830
831 enterLeaveNamespace(out, true /* enter */);
832 out << "\n";
833
834 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800835 << proxyName
836 << " : public ::android::hardware::BpInterface<"
837 << iface->localName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700838 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700839
840 out.indent();
841
Yifan Hongeefe4f22017-01-04 15:32:42 -0800842 out << "explicit "
843 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700844 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700845 << "\n\n";
846
Yifan Hong10fe0b52016-10-19 14:20:17 -0700847 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700848
Yifan Hong068c5522016-10-31 14:07:25 -0700849 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
850 method->generateCppSignature(out);
851 out << " override;\n";
852 return OK;
853 });
Steven Moreland9c387612016-09-07 09:54:26 -0700854
855 if (err != OK) {
856 return err;
857 }
Andreas Huber881227d2016-08-02 14:20:21 -0700858
859 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100860 out << "private:\n";
861 out.indent();
862 out << "std::mutex _hidl_mMutex;\n"
863 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
864 << " _hidl_mDeathRecipients;\n";
865 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700866 out << "};\n\n";
867
868 enterLeaveNamespace(out, false /* enter */);
869
870 out << "\n#endif // " << guard << "\n";
871
872 return OK;
873}
874
Andreas Huberb82318c2016-08-02 14:45:54 -0700875status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700876
Andreas Huberb82318c2016-08-02 14:45:54 -0700877 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700878 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700879 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700880
881 std::string ifaceName;
882 std::string baseName;
883
Yifan Hongfe95aa22016-10-19 17:26:45 -0700884 const Interface *iface = nullptr;
885 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700886 if (!AST::isInterface(&ifaceName)) {
887 baseName = "types";
888 isInterface = false;
889 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700890 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700891 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700892 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700893 }
894
895 path.append(baseName);
896
897 if (baseName != "types") {
898 path.append("All");
899 }
900
901 path.append(".cpp");
902
Andreas Huberd2943e12016-08-05 11:59:31 -0700903 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700904 FILE *file = fopen(path.c_str(), "w");
905
906 if (file == NULL) {
907 return -errno;
908 }
909
910 Formatter out(file);
911
Steven Moreland05cd4232016-11-21 16:01:12 -0800912 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100913 out << "#include <cutils/trace.h>\n";
914 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700915 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700916 // This is a no-op for IServiceManager itself.
917 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
918
Yifan Hongeefe4f22017-01-04 15:32:42 -0800919 generateCppPackageInclude(out, mPackage, iface->getProxyName());
920 generateCppPackageInclude(out, mPackage, iface->getStubName());
921 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700922
923 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700924 generateCppPackageInclude(out,
925 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800926 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700927 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800928
929 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700930 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700931 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800932 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700933 }
934
935 out << "\n";
936
937 enterLeaveNamespace(out, true /* enter */);
938 out << "\n";
939
940 status_t err = generateTypeSource(out, ifaceName);
941
942 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700943 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700944
945 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -0800946 out << "const char* "
947 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -0700948 << "::descriptor(\""
949 << iface->fqName().string()
950 << "\");\n\n";
951
Yifan Hongeefe4f22017-01-04 15:32:42 -0800952 out << "int "
953 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -0800954 << "::hidlStaticBlock = []() -> int {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800955 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800956 out << "::android::hardware::gBnConstructorMap["
957 << iface->localName()
Steven Morelandd39133b2016-11-11 12:30:08 -0800958 << "::descriptor]\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800959 out.indent(2, [&] {
Yifan Hong158655a2016-11-08 12:34:07 -0800960 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800961 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800962 out << "return new "
963 << iface->getStubName()
964 << "(reinterpret_cast<"
965 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -0800966 << " *>(iIntf));\n";
967 });
968 out << "};\n";
969 });
Yifan Hongeefe4f22017-01-04 15:32:42 -0800970 out << "::android::hardware::gBsConstructorMap["
971 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -0800972 << "::descriptor]\n";
973 out.indent(2, [&] {
974 out << "= [](void *iIntf) -> ::android::sp<"
975 << gIBaseFqName.cppName()
976 << "> {\n";
977 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800978 out << "return new "
979 << iface->getPassthroughName()
980 << "(reinterpret_cast<"
981 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -0800982 << " *>(iIntf));\n";
983 });
984 out << "};\n";
985 });
Yifan Hong158655a2016-11-08 12:34:07 -0800986 out << "return 1;\n";
987 });
988 out << "}();\n\n";
989
Yifan Hongfe95aa22016-10-19 17:26:45 -0700990 err = generateInterfaceSource(out);
991 }
992
993 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800994 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -0700995 }
996
997 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800998 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -0700999 }
1000
Steven Moreland40786312016-08-16 10:29:40 -07001001 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001002 err = generatePassthroughSource(out);
1003 }
1004
1005 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001006 const Interface *iface = mRootScope->getInterface();
1007
Yifan Hongc8934042016-11-17 17:10:52 -08001008 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001009 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001010 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001011 std::string package = iface->fqName().package()
1012 + iface->fqName().atVersion();
1013
Yifan Hongeefe4f22017-01-04 15:32:42 -08001014 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001015 }
Steven Moreland40786312016-08-16 10:29:40 -07001016 }
1017
Andreas Huber881227d2016-08-02 14:20:21 -07001018 enterLeaveNamespace(out, false /* enter */);
1019
1020 return err;
1021}
1022
Steven Moreland67f67b42016-09-29 08:59:02 -07001023// static
1024void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001025 out.sIf(nonNull + " == nullptr", [&] {
1026 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1027 out.indent(2, [&] {
1028 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1029 });
1030 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001031}
1032
Andreas Huber881227d2016-08-02 14:20:21 -07001033status_t AST::generateTypeSource(
1034 Formatter &out, const std::string &ifaceName) const {
1035 return mRootScope->emitTypeDefinitions(out, ifaceName);
1036}
1037
Andreas Hubere7ff2282016-08-16 13:50:03 -07001038void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001039 Formatter &out,
1040 const std::vector<TypedVar *> &args,
1041 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001042 if (args.empty()) {
1043 return;
1044 }
1045
1046 for (const auto &arg : args) {
1047 const Type &type = arg->type();
1048
Yifan Hong3b320f82016-11-01 15:15:54 -07001049 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001050 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001051 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001052 << ";\n";
1053 }
1054
1055 out << "\n";
1056}
1057
Andreas Huber881227d2016-08-02 14:20:21 -07001058void AST::emitCppReaderWriter(
1059 Formatter &out,
1060 const std::string &parcelObj,
1061 bool parcelObjIsPointer,
1062 const TypedVar *arg,
1063 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001064 Type::ErrorMode mode,
1065 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001066 const Type &type = arg->type();
1067
Andreas Huber881227d2016-08-02 14:20:21 -07001068 type.emitReaderWriter(
1069 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001070 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001071 parcelObj,
1072 parcelObjIsPointer,
1073 isReader,
1074 mode);
1075}
1076
Yifan Hongbf459bc2016-08-23 16:50:37 -07001077void AST::emitCppResolveReferences(
1078 Formatter &out,
1079 const std::string &parcelObj,
1080 bool parcelObjIsPointer,
1081 const TypedVar *arg,
1082 bool isReader,
1083 Type::ErrorMode mode,
1084 bool addPrefixToName) const {
1085 const Type &type = arg->type();
1086 if(type.needsResolveReferences()) {
1087 type.emitResolveReferences(
1088 out,
1089 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1090 isReader, // nameIsPointer
1091 parcelObj,
1092 parcelObjIsPointer,
1093 isReader,
1094 mode);
1095 }
1096}
1097
Yifan Hong068c5522016-10-31 14:07:25 -07001098status_t AST::generateProxyMethodSource(Formatter &out,
1099 const std::string &klassName,
1100 const Method *method,
1101 const Interface *superInterface) const {
1102
1103 method->generateCppSignature(out,
1104 klassName,
1105 true /* specify namespaces */);
1106
1107 const bool returnsValue = !method->results().empty();
1108 const TypedVar *elidedReturn = method->canElideCallback();
1109
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001110 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001111
1112 out.indent();
1113
Martijn Coenen115d4282016-12-19 05:14:04 +01001114 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1115 method->cppImpl(IMPL_PROXY, out);
1116 out.unindent();
1117 out << "}\n\n";
1118 return OK;
1119 }
1120
Yifan Hong068c5522016-10-31 14:07:25 -07001121 if (returnsValue && elidedReturn == nullptr) {
1122 generateCheckNonNull(out, "_hidl_cb");
1123 }
1124
1125 status_t status = generateCppInstrumentationCall(
1126 out,
1127 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001128 method);
1129 if (status != OK) {
1130 return status;
1131 }
1132
1133 out << "::android::hardware::Parcel _hidl_data;\n";
1134 out << "::android::hardware::Parcel _hidl_reply;\n";
1135 out << "::android::status_t _hidl_err;\n";
1136 out << "::android::hardware::Status _hidl_status;\n\n";
1137
1138 declareCppReaderLocals(
1139 out, method->results(), true /* forResults */);
1140
1141 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001142 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001143 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001144 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1145
Martijn Coenenfff73352017-01-04 16:36:31 +01001146 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001147 // First DFS: write all buffers and resolve pointers for parent
1148 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001149 if (arg->type().isInterface()) {
1150 hasInterfaceArgument = true;
1151 }
Yifan Hong068c5522016-10-31 14:07:25 -07001152 emitCppReaderWriter(
1153 out,
1154 "_hidl_data",
1155 false /* parcelObjIsPointer */,
1156 arg,
1157 false /* reader */,
1158 Type::ErrorMode_Goto,
1159 false /* addPrefixToName */);
1160 }
1161
1162 // Second DFS: resolve references.
1163 for (const auto &arg : method->args()) {
1164 emitCppResolveReferences(
1165 out,
1166 "_hidl_data",
1167 false /* parcelObjIsPointer */,
1168 arg,
1169 false /* reader */,
1170 Type::ErrorMode_Goto,
1171 false /* addPrefixToName */);
1172 }
1173
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001174 if (hasInterfaceArgument) {
1175 // Start binder threadpool to handle incoming transactions
1176 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1177 }
Yifan Hong068c5522016-10-31 14:07:25 -07001178 out << "_hidl_err = remote()->transact("
1179 << method->getSerialId()
1180 << " /* "
1181 << method->name()
1182 << " */, _hidl_data, &_hidl_reply";
1183
1184 if (method->isOneway()) {
1185 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1186 }
1187 out << ");\n";
1188
1189 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1190
1191 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001192 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001193 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1194 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1195
1196
1197 // First DFS: write all buffers and resolve pointers for parent
1198 for (const auto &arg : method->results()) {
1199 emitCppReaderWriter(
1200 out,
1201 "_hidl_reply",
1202 false /* parcelObjIsPointer */,
1203 arg,
1204 true /* reader */,
1205 Type::ErrorMode_Goto,
1206 true /* addPrefixToName */);
1207 }
1208
1209 // Second DFS: resolve references.
1210 for (const auto &arg : method->results()) {
1211 emitCppResolveReferences(
1212 out,
1213 "_hidl_reply",
1214 false /* parcelObjIsPointer */,
1215 arg,
1216 true /* reader */,
1217 Type::ErrorMode_Goto,
1218 true /* addPrefixToName */);
1219 }
1220
1221 if (returnsValue && elidedReturn == nullptr) {
1222 out << "_hidl_cb(";
1223
1224 bool first = true;
1225 for (const auto &arg : method->results()) {
1226 if (!first) {
1227 out << ", ";
1228 }
1229
1230 if (arg->type().resultNeedsDeref()) {
1231 out << "*";
1232 }
1233 out << "_hidl_out_" << arg->name();
1234
1235 first = false;
1236 }
1237
1238 out << ");\n\n";
1239 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001240 }
1241 status = generateCppInstrumentationCall(
1242 out,
1243 InstrumentationEvent::CLIENT_API_EXIT,
1244 method);
1245 if (status != OK) {
1246 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001247 }
1248
1249 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001250 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1251 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001252 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001253 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1254 } else {
1255 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1256 out << "return ::android::hardware::Return<void>();\n\n";
1257 }
1258
1259 out.unindent();
1260 out << "_hidl_error:\n";
1261 out.indent();
1262 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1263 out << "return ::android::hardware::Return<";
1264 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001265 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001266 } else {
1267 out << "void";
1268 }
1269 out << ">(_hidl_status);\n";
1270
1271 out.unindent();
1272 out << "}\n\n";
1273 return OK;
1274}
1275
Andreas Huber881227d2016-08-02 14:20:21 -07001276status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001277 Formatter &out, const FQName &fqName) const {
1278 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001279
1280 out << klassName
1281 << "::"
1282 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001283 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001284
1285 out.indent();
1286 out.indent();
1287
1288 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001289 << "<"
1290 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001291 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001292 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001293 << mPackage.string()
Yifan Hongeefe4f22017-01-04 15:32:42 -08001294 << "::"
1295 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001296 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001297
Andreas Huber881227d2016-08-02 14:20:21 -07001298 out.unindent();
1299 out.unindent();
1300 out << "}\n\n";
1301
Yifan Hong068c5522016-10-31 14:07:25 -07001302 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1303 return generateProxyMethodSource(out, klassName, method, superInterface);
1304 });
Andreas Huber881227d2016-08-02 14:20:21 -07001305
Yifan Hong068c5522016-10-31 14:07:25 -07001306 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001307}
1308
1309status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001310 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001311 const Interface *iface) const {
1312 const std::string interfaceName = iface->localName();
1313 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001314
Steven Moreland40786312016-08-16 10:29:40 -07001315 out << klassName
1316 << "::"
1317 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001318 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001319
1320 out.indent();
1321 out.indent();
1322
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001323 if (iface->isIBase()) {
1324 out << ": ::android::hardware::HidlInstrumentor(\"";
1325 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001326 out << ": "
1327 << gIBaseFqName.getInterfaceStubFqName().cppName()
1328 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001329 }
1330
1331 out << mPackage.string()
Yifan Hongeefe4f22017-01-04 15:32:42 -08001332 << "::"
1333 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001334 << "\") { \n";
1335 out.indent();
1336 out << "_hidl_mImpl = _hidl_impl;\n";
1337 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001338
1339 out.unindent();
1340 out.unindent();
1341 out << "}\n\n";
1342
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001343 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001344 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001345 // class properly.
1346 out << klassName
1347 << "::"
1348 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001349 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl,"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001350 << " const std::string &prefix)\n";
1351
1352 out.indent();
1353 out.indent();
1354
1355 out << ": ::android::hardware::HidlInstrumentor(prefix) { \n";
1356 out.indent();
1357 out << "_hidl_mImpl = _hidl_impl;\n";
1358 out.unindent();
1359
1360 out.unindent();
1361 out.unindent();
1362 out << "}\n\n";
1363 }
1364
1365
Andreas Huber881227d2016-08-02 14:20:21 -07001366 out << "::android::status_t " << klassName << "::onTransact(\n";
1367
1368 out.indent();
1369 out.indent();
1370
Iliyan Malchev549e2592016-08-10 08:59:12 -07001371 out << "uint32_t _hidl_code,\n"
1372 << "const ::android::hardware::Parcel &_hidl_data,\n"
1373 << "::android::hardware::Parcel *_hidl_reply,\n"
1374 << "uint32_t _hidl_flags,\n"
1375 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001376
1377 out.unindent();
1378
Iliyan Malchev549e2592016-08-10 08:59:12 -07001379 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001380 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001381 out.indent();
1382
Yifan Hong10fe0b52016-10-19 14:20:17 -07001383 for (const auto &tuple : iface->allMethodsFromRoot()) {
1384 const Method *method = tuple.method();
1385 const Interface *superInterface = tuple.interface();
1386 out << "case "
1387 << method->getSerialId()
1388 << " /* "
1389 << method->name()
1390 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001391
Yifan Hong10fe0b52016-10-19 14:20:17 -07001392 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001393
Yifan Hong10fe0b52016-10-19 14:20:17 -07001394 status_t err =
1395 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001396
Yifan Hong10fe0b52016-10-19 14:20:17 -07001397 if (err != OK) {
1398 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001399 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001400
1401 out.unindent();
1402 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001403 }
1404
1405 out << "default:\n{\n";
1406 out.indent();
1407
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001408 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001409
1410 out.indent();
1411 out.indent();
1412
Iliyan Malchev549e2592016-08-10 08:59:12 -07001413 out << "_hidl_code, _hidl_data, _hidl_reply, "
1414 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001415
1416 out.unindent();
1417 out.unindent();
1418
1419 out.unindent();
1420 out << "}\n";
1421
1422 out.unindent();
1423 out << "}\n\n";
1424
Yifan Honga018ed52016-12-13 16:35:08 -08001425 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1426 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1427 out.indent(2, [&] {
1428 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1429 out << "_hidl_reply);\n";
1430 });
1431 });
Andreas Huber881227d2016-08-02 14:20:21 -07001432
Iliyan Malchev549e2592016-08-10 08:59:12 -07001433 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001434
1435 out.unindent();
1436 out << "}\n\n";
1437
1438 return OK;
1439}
1440
1441status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001442 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001443 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1444 method->cppImpl(IMPL_STUB, out);
1445 out << "break;\n";
1446 return OK;
1447 }
1448
Yifan Hongeefe4f22017-01-04 15:32:42 -08001449 out << "if (!_hidl_data.enforceInterface("
1450 << iface->fullName()
1451 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001452
Andreas Huber881227d2016-08-02 14:20:21 -07001453 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001454 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001455 out << "break;\n";
1456 out.unindent();
1457 out << "}\n\n";
1458
Andreas Huber5e44a292016-09-27 14:52:39 -07001459 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001460
Yifan Hongbf459bc2016-08-23 16:50:37 -07001461 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001462 for (const auto &arg : method->args()) {
1463 emitCppReaderWriter(
1464 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001465 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001466 false /* parcelObjIsPointer */,
1467 arg,
1468 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001469 Type::ErrorMode_Break,
1470 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001471 }
1472
Yifan Hongbf459bc2016-08-23 16:50:37 -07001473 // Second DFS: resolve references
1474 for (const auto &arg : method->args()) {
1475 emitCppResolveReferences(
1476 out,
1477 "_hidl_data",
1478 false /* parcelObjIsPointer */,
1479 arg,
1480 true /* reader */,
1481 Type::ErrorMode_Break,
1482 false /* addPrefixToName */);
1483 }
1484
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001485 status_t status = generateCppInstrumentationCall(
1486 out,
1487 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001488 method);
1489 if (status != OK) {
1490 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001491 }
1492
Andreas Huber881227d2016-08-02 14:20:21 -07001493 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001494 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001495
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001496 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001497 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001498 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001499 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001500 << " = "
1501 << "_hidl_mImpl->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001502 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001503
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001504 bool first = true;
1505 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001506 if (!first) {
1507 out << ", ";
1508 }
1509
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001510 if (arg->type().resultNeedsDeref()) {
1511 out << "*";
1512 }
1513
1514 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001515
1516 first = false;
1517 }
1518
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001519 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001520 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1521 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001522
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001523 elidedReturn->type().emitReaderWriter(
1524 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001525 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001526 "_hidl_reply",
1527 true, /* parcelObjIsPointer */
1528 false, /* isReader */
1529 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001530
Yifan Hongbf459bc2016-08-23 16:50:37 -07001531 emitCppResolveReferences(
1532 out,
1533 "_hidl_reply",
1534 true /* parcelObjIsPointer */,
1535 elidedReturn,
1536 false /* reader */,
1537 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001538 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001539
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001540 status_t status = generateCppInstrumentationCall(
1541 out,
1542 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001543 method);
1544 if (status != OK) {
1545 return status;
1546 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001547
Iliyan Malchev549e2592016-08-10 08:59:12 -07001548 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001549 } else {
1550 if (returnsValue) {
1551 out << "bool _hidl_callbackCalled = false;\n\n";
1552 }
Andreas Huber881227d2016-08-02 14:20:21 -07001553
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001554 out << "_hidl_mImpl->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001555
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001556 bool first = true;
1557 for (const auto &arg : method->args()) {
1558 if (!first) {
1559 out << ", ";
1560 }
Andreas Huber881227d2016-08-02 14:20:21 -07001561
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001562 if (arg->type().resultNeedsDeref()) {
1563 out << "*";
1564 }
1565
1566 out << arg->name();
1567
1568 first = false;
1569 }
1570
1571 if (returnsValue) {
1572 if (!first) {
1573 out << ", ";
1574 }
1575
1576 out << "[&](";
1577
1578 first = true;
1579 for (const auto &arg : method->results()) {
1580 if (!first) {
1581 out << ", ";
1582 }
1583
Yifan Honga47eef32016-12-12 10:38:54 -08001584 out << "const auto &_hidl_out_" << arg->name();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001585
1586 first = false;
1587 }
1588
1589 out << ") {\n";
1590 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001591 out << "if (_hidl_callbackCalled) {\n";
1592 out.indent();
1593 out << "LOG_ALWAYS_FATAL(\""
1594 << method->name()
1595 << ": _hidl_cb called a second time, but must be called once.\");\n";
1596 out.unindent();
1597 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001598 out << "_hidl_callbackCalled = true;\n\n";
1599
Yifan Hong859e53f2016-11-14 19:08:24 -08001600 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1601 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001602
Yifan Hongbf459bc2016-08-23 16:50:37 -07001603 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001604 for (const auto &arg : method->results()) {
1605 emitCppReaderWriter(
1606 out,
1607 "_hidl_reply",
1608 true /* parcelObjIsPointer */,
1609 arg,
1610 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001611 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001612 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001613 }
1614
Yifan Hongbf459bc2016-08-23 16:50:37 -07001615 // Second DFS: resolve references
1616 for (const auto &arg : method->results()) {
1617 emitCppResolveReferences(
1618 out,
1619 "_hidl_reply",
1620 true /* parcelObjIsPointer */,
1621 arg,
1622 false /* reader */,
1623 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001624 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001625 }
1626
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001627 status_t status = generateCppInstrumentationCall(
1628 out,
1629 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001630 method);
1631 if (status != OK) {
1632 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001633 }
1634
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001635 out << "_hidl_cb(*_hidl_reply);\n";
1636
1637 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001638 out << "});\n\n";
1639 } else {
1640 out << ");\n\n";
1641 status_t status = generateCppInstrumentationCall(
1642 out,
1643 InstrumentationEvent::SERVER_API_EXIT,
1644 method);
1645 if (status != OK) {
1646 return status;
1647 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001648 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001649
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001650 if (returnsValue) {
1651 out << "if (!_hidl_callbackCalled) {\n";
1652 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001653 out << "LOG_ALWAYS_FATAL(\""
1654 << method->name()
1655 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001656 out.unindent();
1657 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001658 } else {
1659 out << "::android::hardware::writeToParcel("
1660 << "::android::hardware::Status::ok(), "
1661 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001662 }
Andreas Huber881227d2016-08-02 14:20:21 -07001663 }
1664
1665 out << "break;\n";
1666
1667 return OK;
1668}
1669
Steven Moreland69e7c702016-09-09 11:16:32 -07001670status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1671 std::string ifaceName;
1672 if (!AST::isInterface(&ifaceName)) {
1673 // types.hal does not get a stub header.
1674 return OK;
1675 }
1676
1677 const Interface *iface = mRootScope->getInterface();
1678
Yifan Hongeefe4f22017-01-04 15:32:42 -08001679 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001680
1681 bool supportOneway = iface->hasOnewayMethods();
1682
1683 std::string path = outputPath;
1684 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1685 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1686 path.append(klassName);
1687 path.append(".h");
1688
1689 CHECK(Coordinator::MakeParentHierarchy(path));
1690 FILE *file = fopen(path.c_str(), "w");
1691
1692 if (file == NULL) {
1693 return -errno;
1694 }
1695
1696 Formatter out(file);
1697
1698 const std::string guard = makeHeaderGuard(klassName);
1699
1700 out << "#ifndef " << guard << "\n";
1701 out << "#define " << guard << "\n\n";
1702
1703 std::vector<std::string> packageComponents;
1704 getPackageAndVersionComponents(
1705 &packageComponents, false /* cpp_compatible */);
1706
Yifan Hongb0949432016-12-15 15:32:24 -08001707 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001708 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001709
1710 generateCppPackageInclude(out, mPackage, ifaceName);
1711 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001712
Yifan Hong7a118f52016-12-07 11:21:15 -08001713 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001714 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001715 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001716 }
1717
1718 enterLeaveNamespace(out, true /* enter */);
1719 out << "\n";
1720
1721 out << "struct "
1722 << klassName
1723 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001724 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001725
1726 out.indent();
1727 out << "explicit "
1728 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001729 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001730 << ifaceName
1731 << "> impl);\n";
1732
Yifan Hong068c5522016-10-31 14:07:25 -07001733 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1734 return generatePassthroughMethod(out, method);
1735 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001736
1737 if (err != OK) {
1738 return err;
1739 }
1740
1741 out.unindent();
1742 out << "private:\n";
1743 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001744 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001745
1746 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001747 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001748
1749 out << "\n";
1750
1751 out << "::android::hardware::Return<void> addOnewayTask("
1752 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001753 }
1754
1755 out.unindent();
1756
1757 out << "};\n\n";
1758
1759 enterLeaveNamespace(out, false /* enter */);
1760
1761 out << "\n#endif // " << guard << "\n";
1762
1763 return OK;
1764}
1765
Yifan Hongfe95aa22016-10-19 17:26:45 -07001766status_t AST::generateInterfaceSource(Formatter &out) const {
1767 const Interface *iface = mRootScope->getInterface();
1768
Yifan Hong2d7126b2016-10-20 15:12:57 -07001769 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001770 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001771
Yifan Hong3d746092016-12-07 14:26:33 -08001772 for (const Interface *superType : iface->typeChain()) {
1773 out << "// static \n"
1774 << childTypeResult
Yifan Hongeefe4f22017-01-04 15:32:42 -08001775 << " "
1776 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001777 << "::castFrom("
1778 << superType->getCppArgumentType()
1779 << " parent) {\n";
1780 out.indent();
1781 if (iface == superType) {
1782 out << "return parent;\n";
1783 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001784 out << "return ::android::hardware::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001785 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001786 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001787 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001788 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001789 << ">(\n";
1790 out.indent();
1791 out.indent();
1792 out << "parent, \""
1793 << iface->fqName().string()
1794 << "\");\n";
1795 out.unindent();
1796 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001797 }
Yifan Hong3d746092016-12-07 14:26:33 -08001798 out.unindent();
1799 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001800 }
1801
1802 return OK;
1803}
1804
Steven Moreland69e7c702016-09-09 11:16:32 -07001805status_t AST::generatePassthroughSource(Formatter &out) const {
1806 const Interface *iface = mRootScope->getInterface();
1807
Yifan Hongeefe4f22017-01-04 15:32:42 -08001808 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001809
1810 out << klassName
1811 << "::"
1812 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001813 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001814 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001815 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001816 << iface->fqName().string()
1817 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001818 if (iface->hasOnewayMethods()) {
1819 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001820 out.indent([&] {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001821 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1822 });
1823 }
1824 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001825
1826 if (iface->hasOnewayMethods()) {
1827 out << "::android::hardware::Return<void> "
1828 << klassName
1829 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1830 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001831 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001832 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001833 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1834 out.indent();
1835 out.indent();
1836 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1837 out.unindent();
1838 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001839 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001840 out << "}\n";
1841
Steven Morelandd366c262016-10-11 15:29:10 -07001842 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001843
1844 out.unindent();
1845 out << "}\n\n";
1846
1847
1848 }
1849
1850 return OK;
1851}
1852
Martijn Coenen7b295242016-11-04 16:52:56 +01001853status_t AST::generateCppAtraceCall(Formatter &out,
1854 InstrumentationEvent event,
1855 const Method *method) const {
1856 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001857 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001858 switch (event) {
1859 case SERVER_API_ENTRY:
1860 {
1861 out << "atrace_begin(ATRACE_TAG_HAL, \""
1862 << baseString + "::server\");\n";
1863 break;
1864 }
1865 case CLIENT_API_ENTRY:
1866 {
1867 out << "atrace_begin(ATRACE_TAG_HAL, \""
1868 << baseString + "::client\");\n";
1869 break;
1870 }
1871 case PASSTHROUGH_ENTRY:
1872 {
1873 out << "atrace_begin(ATRACE_TAG_HAL, \""
1874 << baseString + "::passthrough\");\n";
1875 break;
1876 }
1877 case SERVER_API_EXIT:
1878 case CLIENT_API_EXIT:
1879 case PASSTHROUGH_EXIT:
1880 {
1881 out << "atrace_end(ATRACE_TAG_HAL);\n";
1882 break;
1883 }
1884 default:
1885 {
1886 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1887 return UNKNOWN_ERROR;
1888 }
1889 }
1890
1891 return OK;
1892}
1893
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001894status_t AST::generateCppInstrumentationCall(
1895 Formatter &out,
1896 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001897 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001898 status_t err = generateCppAtraceCall(out, event, method);
1899 if (err != OK) {
1900 return err;
1901 }
1902
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001903 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1904 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001905 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001906 std::string event_str = "";
1907 switch (event) {
1908 case SERVER_API_ENTRY:
1909 {
1910 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1911 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001912 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001913 << (arg->type().resultNeedsDeref() ? "" : "&")
1914 << arg->name()
1915 << ");\n";
1916 }
1917 break;
1918 }
1919 case SERVER_API_EXIT:
1920 {
1921 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001922 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001923 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001924 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001925 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001926 }
1927 break;
1928 }
1929 case CLIENT_API_ENTRY:
1930 {
1931 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1932 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001933 out << "_hidl_args.push_back((void *)&"
1934 << arg->name()
1935 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001936 }
1937 break;
1938 }
1939 case CLIENT_API_EXIT:
1940 {
1941 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1942 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001943 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001944 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001945 << "_hidl_out_"
1946 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001947 << ");\n";
1948 }
1949 break;
1950 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001951 case PASSTHROUGH_ENTRY:
1952 {
1953 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1954 for (const auto &arg : method->args()) {
1955 out << "_hidl_args.push_back((void *)&"
1956 << arg->name()
1957 << ");\n";
1958 }
1959 break;
1960 }
1961 case PASSTHROUGH_EXIT:
1962 {
1963 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001964 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001965 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001966 << arg->name()
1967 << ");\n";
1968 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001969 break;
1970 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001971 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001972 {
Steven Moreland031ccf12016-10-31 15:54:38 -07001973 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001974 return UNKNOWN_ERROR;
1975 }
1976 }
1977
Steven Moreland031ccf12016-10-31 15:54:38 -07001978 const Interface *iface = mRootScope->getInterface();
1979
Steven Moreland1ab31442016-11-03 18:37:51 -07001980 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001981 out.indent();
1982 out << "callback("
1983 << event_str
1984 << ", \""
1985 << mPackage.package()
1986 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07001987 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001988 << "\", \""
1989 << iface->localName()
1990 << "\", \""
1991 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001992 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001993 out.unindent();
1994 out << "}\n";
1995 out.unindent();
1996 out << "}\n\n";
1997
1998 return OK;
1999}
2000
Andreas Huber881227d2016-08-02 14:20:21 -07002001} // namespace android
2002