blob: aa22362f384dd41ca8c0a4a4bbfb0f5e59094775 [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Huber881227d2016-08-02 14:20:21 -070017#include "AST.h"
18
19#include "Coordinator.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070020#include "EnumType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070021#include "Interface.h"
22#include "Method.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070023#include "ScalarType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070024#include "Scope.h"
25
Andreas Huberdca261f2016-08-04 13:47:51 -070026#include <algorithm>
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070027#include <hidl-util/Formatter.h>
Steven Moreland5708edf2016-11-04 15:33:31 +000028#include <hidl-util/StringHelper.h>
Andreas Huber881227d2016-08-02 14:20:21 -070029#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070030#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070031#include <vector>
32
33namespace android {
34
Andreas Huberb82318c2016-08-02 14:45:54 -070035status_t AST::generateCpp(const std::string &outputPath) const {
36 status_t err = generateInterfaceHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070037
38 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070039 err = generateStubHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070040 }
41
42 if (err == OK) {
Steven Moreland40786312016-08-16 10:29:40 -070043 err = generateHwBinderHeader(outputPath);
44 }
45
46 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070047 err = generateProxyHeader(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070048 }
49
50 if (err == OK) {
Andreas Huberb82318c2016-08-02 14:45:54 -070051 err = generateAllSource(outputPath);
Andreas Huber881227d2016-08-02 14:20:21 -070052 }
53
Steven Moreland69e7c702016-09-09 11:16:32 -070054 if (err == OK) {
Yifan Hong7a118f52016-12-07 11:21:15 -080055 err = generatePassthroughHeader(outputPath);
Steven Moreland69e7c702016-09-09 11:16:32 -070056 }
57
Andreas Huber881227d2016-08-02 14:20:21 -070058 return err;
59}
60
Andreas Huber737080b2016-08-02 15:38:04 -070061void AST::getPackageComponents(
62 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070063 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070064}
65
66void AST::getPackageAndVersionComponents(
67 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070068 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070069}
70
Steven Moreland5708edf2016-11-04 15:33:31 +000071std::string AST::makeHeaderGuard(const std::string &baseName,
72 bool indicateGenerated) const {
73 std::string guard;
Andreas Huber881227d2016-08-02 14:20:21 -070074
Steven Moreland5708edf2016-11-04 15:33:31 +000075 if (indicateGenerated) {
76 guard += "HIDL_GENERATED_";
77 }
78
79 guard += StringHelper::Uppercase(mPackage.tokenName());
Andreas Huber881227d2016-08-02 14:20:21 -070080 guard += "_";
Steven Moreland5708edf2016-11-04 15:33:31 +000081 guard += StringHelper::Uppercase(baseName);
82 guard += "_H";
Andreas Huber881227d2016-08-02 14:20:21 -070083
84 return guard;
85}
86
Steven Morelandee88eed2016-10-31 17:49:00 -070087// static
88void AST::generateCppPackageInclude(
89 Formatter &out,
90 const FQName &package,
91 const std::string &klass) {
92
93 out << "#include <";
94
95 std::vector<std::string> components;
96 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
97
98 for (const auto &component : components) {
99 out << component << "/";
100 }
101
102 out << klass
103 << ".h>\n";
104}
105
Andreas Huber881227d2016-08-02 14:20:21 -0700106void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
107 std::vector<std::string> packageComponents;
108 getPackageAndVersionComponents(
109 &packageComponents, true /* cpp_compatible */);
110
111 if (enter) {
112 for (const auto &component : packageComponents) {
113 out << "namespace " << component << " {\n";
114 }
Andreas Huber0e00de42016-08-03 09:56:02 -0700115
Andreas Huber2831d512016-08-15 09:33:47 -0700116 out.setNamespace(mPackage.cppNamespace() + "::");
Andreas Huber881227d2016-08-02 14:20:21 -0700117 } else {
Andreas Huber0e00de42016-08-03 09:56:02 -0700118 out.setNamespace(std::string());
119
Andreas Huber881227d2016-08-02 14:20:21 -0700120 for (auto it = packageComponents.rbegin();
121 it != packageComponents.rend();
122 ++it) {
123 out << "} // namespace " << *it << "\n";
124 }
125 }
126}
127
Yifan Hongeefe4f22017-01-04 15:32:42 -0800128static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
129 out << "static ::android::sp<" << interfaceName << "> getService("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800130 << "const std::string &serviceName=\"default\", bool getStub=false);\n";
131 out << "static ::android::sp<" << interfaceName << "> getService("
132 << "const char serviceName[], bool getStub=false)"
133 << " { std::string str(serviceName ? serviceName : \"\");"
134 << " return getService(str, getStub); }\n";
135 out << "static ::android::sp<" << interfaceName << "> getService("
136 << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
137 // without c_str the std::string constructor is ambiguous
138 << " { std::string str(serviceName.c_str());"
139 << " return getService(str, getStub); }\n";
140 out << "static ::android::sp<" << interfaceName << "> getService("
141 << "bool getStub) { return getService(\"default\", getStub); }\n";
142 out << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800143 out << "static bool registerForNotifications(\n";
144 out.indent(2, [&] {
145 out << "const std::string &serviceName,\n"
146 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
147 << "&notification);\n";
148 });
149
150}
151
152static void implementServiceManagerInteractions(Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -0800153 const FQName &fqName, const std::string &package) {
154
155 const std::string interfaceName = fqName.getInterfaceName();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800156
157 out << "// static\n"
Yifan Hongeefe4f22017-01-04 15:32:42 -0800158 << "::android::sp<" << interfaceName << "> " << interfaceName << "::getService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800159 << "const std::string &serviceName, bool getStub) ";
160 out.block([&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000161 out << "::android::sp<" << interfaceName << "> iface = nullptr;\n";
162 out << "::android::vintf::Transport transport = ::android::hardware::getTransportFromManifest(\""
163 << fqName.package() << "\");\n";
164
165 out.sIf("!getStub && "
166 "(transport == ::android::vintf::Transport::HWBINDER || "
167 // TODO(b/34625838): Don't load in passthrough mode
168 "transport == ::android::vintf::Transport::PASSTHROUGH || "
169 "transport == ::android::vintf::Transport::EMPTY)", [&] {
170 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800171 out.indent(2, [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000172 out << "= ::android::hardware::defaultServiceManager();\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800173 });
Steven Morelandf10af872017-01-25 16:01:56 +0000174 out.sIf("sm != nullptr", [&] {
Steven Morelandbec74ed2017-01-25 17:42:35 -0800175 // TODO(b/34274385) remove sysprop check
176 out.sIf("transport == ::android::vintf::Transport::HWBINDER &&"
177 " ::android::hardware::details::blockingHalBinderizationEnabled()", [&]() {
Steven Moreland6d7b91c2017-01-24 18:58:07 -0800178 out << "::android::hardware::details::waitForHwService("
179 << interfaceName << "::descriptor" << ", serviceName);\n";
180 }).endl();
Steven Morelandf10af872017-01-25 16:01:56 +0000181 out << "::android::hardware::Return<::android::sp<" << gIBaseFqName.cppName() << ">> ret = \n";
182 out.indent(2, [&] {
183 out << "sm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
184 });
185 out.sIf("ret.isOk()", [&] {
186 out << "iface = " << interfaceName << "::castFrom(ret);\n";
187 out.sIf("iface != nullptr", [&] {
188 out << "return iface;\n";
189 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800190 }).endl();
191 }).endl();
192 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800193
Steven Morelandf10af872017-01-25 16:01:56 +0000194 out.sIf("getStub || "
195 "transport == ::android::vintf::Transport::PASSTHROUGH || "
Steven Morelandbec74ed2017-01-25 17:42:35 -0800196 "(transport == ::android::vintf::Transport::HWBINDER &&"
197 " !::android::hardware::details::blockingHalBinderizationEnabled()) ||"
Steven Morelandf10af872017-01-25 16:01:56 +0000198 "transport == ::android::vintf::Transport::EMPTY", [&] {
199 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> pm\n";
Steven Morelande3fa5da2017-01-25 07:07:53 +0000200 out.indent(2, [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000201 out << "= ::android::hardware::getPassthroughServiceManager();\n";
Steven Morelande3fa5da2017-01-25 07:07:53 +0000202 });
Steven Morelandf10af872017-01-25 16:01:56 +0000203
204 out.sIf("pm != nullptr", [&] () {
205 out << "::android::hardware::Return<::android::sp<" << gIBaseFqName.cppName() << ">> ret = \n";
206 out.indent(2, [&] {
207 out << "pm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
Steven Moreland2c2dea82017-01-18 17:24:17 -0800208 });
Steven Morelandf10af872017-01-25 16:01:56 +0000209 out.sIf("ret.isOk()", [&] {
210 out << "::android::sp<" << gIBaseFqName.cppName()
211 << "> baseInterface = ret;\n";
212 out.sIf("baseInterface != nullptr", [&]() {
213 out << "iface = new " << fqName.getInterfacePassthroughName()
214 << "(" << interfaceName << "::castFrom(baseInterface));\n";
215 });
216 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800217 }).endl();
218 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800219
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800220 out << "return iface;\n";
221 }).endl().endl();
222
Yifan Hongeefe4f22017-01-04 15:32:42 -0800223 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800224 << "const std::string &serviceName) ";
225 out.block([&] {
226 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
227 out.indent(2, [&] {
228 out << "= ::android::hardware::defaultServiceManager();\n";
229 });
230 out.sIf("sm == nullptr", [&] {
231 out << "return ::android::INVALID_OPERATION;\n";
232 }).endl();
233 out << "bool success = false;\n"
234 << "::android::hardware::Return<void> ret =\n";
235 out.indent(2, [&] {
236 out << "this->interfaceChain("
237 << "[&success, &sm, &serviceName, this](const auto &chain) ";
238 out.block([&] {
239 out << "::android::hardware::Return<bool> addRet = "
240 << "sm->add(chain, serviceName.c_str(), this);\n";
241 out << "success = addRet.isOk() && addRet;\n";
242 });
243 out << ");\n";
Steven Morelandcd00b9b2016-12-29 10:34:03 -0800244 out << "success = success && ret.isOk();\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800245 });
246 out << "return success ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
247 }).endl().endl();
248
Yifan Hongeefe4f22017-01-04 15:32:42 -0800249 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800250 out.indent(2, [&] {
251 out << "const std::string &serviceName,\n"
252 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
253 << "&notification) ";
254 });
255 out.block([&] {
256 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
257 out.indent(2, [&] {
258 out << "= ::android::hardware::defaultServiceManager();\n";
259 });
260 out.sIf("sm == nullptr", [&] {
261 out << "return false;\n";
262 }).endl();
263 out << "::android::hardware::Return<bool> success =\n";
264 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800265 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800266 out.indent(2, [&] {
267 out << "serviceName, notification);\n";
268 });
269 });
270 out << "return success.isOk() && success;\n";
271 }).endl().endl();
272}
273
Andreas Huberb82318c2016-08-02 14:45:54 -0700274status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700275
Andreas Huberb82318c2016-08-02 14:45:54 -0700276 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700277 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700278 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700279
280 std::string ifaceName;
281 bool isInterface = true;
282 if (!AST::isInterface(&ifaceName)) {
283 ifaceName = "types";
284 isInterface = false;
285 }
286 path.append(ifaceName);
287 path.append(".h");
288
Andreas Huberd2943e12016-08-05 11:59:31 -0700289 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700290 FILE *file = fopen(path.c_str(), "w");
291
292 if (file == NULL) {
293 return -errno;
294 }
295
296 Formatter out(file);
297
298 const std::string guard = makeHeaderGuard(ifaceName);
299
300 out << "#ifndef " << guard << "\n";
301 out << "#define " << guard << "\n\n";
302
Andreas Huber737080b2016-08-02 15:38:04 -0700303 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700304 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700305 }
306
307 if (!mImportedNames.empty()) {
308 out << "\n";
309 }
310
Steven Moreland0693f312016-11-09 15:06:14 -0800311 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800312 if (isIBase()) {
313 out << "// skipped #include IServiceNotification.h\n\n";
314 } else {
315 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
316 }
Steven Moreland0693f312016-11-09 15:06:14 -0800317 }
318
Yifan Hongc8934042016-11-17 17:10:52 -0800319 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700320 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700321
322 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200323 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700324 }
325
Martijn Coenenaf712c02016-11-16 15:26:27 +0100326 out << "#include <utils/NativeHandle.h>\n";
327 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700328
329 enterLeaveNamespace(out, true /* enter */);
330 out << "\n";
331
332 if (isInterface) {
333 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700334 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700335
336 const Interface *iface = mRootScope->getInterface();
337 const Interface *superType = iface->superType();
338
Steven Moreland40786312016-08-16 10:29:40 -0700339 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800340 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700341 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000342 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700343 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700344 }
345
346 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700347
348 out.indent();
349
Andreas Huber881227d2016-08-02 14:20:21 -0700350 }
351
352 status_t err = emitTypeDeclarations(out);
353
354 if (err != OK) {
355 return err;
356 }
357
358 if (isInterface) {
359 const Interface *iface = mRootScope->getInterface();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700360 const Interface *superType = iface->superType();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800361
Yifan Hongc8934042016-11-17 17:10:52 -0800362 out << "virtual bool isRemote() const ";
363 if (!isIBase()) {
364 out << "override ";
365 }
366 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800367
Andreas Huber881227d2016-08-02 14:20:21 -0700368 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700369 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700370
Andreas Huber881227d2016-08-02 14:20:21 -0700371 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800372 const TypedVar *elidedReturn = method->canElideCallback();
373
374 if (elidedReturn == nullptr && returnsValue) {
375 out << "using "
376 << method->name()
377 << "_cb = std::function<void("
378 << Method::GetArgSignature(method->results(),
379 true /* specify namespaces */)
380 << ")>;\n";
381 }
Andreas Huber881227d2016-08-02 14:20:21 -0700382
Andreas Huber3599d922016-08-09 10:42:57 -0700383 method->dumpAnnotations(out);
384
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700385 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700386 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700387 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700388 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700389 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700390 }
391
392 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700393 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700394 << Method::GetArgSignature(method->args(),
395 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700396
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700397 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700398 if (!method->args().empty()) {
399 out << ", ";
400 }
401
Steven Moreland67f67b42016-09-29 08:59:02 -0700402 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700403 }
404
Yifan Hong10fe0b52016-10-19 14:20:17 -0700405 out << ")";
406 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800407 if (!isIBase()) {
408 out << " override";
409 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700410 out << " {\n";
411 out.indent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100412 method->cppImpl(IMPL_HEADER, out);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700413 out.unindent();
414 out << "\n}\n";
415 } else {
416 out << " = 0;\n";
417 }
Andreas Huber881227d2016-08-02 14:20:21 -0700418 }
Steven Moreland40786312016-08-16 10:29:40 -0700419
Yifan Hong3d746092016-12-07 14:26:33 -0800420 out << "// cast static functions\n";
421 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700422
Yifan Hong3d746092016-12-07 14:26:33 -0800423 for (const Interface *superType : iface->typeChain()) {
424 out << "static "
425 << childTypeResult
426 << " castFrom("
427 << superType->getCppArgumentType()
428 << " parent"
429 << ");\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700430 }
431
Steven Morelandd39133b2016-11-11 12:30:08 -0800432 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700433
Yifan Hongc8934042016-11-17 17:10:52 -0800434 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800435 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800436 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800437 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800438 }
Yifan Hong158655a2016-11-08 12:34:07 -0800439
440 out << "private: static int hidlStaticBlock;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700441 }
442
443 if (isInterface) {
444 out.unindent();
445
Andreas Hubere3f769a2016-10-10 10:54:44 -0700446 out << "};\n\n";
447 }
448
449 err = mRootScope->emitGlobalTypeDeclarations(out);
450
451 if (err != OK) {
452 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700453 }
454
455 out << "\n";
456 enterLeaveNamespace(out, false /* enter */);
457
458 out << "\n#endif // " << guard << "\n";
459
460 return OK;
461}
462
Steven Moreland40786312016-08-16 10:29:40 -0700463status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
464 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800465 bool isInterface = AST::isInterface(&ifaceName);
466 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800467 std::string klassName{};
468
469 if(isInterface) {
470 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800471 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800472 } else {
473 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700474 }
475
Steven Moreland40786312016-08-16 10:29:40 -0700476 std::string path = outputPath;
477 path.append(mCoordinator->convertPackageRootToPath(mPackage));
478 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
479 path.append(klassName + ".h");
480
Yifan Hong244e82d2016-11-11 11:13:57 -0800481 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700482
483 if (file == NULL) {
484 return -errno;
485 }
486
487 Formatter out(file);
488
489 const std::string guard = makeHeaderGuard(klassName);
490
491 out << "#ifndef " << guard << "\n";
492 out << "#define " << guard << "\n\n";
493
Yifan Hong244e82d2016-11-11 11:13:57 -0800494 if (isInterface) {
495 generateCppPackageInclude(out, mPackage, ifaceName);
496 } else {
497 generateCppPackageInclude(out, mPackage, "types");
498 }
Steven Moreland40786312016-08-16 10:29:40 -0700499
Steven Morelandee88eed2016-10-31 17:49:00 -0700500 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700501
502 for (const auto &item : mImportedNames) {
503 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800504 generateCppPackageInclude(out, item, "hwtypes");
505 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800506 generateCppPackageInclude(out, item, item.getInterfaceStubName());
507 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700508 }
Steven Moreland40786312016-08-16 10:29:40 -0700509 }
510
511 out << "\n";
512
Martijn Coenen93915102016-09-01 01:35:52 +0200513 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700514 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100515 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700516
517 out << "\n";
518
519 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700520
Yifan Hong244e82d2016-11-11 11:13:57 -0800521 status_t err = mRootScope->emitGlobalHwDeclarations(out);
522 if (err != OK) {
523 return err;
524 }
Steven Moreland40786312016-08-16 10:29:40 -0700525
526 enterLeaveNamespace(out, false /* enter */);
527
528 out << "\n#endif // " << guard << "\n";
529
530 return OK;
531}
532
Andreas Huber881227d2016-08-02 14:20:21 -0700533status_t AST::emitTypeDeclarations(Formatter &out) const {
534 return mRootScope->emitTypeDeclarations(out);
535}
536
Yifan Hong7a118f52016-12-07 11:21:15 -0800537static void wrapPassthroughArg(Formatter &out,
538 const TypedVar *arg, bool addPrefixToName,
539 std::function<void(void)> handleError) {
540 if (!arg->type().isInterface()) {
541 return;
542 }
543 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
544 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
545 + arg->name();
546 const Interface &iface = static_cast<const Interface &>(arg->type());
547 out << iface.getCppStackType() << " " << wrappedName << ";\n";
548 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
549 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
550 out << wrappedName
551 << " = "
552 << iface.fqName().cppName()
553 << "::castFrom(::android::hardware::wrapPassthrough("
554 << name << "));\n";
555 out.sIf(wrappedName + " == nullptr", [&] {
556 // Fatal error. Happens when the BsFoo class is not found in the binary
557 // or any dynamic libraries.
558 handleError();
559 }).endl();
560 }).sElse([&] {
561 out << wrappedName << " = " << name << ";\n";
562 }).endl().endl();
563}
564
Steven Moreland69e7c702016-09-09 11:16:32 -0700565status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700566 const Method *method) const {
567 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700568
569 out << " {\n";
570 out.indent();
571
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800572 if (method->isHidlReserved()
573 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
574 method->cppImpl(IMPL_PASSTHROUGH, out);
575 out.unindent();
576 out << "}\n\n";
577 return OK;
578 }
579
Steven Moreland69e7c702016-09-09 11:16:32 -0700580 const bool returnsValue = !method->results().empty();
581 const TypedVar *elidedReturn = method->canElideCallback();
582
Steven Moreland67f67b42016-09-29 08:59:02 -0700583 if (returnsValue && elidedReturn == nullptr) {
584 generateCheckNonNull(out, "_hidl_cb");
585 }
586
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700587 generateCppInstrumentationCall(
588 out,
589 InstrumentationEvent::PASSTHROUGH_ENTRY,
590 method);
591
Yifan Hong7a118f52016-12-07 11:21:15 -0800592
593 for (const auto &arg : method->args()) {
594 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
595 out << "return ::android::hardware::Status::fromExceptionCode(\n";
596 out.indent(2, [&] {
597 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800598 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800599 });
600 });
601 }
602
603 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700604 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700605
606 if (method->isOneway()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800607 out << "addOnewayTask([this, &_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700608 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800609 out << ", "
610 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
611 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700612 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700613 out << "] {\n";
614 out.indent();
615 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700616 }
617
618 out << "mImpl->"
619 << method->name()
620 << "(";
621
622 bool first = true;
623 for (const auto &arg : method->args()) {
624 if (!first) {
625 out << ", ";
626 }
627 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800628 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700629 }
630 if (returnsValue && elidedReturn == nullptr) {
631 if (!method->args().empty()) {
632 out << ", ";
633 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800634 out << "[&](";
635 first = true;
636 for (const auto &arg : method->results()) {
637 if (!first) {
638 out << ", ";
639 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700640
Yifan Hong7a118f52016-12-07 11:21:15 -0800641 out << "const auto &_hidl_out_"
642 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800643
644 first = false;
645 }
646
647 out << ") {\n";
648 out.indent();
649 status_t status = generateCppInstrumentationCall(
650 out,
651 InstrumentationEvent::PASSTHROUGH_EXIT,
652 method);
653 if (status != OK) {
654 return status;
655 }
656
Yifan Hong7a118f52016-12-07 11:21:15 -0800657 for (const auto &arg : method->results()) {
658 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
659 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
660 out.indent(2, [&] {
661 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800662 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800663 });
664 out << "return;\n";
665 });
666 }
667
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800668 out << "_hidl_cb(";
669 first = true;
670 for (const auto &arg : method->results()) {
671 if (!first) {
672 out << ", ";
673 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800674 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800675 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
676 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800677 }
678 out << ");\n";
679 out.unindent();
680 out << "});\n\n";
681 } else {
682 out << ");\n\n";
683 if (elidedReturn != nullptr) {
684 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800685 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800686 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000687 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800688 }
689 status_t status = generateCppInstrumentationCall(
690 out,
691 InstrumentationEvent::PASSTHROUGH_EXIT,
692 method);
693 if (status != OK) {
694 return status;
695 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700696 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700697
698 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700699 out.unindent();
700 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700701 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700702
703 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700704
705 out.unindent();
706 out << "}\n";
707
708 return OK;
709}
710
Yifan Hong068c5522016-10-31 14:07:25 -0700711status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700712
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700713 const Interface *iface = mRootScope->getInterface();
714
Yifan Hong10fe0b52016-10-19 14:20:17 -0700715 const Interface *prevIterface = nullptr;
716 for (const auto &tuple : iface->allMethodsFromRoot()) {
717 const Method *method = tuple.method();
718 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700719
Yifan Hong10fe0b52016-10-19 14:20:17 -0700720 if(prevIterface != superInterface) {
721 if (prevIterface != nullptr) {
722 out << "\n";
723 }
724 out << "// Methods from "
725 << superInterface->fullName()
726 << " follow.\n";
727 prevIterface = superInterface;
728 }
Yifan Hong068c5522016-10-31 14:07:25 -0700729 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700730
Yifan Hong10fe0b52016-10-19 14:20:17 -0700731 if (err != OK) {
732 return err;
733 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700734 }
735
Yifan Hong10fe0b52016-10-19 14:20:17 -0700736 out << "\n";
737
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700738 return OK;
739}
740
Andreas Huberb82318c2016-08-02 14:45:54 -0700741status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700742 std::string ifaceName;
743 if (!AST::isInterface(&ifaceName)) {
744 // types.hal does not get a stub header.
745 return OK;
746 }
747
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700748 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800749 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700750
Andreas Huberb82318c2016-08-02 14:45:54 -0700751 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700752 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700753 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700754 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700755 path.append(".h");
756
Andreas Huberd2943e12016-08-05 11:59:31 -0700757 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700758 FILE *file = fopen(path.c_str(), "w");
759
760 if (file == NULL) {
761 return -errno;
762 }
763
764 Formatter out(file);
765
Steven Moreland40786312016-08-16 10:29:40 -0700766 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700767
768 out << "#ifndef " << guard << "\n";
769 out << "#define " << guard << "\n\n";
770
Yifan Hongeefe4f22017-01-04 15:32:42 -0800771 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700772 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700773
774 enterLeaveNamespace(out, true /* enter */);
775 out << "\n";
776
777 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800778 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100779 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800780 out << " : public ::android::hardware::BHwBinder";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100781 out << ", public ::android::hardware::HidlInstrumentor {\n";
782 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800783 out << " : public "
784 << gIBaseFqName.getInterfaceStubFqName().cppName()
785 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100786 }
Andreas Huber881227d2016-08-02 14:20:21 -0700787
788 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800789 out << "explicit "
790 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700791 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100792 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800793 out << "explicit "
794 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100795 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
796 << " const std::string& prefix);"
Steven Moreland40786312016-08-16 10:29:40 -0700797 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700798 out << "::android::status_t onTransact(\n";
799 out.indent();
800 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700801 out << "uint32_t _hidl_code,\n";
802 out << "const ::android::hardware::Parcel &_hidl_data,\n";
803 out << "::android::hardware::Parcel *_hidl_reply,\n";
804 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700805 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700806 out.unindent();
807 out.unindent();
808
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100809 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
810 out.unindent();
811 out << "private:\n";
812 out.indent();
813 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700814 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700815 out << "};\n\n";
816
817 enterLeaveNamespace(out, false /* enter */);
818
819 out << "\n#endif // " << guard << "\n";
820
821 return OK;
822}
823
Andreas Huberb82318c2016-08-02 14:45:54 -0700824status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700825 std::string ifaceName;
826 if (!AST::isInterface(&ifaceName)) {
827 // types.hal does not get a proxy header.
828 return OK;
829 }
830
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700831 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800832 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700833
Andreas Huberb82318c2016-08-02 14:45:54 -0700834 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700835 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700836 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800837 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700838 path.append(".h");
839
Andreas Huberd2943e12016-08-05 11:59:31 -0700840 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700841 FILE *file = fopen(path.c_str(), "w");
842
843 if (file == NULL) {
844 return -errno;
845 }
846
847 Formatter out(file);
848
Yifan Hongeefe4f22017-01-04 15:32:42 -0800849 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700850
851 out << "#ifndef " << guard << "\n";
852 out << "#define " << guard << "\n\n";
853
Martijn Coenen115d4282016-12-19 05:14:04 +0100854 out << "#include <hidl/HidlTransportSupport.h>\n\n";
855
Andreas Huber881227d2016-08-02 14:20:21 -0700856 std::vector<std::string> packageComponents;
857 getPackageAndVersionComponents(
858 &packageComponents, false /* cpp_compatible */);
859
Yifan Hongeefe4f22017-01-04 15:32:42 -0800860 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700861 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700862
863 enterLeaveNamespace(out, true /* enter */);
864 out << "\n";
865
866 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800867 << proxyName
868 << " : public ::android::hardware::BpInterface<"
869 << iface->localName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700870 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700871
872 out.indent();
873
Yifan Hongeefe4f22017-01-04 15:32:42 -0800874 out << "explicit "
875 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700876 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700877 << "\n\n";
878
Yifan Hong10fe0b52016-10-19 14:20:17 -0700879 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700880
Yifan Hong068c5522016-10-31 14:07:25 -0700881 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
882 method->generateCppSignature(out);
883 out << " override;\n";
884 return OK;
885 });
Steven Moreland9c387612016-09-07 09:54:26 -0700886
887 if (err != OK) {
888 return err;
889 }
Andreas Huber881227d2016-08-02 14:20:21 -0700890
891 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100892 out << "private:\n";
893 out.indent();
894 out << "std::mutex _hidl_mMutex;\n"
895 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
896 << " _hidl_mDeathRecipients;\n";
897 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700898 out << "};\n\n";
899
900 enterLeaveNamespace(out, false /* enter */);
901
902 out << "\n#endif // " << guard << "\n";
903
904 return OK;
905}
906
Andreas Huberb82318c2016-08-02 14:45:54 -0700907status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700908
Andreas Huberb82318c2016-08-02 14:45:54 -0700909 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700910 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700911 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700912
913 std::string ifaceName;
914 std::string baseName;
915
Yifan Hongfe95aa22016-10-19 17:26:45 -0700916 const Interface *iface = nullptr;
917 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700918 if (!AST::isInterface(&ifaceName)) {
919 baseName = "types";
920 isInterface = false;
921 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700922 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700923 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700924 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700925 }
926
927 path.append(baseName);
928
929 if (baseName != "types") {
930 path.append("All");
931 }
932
933 path.append(".cpp");
934
Andreas Huberd2943e12016-08-05 11:59:31 -0700935 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700936 FILE *file = fopen(path.c_str(), "w");
937
938 if (file == NULL) {
939 return -errno;
940 }
941
942 Formatter out(file);
943
Steven Moreland623c0042017-01-13 14:42:29 -0800944 out << "#define LOG_TAG \""
945 << mPackage.string() << "::" << baseName
946 << "\"\n\n";
947
Steven Moreland05cd4232016-11-21 16:01:12 -0800948 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100949 out << "#include <cutils/trace.h>\n";
950 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700951 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700952 // This is a no-op for IServiceManager itself.
953 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
954
Steven Morelandbec74ed2017-01-25 17:42:35 -0800955 // TODO(b/34274385) remove this
956 out << "#include <hidl/LegacySupport.h>\n";
957
Yifan Hongeefe4f22017-01-04 15:32:42 -0800958 generateCppPackageInclude(out, mPackage, iface->getProxyName());
959 generateCppPackageInclude(out, mPackage, iface->getStubName());
960 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700961
962 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700963 generateCppPackageInclude(out,
964 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800965 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700966 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800967
968 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700969 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700970 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800971 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700972 }
973
974 out << "\n";
975
976 enterLeaveNamespace(out, true /* enter */);
977 out << "\n";
978
979 status_t err = generateTypeSource(out, ifaceName);
980
981 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700982 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700983
984 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -0800985 out << "const char* "
986 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -0700987 << "::descriptor(\""
988 << iface->fqName().string()
989 << "\");\n\n";
990
Yifan Hongeefe4f22017-01-04 15:32:42 -0800991 out << "int "
992 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -0800993 << "::hidlStaticBlock = []() -> int {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800994 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800995 out << "::android::hardware::gBnConstructorMap["
996 << iface->localName()
Steven Morelandd39133b2016-11-11 12:30:08 -0800997 << "::descriptor]\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800998 out.indent(2, [&] {
Yifan Hong158655a2016-11-08 12:34:07 -0800999 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001000 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001001 out << "return new "
1002 << iface->getStubName()
1003 << "(reinterpret_cast<"
1004 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001005 << " *>(iIntf));\n";
1006 });
1007 out << "};\n";
1008 });
Yifan Hongeefe4f22017-01-04 15:32:42 -08001009 out << "::android::hardware::gBsConstructorMap["
1010 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001011 << "::descriptor]\n";
1012 out.indent(2, [&] {
1013 out << "= [](void *iIntf) -> ::android::sp<"
1014 << gIBaseFqName.cppName()
1015 << "> {\n";
1016 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001017 out << "return new "
1018 << iface->getPassthroughName()
1019 << "(reinterpret_cast<"
1020 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001021 << " *>(iIntf));\n";
1022 });
1023 out << "};\n";
1024 });
Yifan Hong158655a2016-11-08 12:34:07 -08001025 out << "return 1;\n";
1026 });
1027 out << "}();\n\n";
1028
Yifan Hongfe95aa22016-10-19 17:26:45 -07001029 err = generateInterfaceSource(out);
1030 }
1031
1032 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001033 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001034 }
1035
1036 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001037 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001038 }
1039
Steven Moreland40786312016-08-16 10:29:40 -07001040 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001041 err = generatePassthroughSource(out);
1042 }
1043
1044 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001045 const Interface *iface = mRootScope->getInterface();
1046
Yifan Hongc8934042016-11-17 17:10:52 -08001047 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001048 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001049 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001050 std::string package = iface->fqName().package()
1051 + iface->fqName().atVersion();
1052
Yifan Hongeefe4f22017-01-04 15:32:42 -08001053 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001054 }
Steven Moreland40786312016-08-16 10:29:40 -07001055 }
1056
Andreas Huber881227d2016-08-02 14:20:21 -07001057 enterLeaveNamespace(out, false /* enter */);
1058
1059 return err;
1060}
1061
Steven Moreland67f67b42016-09-29 08:59:02 -07001062// static
1063void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001064 out.sIf(nonNull + " == nullptr", [&] {
1065 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1066 out.indent(2, [&] {
1067 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1068 });
1069 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001070}
1071
Andreas Huber881227d2016-08-02 14:20:21 -07001072status_t AST::generateTypeSource(
1073 Formatter &out, const std::string &ifaceName) const {
1074 return mRootScope->emitTypeDefinitions(out, ifaceName);
1075}
1076
Andreas Hubere7ff2282016-08-16 13:50:03 -07001077void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001078 Formatter &out,
1079 const std::vector<TypedVar *> &args,
1080 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001081 if (args.empty()) {
1082 return;
1083 }
1084
1085 for (const auto &arg : args) {
1086 const Type &type = arg->type();
1087
Yifan Hong3b320f82016-11-01 15:15:54 -07001088 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001089 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001090 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001091 << ";\n";
1092 }
1093
1094 out << "\n";
1095}
1096
Andreas Huber881227d2016-08-02 14:20:21 -07001097void AST::emitCppReaderWriter(
1098 Formatter &out,
1099 const std::string &parcelObj,
1100 bool parcelObjIsPointer,
1101 const TypedVar *arg,
1102 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001103 Type::ErrorMode mode,
1104 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001105 const Type &type = arg->type();
1106
Andreas Huber881227d2016-08-02 14:20:21 -07001107 type.emitReaderWriter(
1108 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001109 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001110 parcelObj,
1111 parcelObjIsPointer,
1112 isReader,
1113 mode);
1114}
1115
Yifan Hongbf459bc2016-08-23 16:50:37 -07001116void AST::emitCppResolveReferences(
1117 Formatter &out,
1118 const std::string &parcelObj,
1119 bool parcelObjIsPointer,
1120 const TypedVar *arg,
1121 bool isReader,
1122 Type::ErrorMode mode,
1123 bool addPrefixToName) const {
1124 const Type &type = arg->type();
1125 if(type.needsResolveReferences()) {
1126 type.emitResolveReferences(
1127 out,
1128 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1129 isReader, // nameIsPointer
1130 parcelObj,
1131 parcelObjIsPointer,
1132 isReader,
1133 mode);
1134 }
1135}
1136
Yifan Hong068c5522016-10-31 14:07:25 -07001137status_t AST::generateProxyMethodSource(Formatter &out,
1138 const std::string &klassName,
1139 const Method *method,
1140 const Interface *superInterface) const {
1141
1142 method->generateCppSignature(out,
1143 klassName,
1144 true /* specify namespaces */);
1145
1146 const bool returnsValue = !method->results().empty();
1147 const TypedVar *elidedReturn = method->canElideCallback();
1148
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001149 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001150
1151 out.indent();
1152
Martijn Coenen115d4282016-12-19 05:14:04 +01001153 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1154 method->cppImpl(IMPL_PROXY, out);
1155 out.unindent();
1156 out << "}\n\n";
1157 return OK;
1158 }
1159
Yifan Hong068c5522016-10-31 14:07:25 -07001160 if (returnsValue && elidedReturn == nullptr) {
1161 generateCheckNonNull(out, "_hidl_cb");
1162 }
1163
1164 status_t status = generateCppInstrumentationCall(
1165 out,
1166 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001167 method);
1168 if (status != OK) {
1169 return status;
1170 }
1171
1172 out << "::android::hardware::Parcel _hidl_data;\n";
1173 out << "::android::hardware::Parcel _hidl_reply;\n";
1174 out << "::android::status_t _hidl_err;\n";
1175 out << "::android::hardware::Status _hidl_status;\n\n";
1176
1177 declareCppReaderLocals(
1178 out, method->results(), true /* forResults */);
1179
1180 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001181 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001182 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001183 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1184
Martijn Coenenfff73352017-01-04 16:36:31 +01001185 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001186 // First DFS: write all buffers and resolve pointers for parent
1187 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001188 if (arg->type().isInterface()) {
1189 hasInterfaceArgument = true;
1190 }
Yifan Hong068c5522016-10-31 14:07:25 -07001191 emitCppReaderWriter(
1192 out,
1193 "_hidl_data",
1194 false /* parcelObjIsPointer */,
1195 arg,
1196 false /* reader */,
1197 Type::ErrorMode_Goto,
1198 false /* addPrefixToName */);
1199 }
1200
1201 // Second DFS: resolve references.
1202 for (const auto &arg : method->args()) {
1203 emitCppResolveReferences(
1204 out,
1205 "_hidl_data",
1206 false /* parcelObjIsPointer */,
1207 arg,
1208 false /* reader */,
1209 Type::ErrorMode_Goto,
1210 false /* addPrefixToName */);
1211 }
1212
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001213 if (hasInterfaceArgument) {
1214 // Start binder threadpool to handle incoming transactions
1215 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1216 }
Yifan Hong068c5522016-10-31 14:07:25 -07001217 out << "_hidl_err = remote()->transact("
1218 << method->getSerialId()
1219 << " /* "
1220 << method->name()
1221 << " */, _hidl_data, &_hidl_reply";
1222
1223 if (method->isOneway()) {
1224 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1225 }
1226 out << ");\n";
1227
1228 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1229
1230 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001231 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001232 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1233 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1234
1235
1236 // First DFS: write all buffers and resolve pointers for parent
1237 for (const auto &arg : method->results()) {
1238 emitCppReaderWriter(
1239 out,
1240 "_hidl_reply",
1241 false /* parcelObjIsPointer */,
1242 arg,
1243 true /* reader */,
1244 Type::ErrorMode_Goto,
1245 true /* addPrefixToName */);
1246 }
1247
1248 // Second DFS: resolve references.
1249 for (const auto &arg : method->results()) {
1250 emitCppResolveReferences(
1251 out,
1252 "_hidl_reply",
1253 false /* parcelObjIsPointer */,
1254 arg,
1255 true /* reader */,
1256 Type::ErrorMode_Goto,
1257 true /* addPrefixToName */);
1258 }
1259
1260 if (returnsValue && elidedReturn == nullptr) {
1261 out << "_hidl_cb(";
1262
1263 bool first = true;
1264 for (const auto &arg : method->results()) {
1265 if (!first) {
1266 out << ", ";
1267 }
1268
1269 if (arg->type().resultNeedsDeref()) {
1270 out << "*";
1271 }
1272 out << "_hidl_out_" << arg->name();
1273
1274 first = false;
1275 }
1276
1277 out << ");\n\n";
1278 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001279 }
1280 status = generateCppInstrumentationCall(
1281 out,
1282 InstrumentationEvent::CLIENT_API_EXIT,
1283 method);
1284 if (status != OK) {
1285 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001286 }
1287
1288 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001289 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1290 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001291 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001292 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1293 } else {
1294 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1295 out << "return ::android::hardware::Return<void>();\n\n";
1296 }
1297
1298 out.unindent();
1299 out << "_hidl_error:\n";
1300 out.indent();
1301 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1302 out << "return ::android::hardware::Return<";
1303 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001304 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001305 } else {
1306 out << "void";
1307 }
1308 out << ">(_hidl_status);\n";
1309
1310 out.unindent();
1311 out << "}\n\n";
1312 return OK;
1313}
1314
Andreas Huber881227d2016-08-02 14:20:21 -07001315status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001316 Formatter &out, const FQName &fqName) const {
1317 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001318
1319 out << klassName
1320 << "::"
1321 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001322 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001323
1324 out.indent();
1325 out.indent();
1326
1327 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001328 << "<"
1329 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001330 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001331 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001332 << mPackage.string()
Yifan Hongeefe4f22017-01-04 15:32:42 -08001333 << "::"
1334 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001335 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001336
Andreas Huber881227d2016-08-02 14:20:21 -07001337 out.unindent();
1338 out.unindent();
1339 out << "}\n\n";
1340
Yifan Hong068c5522016-10-31 14:07:25 -07001341 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1342 return generateProxyMethodSource(out, klassName, method, superInterface);
1343 });
Andreas Huber881227d2016-08-02 14:20:21 -07001344
Yifan Hong068c5522016-10-31 14:07:25 -07001345 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001346}
1347
1348status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001349 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001350 const Interface *iface) const {
1351 const std::string interfaceName = iface->localName();
1352 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001353
Steven Moreland40786312016-08-16 10:29:40 -07001354 out << klassName
1355 << "::"
1356 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001357 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001358
1359 out.indent();
1360 out.indent();
1361
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001362 if (iface->isIBase()) {
1363 out << ": ::android::hardware::HidlInstrumentor(\"";
1364 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001365 out << ": "
1366 << gIBaseFqName.getInterfaceStubFqName().cppName()
1367 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001368 }
1369
1370 out << mPackage.string()
Yifan Hongeefe4f22017-01-04 15:32:42 -08001371 << "::"
1372 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001373 << "\") { \n";
1374 out.indent();
1375 out << "_hidl_mImpl = _hidl_impl;\n";
1376 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001377
1378 out.unindent();
1379 out.unindent();
1380 out << "}\n\n";
1381
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001382 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001383 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001384 // class properly.
1385 out << klassName
1386 << "::"
1387 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001388 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl,"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001389 << " const std::string &prefix)\n";
1390
1391 out.indent();
1392 out.indent();
1393
1394 out << ": ::android::hardware::HidlInstrumentor(prefix) { \n";
1395 out.indent();
1396 out << "_hidl_mImpl = _hidl_impl;\n";
1397 out.unindent();
1398
1399 out.unindent();
1400 out.unindent();
1401 out << "}\n\n";
1402 }
1403
1404
Andreas Huber881227d2016-08-02 14:20:21 -07001405 out << "::android::status_t " << klassName << "::onTransact(\n";
1406
1407 out.indent();
1408 out.indent();
1409
Iliyan Malchev549e2592016-08-10 08:59:12 -07001410 out << "uint32_t _hidl_code,\n"
1411 << "const ::android::hardware::Parcel &_hidl_data,\n"
1412 << "::android::hardware::Parcel *_hidl_reply,\n"
1413 << "uint32_t _hidl_flags,\n"
1414 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001415
1416 out.unindent();
1417
Iliyan Malchev549e2592016-08-10 08:59:12 -07001418 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001419 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001420 out.indent();
1421
Yifan Hong10fe0b52016-10-19 14:20:17 -07001422 for (const auto &tuple : iface->allMethodsFromRoot()) {
1423 const Method *method = tuple.method();
1424 const Interface *superInterface = tuple.interface();
1425 out << "case "
1426 << method->getSerialId()
1427 << " /* "
1428 << method->name()
1429 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001430
Yifan Hong10fe0b52016-10-19 14:20:17 -07001431 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001432
Yifan Hong10fe0b52016-10-19 14:20:17 -07001433 status_t err =
1434 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001435
Yifan Hong10fe0b52016-10-19 14:20:17 -07001436 if (err != OK) {
1437 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001438 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001439
1440 out.unindent();
1441 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001442 }
1443
1444 out << "default:\n{\n";
1445 out.indent();
1446
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001447 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001448
1449 out.indent();
1450 out.indent();
1451
Iliyan Malchev549e2592016-08-10 08:59:12 -07001452 out << "_hidl_code, _hidl_data, _hidl_reply, "
1453 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001454
1455 out.unindent();
1456 out.unindent();
1457
1458 out.unindent();
1459 out << "}\n";
1460
1461 out.unindent();
1462 out << "}\n\n";
1463
Yifan Honga018ed52016-12-13 16:35:08 -08001464 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1465 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1466 out.indent(2, [&] {
1467 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1468 out << "_hidl_reply);\n";
1469 });
1470 });
Andreas Huber881227d2016-08-02 14:20:21 -07001471
Iliyan Malchev549e2592016-08-10 08:59:12 -07001472 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001473
1474 out.unindent();
1475 out << "}\n\n";
1476
1477 return OK;
1478}
1479
1480status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001481 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001482 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1483 method->cppImpl(IMPL_STUB, out);
1484 out << "break;\n";
1485 return OK;
1486 }
1487
Yifan Hongeefe4f22017-01-04 15:32:42 -08001488 out << "if (!_hidl_data.enforceInterface("
1489 << iface->fullName()
1490 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001491
Andreas Huber881227d2016-08-02 14:20:21 -07001492 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001493 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001494 out << "break;\n";
1495 out.unindent();
1496 out << "}\n\n";
1497
Andreas Huber5e44a292016-09-27 14:52:39 -07001498 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001499
Yifan Hongbf459bc2016-08-23 16:50:37 -07001500 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001501 for (const auto &arg : method->args()) {
1502 emitCppReaderWriter(
1503 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001504 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001505 false /* parcelObjIsPointer */,
1506 arg,
1507 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001508 Type::ErrorMode_Break,
1509 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001510 }
1511
Yifan Hongbf459bc2016-08-23 16:50:37 -07001512 // Second DFS: resolve references
1513 for (const auto &arg : method->args()) {
1514 emitCppResolveReferences(
1515 out,
1516 "_hidl_data",
1517 false /* parcelObjIsPointer */,
1518 arg,
1519 true /* reader */,
1520 Type::ErrorMode_Break,
1521 false /* addPrefixToName */);
1522 }
1523
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001524 status_t status = generateCppInstrumentationCall(
1525 out,
1526 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001527 method);
1528 if (status != OK) {
1529 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001530 }
1531
Andreas Huber881227d2016-08-02 14:20:21 -07001532 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001533 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001534
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001535 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001536 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001537 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001538 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001539 << " = "
1540 << "_hidl_mImpl->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001541 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001542
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001543 bool first = true;
1544 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001545 if (!first) {
1546 out << ", ";
1547 }
1548
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001549 if (arg->type().resultNeedsDeref()) {
1550 out << "*";
1551 }
1552
1553 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001554
1555 first = false;
1556 }
1557
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001558 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001559 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1560 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001561
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001562 elidedReturn->type().emitReaderWriter(
1563 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001564 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001565 "_hidl_reply",
1566 true, /* parcelObjIsPointer */
1567 false, /* isReader */
1568 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001569
Yifan Hongbf459bc2016-08-23 16:50:37 -07001570 emitCppResolveReferences(
1571 out,
1572 "_hidl_reply",
1573 true /* parcelObjIsPointer */,
1574 elidedReturn,
1575 false /* reader */,
1576 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001577 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001578
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001579 status_t status = generateCppInstrumentationCall(
1580 out,
1581 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001582 method);
1583 if (status != OK) {
1584 return status;
1585 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001586
Iliyan Malchev549e2592016-08-10 08:59:12 -07001587 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001588 } else {
1589 if (returnsValue) {
1590 out << "bool _hidl_callbackCalled = false;\n\n";
1591 }
Andreas Huber881227d2016-08-02 14:20:21 -07001592
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001593 out << "_hidl_mImpl->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001594
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001595 bool first = true;
1596 for (const auto &arg : method->args()) {
1597 if (!first) {
1598 out << ", ";
1599 }
Andreas Huber881227d2016-08-02 14:20:21 -07001600
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001601 if (arg->type().resultNeedsDeref()) {
1602 out << "*";
1603 }
1604
1605 out << arg->name();
1606
1607 first = false;
1608 }
1609
1610 if (returnsValue) {
1611 if (!first) {
1612 out << ", ";
1613 }
1614
1615 out << "[&](";
1616
1617 first = true;
1618 for (const auto &arg : method->results()) {
1619 if (!first) {
1620 out << ", ";
1621 }
1622
Yifan Honga47eef32016-12-12 10:38:54 -08001623 out << "const auto &_hidl_out_" << arg->name();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001624
1625 first = false;
1626 }
1627
1628 out << ") {\n";
1629 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001630 out << "if (_hidl_callbackCalled) {\n";
1631 out.indent();
1632 out << "LOG_ALWAYS_FATAL(\""
1633 << method->name()
1634 << ": _hidl_cb called a second time, but must be called once.\");\n";
1635 out.unindent();
1636 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001637 out << "_hidl_callbackCalled = true;\n\n";
1638
Yifan Hong859e53f2016-11-14 19:08:24 -08001639 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1640 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001641
Yifan Hongbf459bc2016-08-23 16:50:37 -07001642 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001643 for (const auto &arg : method->results()) {
1644 emitCppReaderWriter(
1645 out,
1646 "_hidl_reply",
1647 true /* parcelObjIsPointer */,
1648 arg,
1649 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001650 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001651 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001652 }
1653
Yifan Hongbf459bc2016-08-23 16:50:37 -07001654 // Second DFS: resolve references
1655 for (const auto &arg : method->results()) {
1656 emitCppResolveReferences(
1657 out,
1658 "_hidl_reply",
1659 true /* parcelObjIsPointer */,
1660 arg,
1661 false /* reader */,
1662 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001663 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001664 }
1665
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001666 status_t status = generateCppInstrumentationCall(
1667 out,
1668 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001669 method);
1670 if (status != OK) {
1671 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001672 }
1673
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001674 out << "_hidl_cb(*_hidl_reply);\n";
1675
1676 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001677 out << "});\n\n";
1678 } else {
1679 out << ");\n\n";
1680 status_t status = generateCppInstrumentationCall(
1681 out,
1682 InstrumentationEvent::SERVER_API_EXIT,
1683 method);
1684 if (status != OK) {
1685 return status;
1686 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001687 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001688
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001689 if (returnsValue) {
1690 out << "if (!_hidl_callbackCalled) {\n";
1691 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001692 out << "LOG_ALWAYS_FATAL(\""
1693 << method->name()
1694 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001695 out.unindent();
1696 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001697 } else {
1698 out << "::android::hardware::writeToParcel("
1699 << "::android::hardware::Status::ok(), "
1700 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001701 }
Andreas Huber881227d2016-08-02 14:20:21 -07001702 }
1703
1704 out << "break;\n";
1705
1706 return OK;
1707}
1708
Steven Moreland69e7c702016-09-09 11:16:32 -07001709status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1710 std::string ifaceName;
1711 if (!AST::isInterface(&ifaceName)) {
1712 // types.hal does not get a stub header.
1713 return OK;
1714 }
1715
1716 const Interface *iface = mRootScope->getInterface();
1717
Yifan Hongeefe4f22017-01-04 15:32:42 -08001718 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001719
1720 bool supportOneway = iface->hasOnewayMethods();
1721
1722 std::string path = outputPath;
1723 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1724 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1725 path.append(klassName);
1726 path.append(".h");
1727
1728 CHECK(Coordinator::MakeParentHierarchy(path));
1729 FILE *file = fopen(path.c_str(), "w");
1730
1731 if (file == NULL) {
1732 return -errno;
1733 }
1734
1735 Formatter out(file);
1736
1737 const std::string guard = makeHeaderGuard(klassName);
1738
1739 out << "#ifndef " << guard << "\n";
1740 out << "#define " << guard << "\n\n";
1741
1742 std::vector<std::string> packageComponents;
1743 getPackageAndVersionComponents(
1744 &packageComponents, false /* cpp_compatible */);
1745
Yifan Hongb0949432016-12-15 15:32:24 -08001746 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001747 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001748
1749 generateCppPackageInclude(out, mPackage, ifaceName);
1750 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001751
Yifan Hong7a118f52016-12-07 11:21:15 -08001752 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001753 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001754 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001755 }
1756
1757 enterLeaveNamespace(out, true /* enter */);
1758 out << "\n";
1759
1760 out << "struct "
1761 << klassName
1762 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001763 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001764
1765 out.indent();
1766 out << "explicit "
1767 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001768 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001769 << ifaceName
1770 << "> impl);\n";
1771
Yifan Hong068c5522016-10-31 14:07:25 -07001772 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1773 return generatePassthroughMethod(out, method);
1774 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001775
1776 if (err != OK) {
1777 return err;
1778 }
1779
1780 out.unindent();
1781 out << "private:\n";
1782 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001783 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001784
1785 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001786 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001787
1788 out << "\n";
1789
1790 out << "::android::hardware::Return<void> addOnewayTask("
1791 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001792 }
1793
1794 out.unindent();
1795
1796 out << "};\n\n";
1797
1798 enterLeaveNamespace(out, false /* enter */);
1799
1800 out << "\n#endif // " << guard << "\n";
1801
1802 return OK;
1803}
1804
Yifan Hongfe95aa22016-10-19 17:26:45 -07001805status_t AST::generateInterfaceSource(Formatter &out) const {
1806 const Interface *iface = mRootScope->getInterface();
1807
Yifan Hong2d7126b2016-10-20 15:12:57 -07001808 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001809 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001810
Yifan Hong3d746092016-12-07 14:26:33 -08001811 for (const Interface *superType : iface->typeChain()) {
1812 out << "// static \n"
1813 << childTypeResult
Yifan Hongeefe4f22017-01-04 15:32:42 -08001814 << " "
1815 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001816 << "::castFrom("
1817 << superType->getCppArgumentType()
1818 << " parent) {\n";
1819 out.indent();
1820 if (iface == superType) {
1821 out << "return parent;\n";
1822 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001823 out << "return ::android::hardware::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001824 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001825 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001826 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001827 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001828 << ">(\n";
1829 out.indent();
1830 out.indent();
1831 out << "parent, \""
1832 << iface->fqName().string()
1833 << "\");\n";
1834 out.unindent();
1835 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001836 }
Yifan Hong3d746092016-12-07 14:26:33 -08001837 out.unindent();
1838 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001839 }
1840
1841 return OK;
1842}
1843
Steven Moreland69e7c702016-09-09 11:16:32 -07001844status_t AST::generatePassthroughSource(Formatter &out) const {
1845 const Interface *iface = mRootScope->getInterface();
1846
Yifan Hongeefe4f22017-01-04 15:32:42 -08001847 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001848
1849 out << klassName
1850 << "::"
1851 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001852 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001853 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001854 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001855 << iface->fqName().string()
1856 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001857 if (iface->hasOnewayMethods()) {
1858 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001859 out.indent([&] {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001860 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1861 });
1862 }
1863 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001864
1865 if (iface->hasOnewayMethods()) {
1866 out << "::android::hardware::Return<void> "
1867 << klassName
1868 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1869 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001870 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001871 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001872 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1873 out.indent();
1874 out.indent();
1875 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1876 out.unindent();
1877 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001878 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001879 out << "}\n";
1880
Steven Morelandd366c262016-10-11 15:29:10 -07001881 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001882
1883 out.unindent();
1884 out << "}\n\n";
1885
1886
1887 }
1888
1889 return OK;
1890}
1891
Martijn Coenen7b295242016-11-04 16:52:56 +01001892status_t AST::generateCppAtraceCall(Formatter &out,
1893 InstrumentationEvent event,
1894 const Method *method) const {
1895 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001896 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001897 switch (event) {
1898 case SERVER_API_ENTRY:
1899 {
1900 out << "atrace_begin(ATRACE_TAG_HAL, \""
1901 << baseString + "::server\");\n";
1902 break;
1903 }
1904 case CLIENT_API_ENTRY:
1905 {
1906 out << "atrace_begin(ATRACE_TAG_HAL, \""
1907 << baseString + "::client\");\n";
1908 break;
1909 }
1910 case PASSTHROUGH_ENTRY:
1911 {
1912 out << "atrace_begin(ATRACE_TAG_HAL, \""
1913 << baseString + "::passthrough\");\n";
1914 break;
1915 }
1916 case SERVER_API_EXIT:
1917 case CLIENT_API_EXIT:
1918 case PASSTHROUGH_EXIT:
1919 {
1920 out << "atrace_end(ATRACE_TAG_HAL);\n";
1921 break;
1922 }
1923 default:
1924 {
1925 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1926 return UNKNOWN_ERROR;
1927 }
1928 }
1929
1930 return OK;
1931}
1932
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001933status_t AST::generateCppInstrumentationCall(
1934 Formatter &out,
1935 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001936 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001937 status_t err = generateCppAtraceCall(out, event, method);
1938 if (err != OK) {
1939 return err;
1940 }
1941
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001942 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1943 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001944 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001945 std::string event_str = "";
1946 switch (event) {
1947 case SERVER_API_ENTRY:
1948 {
1949 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1950 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001951 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001952 << (arg->type().resultNeedsDeref() ? "" : "&")
1953 << arg->name()
1954 << ");\n";
1955 }
1956 break;
1957 }
1958 case SERVER_API_EXIT:
1959 {
1960 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001961 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001962 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001963 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001964 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001965 }
1966 break;
1967 }
1968 case CLIENT_API_ENTRY:
1969 {
1970 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1971 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001972 out << "_hidl_args.push_back((void *)&"
1973 << arg->name()
1974 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001975 }
1976 break;
1977 }
1978 case CLIENT_API_EXIT:
1979 {
1980 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1981 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001982 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001983 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001984 << "_hidl_out_"
1985 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001986 << ");\n";
1987 }
1988 break;
1989 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001990 case PASSTHROUGH_ENTRY:
1991 {
1992 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1993 for (const auto &arg : method->args()) {
1994 out << "_hidl_args.push_back((void *)&"
1995 << arg->name()
1996 << ");\n";
1997 }
1998 break;
1999 }
2000 case PASSTHROUGH_EXIT:
2001 {
2002 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002003 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002004 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002005 << arg->name()
2006 << ");\n";
2007 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002008 break;
2009 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002010 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002011 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002012 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002013 return UNKNOWN_ERROR;
2014 }
2015 }
2016
Steven Moreland031ccf12016-10-31 15:54:38 -07002017 const Interface *iface = mRootScope->getInterface();
2018
Steven Moreland1ab31442016-11-03 18:37:51 -07002019 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002020 out.indent();
2021 out << "callback("
2022 << event_str
2023 << ", \""
2024 << mPackage.package()
2025 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002026 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002027 << "\", \""
2028 << iface->localName()
2029 << "\", \""
2030 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002031 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002032 out.unindent();
2033 out << "}\n";
2034 out.unindent();
2035 out << "}\n\n";
2036
2037 return OK;
2038}
2039
Andreas Huber881227d2016-08-02 14:20:21 -07002040} // namespace android