blob: 116bc218a1e96f1d19e819576769ef7e64d8fe53 [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,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800796 << " const std::string& HidlInstrumentor_package,"
797 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700798 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700799 out << "::android::status_t onTransact(\n";
800 out.indent();
801 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700802 out << "uint32_t _hidl_code,\n";
803 out << "const ::android::hardware::Parcel &_hidl_data,\n";
804 out << "::android::hardware::Parcel *_hidl_reply,\n";
805 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700806 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700807 out.unindent();
808 out.unindent();
809
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100810 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
811 out.unindent();
812 out << "private:\n";
813 out.indent();
814 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700815 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700816 out << "};\n\n";
817
818 enterLeaveNamespace(out, false /* enter */);
819
820 out << "\n#endif // " << guard << "\n";
821
822 return OK;
823}
824
Andreas Huberb82318c2016-08-02 14:45:54 -0700825status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700826 std::string ifaceName;
827 if (!AST::isInterface(&ifaceName)) {
828 // types.hal does not get a proxy header.
829 return OK;
830 }
831
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700832 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800833 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700834
Andreas Huberb82318c2016-08-02 14:45:54 -0700835 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700836 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700837 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800838 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700839 path.append(".h");
840
Andreas Huberd2943e12016-08-05 11:59:31 -0700841 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700842 FILE *file = fopen(path.c_str(), "w");
843
844 if (file == NULL) {
845 return -errno;
846 }
847
848 Formatter out(file);
849
Yifan Hongeefe4f22017-01-04 15:32:42 -0800850 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700851
852 out << "#ifndef " << guard << "\n";
853 out << "#define " << guard << "\n\n";
854
Martijn Coenen115d4282016-12-19 05:14:04 +0100855 out << "#include <hidl/HidlTransportSupport.h>\n\n";
856
Andreas Huber881227d2016-08-02 14:20:21 -0700857 std::vector<std::string> packageComponents;
858 getPackageAndVersionComponents(
859 &packageComponents, false /* cpp_compatible */);
860
Yifan Hongeefe4f22017-01-04 15:32:42 -0800861 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700862 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700863
864 enterLeaveNamespace(out, true /* enter */);
865 out << "\n";
866
867 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800868 << proxyName
869 << " : public ::android::hardware::BpInterface<"
870 << iface->localName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700871 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700872
873 out.indent();
874
Yifan Hongeefe4f22017-01-04 15:32:42 -0800875 out << "explicit "
876 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700877 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700878 << "\n\n";
879
Yifan Hong10fe0b52016-10-19 14:20:17 -0700880 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700881
Yifan Hong068c5522016-10-31 14:07:25 -0700882 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
883 method->generateCppSignature(out);
884 out << " override;\n";
885 return OK;
886 });
Steven Moreland9c387612016-09-07 09:54:26 -0700887
888 if (err != OK) {
889 return err;
890 }
Andreas Huber881227d2016-08-02 14:20:21 -0700891
892 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100893 out << "private:\n";
894 out.indent();
895 out << "std::mutex _hidl_mMutex;\n"
896 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
897 << " _hidl_mDeathRecipients;\n";
898 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700899 out << "};\n\n";
900
901 enterLeaveNamespace(out, false /* enter */);
902
903 out << "\n#endif // " << guard << "\n";
904
905 return OK;
906}
907
Andreas Huberb82318c2016-08-02 14:45:54 -0700908status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700909
Andreas Huberb82318c2016-08-02 14:45:54 -0700910 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700911 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700912 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700913
914 std::string ifaceName;
915 std::string baseName;
916
Yifan Hongfe95aa22016-10-19 17:26:45 -0700917 const Interface *iface = nullptr;
918 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700919 if (!AST::isInterface(&ifaceName)) {
920 baseName = "types";
921 isInterface = false;
922 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700923 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700924 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700925 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700926 }
927
928 path.append(baseName);
929
930 if (baseName != "types") {
931 path.append("All");
932 }
933
934 path.append(".cpp");
935
Andreas Huberd2943e12016-08-05 11:59:31 -0700936 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700937 FILE *file = fopen(path.c_str(), "w");
938
939 if (file == NULL) {
940 return -errno;
941 }
942
943 Formatter out(file);
944
Steven Moreland623c0042017-01-13 14:42:29 -0800945 out << "#define LOG_TAG \""
946 << mPackage.string() << "::" << baseName
947 << "\"\n\n";
948
Steven Moreland05cd4232016-11-21 16:01:12 -0800949 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100950 out << "#include <cutils/trace.h>\n";
951 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700952 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700953 // This is a no-op for IServiceManager itself.
954 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
955
Steven Morelandbec74ed2017-01-25 17:42:35 -0800956 // TODO(b/34274385) remove this
957 out << "#include <hidl/LegacySupport.h>\n";
958
Yifan Hongeefe4f22017-01-04 15:32:42 -0800959 generateCppPackageInclude(out, mPackage, iface->getProxyName());
960 generateCppPackageInclude(out, mPackage, iface->getStubName());
961 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700962
963 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700964 generateCppPackageInclude(out,
965 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800966 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700967 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800968
969 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700970 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700971 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800972 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700973 }
974
975 out << "\n";
976
977 enterLeaveNamespace(out, true /* enter */);
978 out << "\n";
979
980 status_t err = generateTypeSource(out, ifaceName);
981
982 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -0700983 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700984
985 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -0800986 out << "const char* "
987 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -0700988 << "::descriptor(\""
989 << iface->fqName().string()
990 << "\");\n\n";
991
Yifan Hongeefe4f22017-01-04 15:32:42 -0800992 out << "int "
993 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -0800994 << "::hidlStaticBlock = []() -> int {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800995 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800996 out << "::android::hardware::gBnConstructorMap["
997 << iface->localName()
Steven Morelandd39133b2016-11-11 12:30:08 -0800998 << "::descriptor]\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800999 out.indent(2, [&] {
Yifan Hong158655a2016-11-08 12:34:07 -08001000 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001001 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001002 out << "return new "
1003 << iface->getStubName()
1004 << "(reinterpret_cast<"
1005 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001006 << " *>(iIntf));\n";
1007 });
1008 out << "};\n";
1009 });
Yifan Hongeefe4f22017-01-04 15:32:42 -08001010 out << "::android::hardware::gBsConstructorMap["
1011 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001012 << "::descriptor]\n";
1013 out.indent(2, [&] {
1014 out << "= [](void *iIntf) -> ::android::sp<"
1015 << gIBaseFqName.cppName()
1016 << "> {\n";
1017 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001018 out << "return new "
1019 << iface->getPassthroughName()
1020 << "(reinterpret_cast<"
1021 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001022 << " *>(iIntf));\n";
1023 });
1024 out << "};\n";
1025 });
Yifan Hong158655a2016-11-08 12:34:07 -08001026 out << "return 1;\n";
1027 });
1028 out << "}();\n\n";
1029
Yifan Hongfe95aa22016-10-19 17:26:45 -07001030 err = generateInterfaceSource(out);
1031 }
1032
1033 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001034 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001035 }
1036
1037 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001038 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001039 }
1040
Steven Moreland40786312016-08-16 10:29:40 -07001041 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001042 err = generatePassthroughSource(out);
1043 }
1044
1045 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001046 const Interface *iface = mRootScope->getInterface();
1047
Yifan Hongc8934042016-11-17 17:10:52 -08001048 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001049 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001050 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001051 std::string package = iface->fqName().package()
1052 + iface->fqName().atVersion();
1053
Yifan Hongeefe4f22017-01-04 15:32:42 -08001054 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001055 }
Steven Moreland40786312016-08-16 10:29:40 -07001056 }
1057
Andreas Huber881227d2016-08-02 14:20:21 -07001058 enterLeaveNamespace(out, false /* enter */);
1059
1060 return err;
1061}
1062
Steven Moreland67f67b42016-09-29 08:59:02 -07001063// static
1064void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001065 out.sIf(nonNull + " == nullptr", [&] {
1066 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1067 out.indent(2, [&] {
1068 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1069 });
1070 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001071}
1072
Andreas Huber881227d2016-08-02 14:20:21 -07001073status_t AST::generateTypeSource(
1074 Formatter &out, const std::string &ifaceName) const {
1075 return mRootScope->emitTypeDefinitions(out, ifaceName);
1076}
1077
Andreas Hubere7ff2282016-08-16 13:50:03 -07001078void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001079 Formatter &out,
1080 const std::vector<TypedVar *> &args,
1081 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001082 if (args.empty()) {
1083 return;
1084 }
1085
1086 for (const auto &arg : args) {
1087 const Type &type = arg->type();
1088
Yifan Hong3b320f82016-11-01 15:15:54 -07001089 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001090 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001091 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001092 << ";\n";
1093 }
1094
1095 out << "\n";
1096}
1097
Andreas Huber881227d2016-08-02 14:20:21 -07001098void AST::emitCppReaderWriter(
1099 Formatter &out,
1100 const std::string &parcelObj,
1101 bool parcelObjIsPointer,
1102 const TypedVar *arg,
1103 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001104 Type::ErrorMode mode,
1105 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001106 const Type &type = arg->type();
1107
Andreas Huber881227d2016-08-02 14:20:21 -07001108 type.emitReaderWriter(
1109 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001110 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001111 parcelObj,
1112 parcelObjIsPointer,
1113 isReader,
1114 mode);
1115}
1116
Yifan Hongbf459bc2016-08-23 16:50:37 -07001117void AST::emitCppResolveReferences(
1118 Formatter &out,
1119 const std::string &parcelObj,
1120 bool parcelObjIsPointer,
1121 const TypedVar *arg,
1122 bool isReader,
1123 Type::ErrorMode mode,
1124 bool addPrefixToName) const {
1125 const Type &type = arg->type();
1126 if(type.needsResolveReferences()) {
1127 type.emitResolveReferences(
1128 out,
1129 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1130 isReader, // nameIsPointer
1131 parcelObj,
1132 parcelObjIsPointer,
1133 isReader,
1134 mode);
1135 }
1136}
1137
Yifan Hong068c5522016-10-31 14:07:25 -07001138status_t AST::generateProxyMethodSource(Formatter &out,
1139 const std::string &klassName,
1140 const Method *method,
1141 const Interface *superInterface) const {
1142
1143 method->generateCppSignature(out,
1144 klassName,
1145 true /* specify namespaces */);
1146
1147 const bool returnsValue = !method->results().empty();
1148 const TypedVar *elidedReturn = method->canElideCallback();
1149
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001150 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001151
1152 out.indent();
1153
Martijn Coenen115d4282016-12-19 05:14:04 +01001154 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1155 method->cppImpl(IMPL_PROXY, out);
1156 out.unindent();
1157 out << "}\n\n";
1158 return OK;
1159 }
1160
Yifan Hong068c5522016-10-31 14:07:25 -07001161 if (returnsValue && elidedReturn == nullptr) {
1162 generateCheckNonNull(out, "_hidl_cb");
1163 }
1164
1165 status_t status = generateCppInstrumentationCall(
1166 out,
1167 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001168 method);
1169 if (status != OK) {
1170 return status;
1171 }
1172
1173 out << "::android::hardware::Parcel _hidl_data;\n";
1174 out << "::android::hardware::Parcel _hidl_reply;\n";
1175 out << "::android::status_t _hidl_err;\n";
1176 out << "::android::hardware::Status _hidl_status;\n\n";
1177
1178 declareCppReaderLocals(
1179 out, method->results(), true /* forResults */);
1180
1181 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001182 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001183 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001184 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1185
Martijn Coenenfff73352017-01-04 16:36:31 +01001186 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001187 // First DFS: write all buffers and resolve pointers for parent
1188 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001189 if (arg->type().isInterface()) {
1190 hasInterfaceArgument = true;
1191 }
Yifan Hong068c5522016-10-31 14:07:25 -07001192 emitCppReaderWriter(
1193 out,
1194 "_hidl_data",
1195 false /* parcelObjIsPointer */,
1196 arg,
1197 false /* reader */,
1198 Type::ErrorMode_Goto,
1199 false /* addPrefixToName */);
1200 }
1201
1202 // Second DFS: resolve references.
1203 for (const auto &arg : method->args()) {
1204 emitCppResolveReferences(
1205 out,
1206 "_hidl_data",
1207 false /* parcelObjIsPointer */,
1208 arg,
1209 false /* reader */,
1210 Type::ErrorMode_Goto,
1211 false /* addPrefixToName */);
1212 }
1213
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001214 if (hasInterfaceArgument) {
1215 // Start binder threadpool to handle incoming transactions
1216 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1217 }
Yifan Hong068c5522016-10-31 14:07:25 -07001218 out << "_hidl_err = remote()->transact("
1219 << method->getSerialId()
1220 << " /* "
1221 << method->name()
1222 << " */, _hidl_data, &_hidl_reply";
1223
1224 if (method->isOneway()) {
1225 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1226 }
1227 out << ");\n";
1228
1229 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1230
1231 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001232 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001233 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1234 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1235
1236
1237 // First DFS: write all buffers and resolve pointers for parent
1238 for (const auto &arg : method->results()) {
1239 emitCppReaderWriter(
1240 out,
1241 "_hidl_reply",
1242 false /* parcelObjIsPointer */,
1243 arg,
1244 true /* reader */,
1245 Type::ErrorMode_Goto,
1246 true /* addPrefixToName */);
1247 }
1248
1249 // Second DFS: resolve references.
1250 for (const auto &arg : method->results()) {
1251 emitCppResolveReferences(
1252 out,
1253 "_hidl_reply",
1254 false /* parcelObjIsPointer */,
1255 arg,
1256 true /* reader */,
1257 Type::ErrorMode_Goto,
1258 true /* addPrefixToName */);
1259 }
1260
1261 if (returnsValue && elidedReturn == nullptr) {
1262 out << "_hidl_cb(";
1263
1264 bool first = true;
1265 for (const auto &arg : method->results()) {
1266 if (!first) {
1267 out << ", ";
1268 }
1269
1270 if (arg->type().resultNeedsDeref()) {
1271 out << "*";
1272 }
1273 out << "_hidl_out_" << arg->name();
1274
1275 first = false;
1276 }
1277
1278 out << ");\n\n";
1279 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001280 }
1281 status = generateCppInstrumentationCall(
1282 out,
1283 InstrumentationEvent::CLIENT_API_EXIT,
1284 method);
1285 if (status != OK) {
1286 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001287 }
1288
1289 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001290 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1291 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001292 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001293 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1294 } else {
1295 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1296 out << "return ::android::hardware::Return<void>();\n\n";
1297 }
1298
1299 out.unindent();
1300 out << "_hidl_error:\n";
1301 out.indent();
1302 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1303 out << "return ::android::hardware::Return<";
1304 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001305 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001306 } else {
1307 out << "void";
1308 }
1309 out << ">(_hidl_status);\n";
1310
1311 out.unindent();
1312 out << "}\n\n";
1313 return OK;
1314}
1315
Andreas Huber881227d2016-08-02 14:20:21 -07001316status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001317 Formatter &out, const FQName &fqName) const {
1318 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001319
1320 out << klassName
1321 << "::"
1322 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001323 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001324
1325 out.indent();
1326 out.indent();
1327
1328 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001329 << "<"
1330 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001331 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001332 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001333 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001334 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001335 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001336 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001337
Andreas Huber881227d2016-08-02 14:20:21 -07001338 out.unindent();
1339 out.unindent();
1340 out << "}\n\n";
1341
Yifan Hong068c5522016-10-31 14:07:25 -07001342 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1343 return generateProxyMethodSource(out, klassName, method, superInterface);
1344 });
Andreas Huber881227d2016-08-02 14:20:21 -07001345
Yifan Hong068c5522016-10-31 14:07:25 -07001346 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001347}
1348
1349status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001350 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001351 const Interface *iface) const {
1352 const std::string interfaceName = iface->localName();
1353 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001354
Steven Moreland40786312016-08-16 10:29:40 -07001355 out << klassName
1356 << "::"
1357 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001358 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001359
1360 out.indent();
1361 out.indent();
1362
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001363 if (iface->isIBase()) {
1364 out << ": ::android::hardware::HidlInstrumentor(\"";
1365 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001366 out << ": "
1367 << gIBaseFqName.getInterfaceStubFqName().cppName()
1368 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001369 }
1370
1371 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001372 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001373 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001374 << "\") { \n";
1375 out.indent();
1376 out << "_hidl_mImpl = _hidl_impl;\n";
1377 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001378
1379 out.unindent();
1380 out.unindent();
1381 out << "}\n\n";
1382
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001383 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001384 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001385 // class properly.
1386 out << klassName
1387 << "::"
1388 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001389 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1390 << " const std::string &HidlInstrumentor_package,"
1391 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001392
1393 out.indent();
1394 out.indent();
1395
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001396 out << ": ::android::hardware::HidlInstrumentor("
1397 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001398 out.indent();
1399 out << "_hidl_mImpl = _hidl_impl;\n";
1400 out.unindent();
1401
1402 out.unindent();
1403 out.unindent();
1404 out << "}\n\n";
1405 }
1406
1407
Andreas Huber881227d2016-08-02 14:20:21 -07001408 out << "::android::status_t " << klassName << "::onTransact(\n";
1409
1410 out.indent();
1411 out.indent();
1412
Iliyan Malchev549e2592016-08-10 08:59:12 -07001413 out << "uint32_t _hidl_code,\n"
1414 << "const ::android::hardware::Parcel &_hidl_data,\n"
1415 << "::android::hardware::Parcel *_hidl_reply,\n"
1416 << "uint32_t _hidl_flags,\n"
1417 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001418
1419 out.unindent();
1420
Iliyan Malchev549e2592016-08-10 08:59:12 -07001421 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001422 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001423 out.indent();
1424
Yifan Hong10fe0b52016-10-19 14:20:17 -07001425 for (const auto &tuple : iface->allMethodsFromRoot()) {
1426 const Method *method = tuple.method();
1427 const Interface *superInterface = tuple.interface();
1428 out << "case "
1429 << method->getSerialId()
1430 << " /* "
1431 << method->name()
1432 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001433
Yifan Hong10fe0b52016-10-19 14:20:17 -07001434 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001435
Yifan Hong10fe0b52016-10-19 14:20:17 -07001436 status_t err =
1437 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001438
Yifan Hong10fe0b52016-10-19 14:20:17 -07001439 if (err != OK) {
1440 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001441 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001442
1443 out.unindent();
1444 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001445 }
1446
1447 out << "default:\n{\n";
1448 out.indent();
1449
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001450 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001451
1452 out.indent();
1453 out.indent();
1454
Iliyan Malchev549e2592016-08-10 08:59:12 -07001455 out << "_hidl_code, _hidl_data, _hidl_reply, "
1456 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001457
1458 out.unindent();
1459 out.unindent();
1460
1461 out.unindent();
1462 out << "}\n";
1463
1464 out.unindent();
1465 out << "}\n\n";
1466
Yifan Honga018ed52016-12-13 16:35:08 -08001467 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1468 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1469 out.indent(2, [&] {
1470 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1471 out << "_hidl_reply);\n";
1472 });
1473 });
Andreas Huber881227d2016-08-02 14:20:21 -07001474
Iliyan Malchev549e2592016-08-10 08:59:12 -07001475 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001476
1477 out.unindent();
1478 out << "}\n\n";
1479
1480 return OK;
1481}
1482
1483status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001484 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001485 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1486 method->cppImpl(IMPL_STUB, out);
1487 out << "break;\n";
1488 return OK;
1489 }
1490
Yifan Hongeefe4f22017-01-04 15:32:42 -08001491 out << "if (!_hidl_data.enforceInterface("
1492 << iface->fullName()
1493 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001494
Andreas Huber881227d2016-08-02 14:20:21 -07001495 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001496 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001497 out << "break;\n";
1498 out.unindent();
1499 out << "}\n\n";
1500
Andreas Huber5e44a292016-09-27 14:52:39 -07001501 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001502
Yifan Hongbf459bc2016-08-23 16:50:37 -07001503 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001504 for (const auto &arg : method->args()) {
1505 emitCppReaderWriter(
1506 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001507 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001508 false /* parcelObjIsPointer */,
1509 arg,
1510 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001511 Type::ErrorMode_Break,
1512 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001513 }
1514
Yifan Hongbf459bc2016-08-23 16:50:37 -07001515 // Second DFS: resolve references
1516 for (const auto &arg : method->args()) {
1517 emitCppResolveReferences(
1518 out,
1519 "_hidl_data",
1520 false /* parcelObjIsPointer */,
1521 arg,
1522 true /* reader */,
1523 Type::ErrorMode_Break,
1524 false /* addPrefixToName */);
1525 }
1526
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001527 status_t status = generateCppInstrumentationCall(
1528 out,
1529 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001530 method);
1531 if (status != OK) {
1532 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001533 }
1534
Andreas Huber881227d2016-08-02 14:20:21 -07001535 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001536 const TypedVar *elidedReturn = method->canElideCallback();
Andreas Huber881227d2016-08-02 14:20:21 -07001537
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001538 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001539 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001540 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001541 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001542 << " = "
1543 << "_hidl_mImpl->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001544 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001545
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001546 bool first = true;
1547 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001548 if (!first) {
1549 out << ", ";
1550 }
1551
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001552 if (arg->type().resultNeedsDeref()) {
1553 out << "*";
1554 }
1555
1556 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001557
1558 first = false;
1559 }
1560
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001561 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001562 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1563 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001564
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001565 elidedReturn->type().emitReaderWriter(
1566 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001567 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001568 "_hidl_reply",
1569 true, /* parcelObjIsPointer */
1570 false, /* isReader */
1571 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001572
Yifan Hongbf459bc2016-08-23 16:50:37 -07001573 emitCppResolveReferences(
1574 out,
1575 "_hidl_reply",
1576 true /* parcelObjIsPointer */,
1577 elidedReturn,
1578 false /* reader */,
1579 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001580 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001581
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001582 status_t status = generateCppInstrumentationCall(
1583 out,
1584 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001585 method);
1586 if (status != OK) {
1587 return status;
1588 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001589
Iliyan Malchev549e2592016-08-10 08:59:12 -07001590 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001591 } else {
1592 if (returnsValue) {
1593 out << "bool _hidl_callbackCalled = false;\n\n";
1594 }
Andreas Huber881227d2016-08-02 14:20:21 -07001595
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001596 out << "_hidl_mImpl->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001597
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001598 bool first = true;
1599 for (const auto &arg : method->args()) {
1600 if (!first) {
1601 out << ", ";
1602 }
Andreas Huber881227d2016-08-02 14:20:21 -07001603
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001604 if (arg->type().resultNeedsDeref()) {
1605 out << "*";
1606 }
1607
1608 out << arg->name();
1609
1610 first = false;
1611 }
1612
1613 if (returnsValue) {
1614 if (!first) {
1615 out << ", ";
1616 }
1617
1618 out << "[&](";
1619
1620 first = true;
1621 for (const auto &arg : method->results()) {
1622 if (!first) {
1623 out << ", ";
1624 }
1625
Yifan Honga47eef32016-12-12 10:38:54 -08001626 out << "const auto &_hidl_out_" << arg->name();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001627
1628 first = false;
1629 }
1630
1631 out << ") {\n";
1632 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001633 out << "if (_hidl_callbackCalled) {\n";
1634 out.indent();
1635 out << "LOG_ALWAYS_FATAL(\""
1636 << method->name()
1637 << ": _hidl_cb called a second time, but must be called once.\");\n";
1638 out.unindent();
1639 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001640 out << "_hidl_callbackCalled = true;\n\n";
1641
Yifan Hong859e53f2016-11-14 19:08:24 -08001642 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1643 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001644
Yifan Hongbf459bc2016-08-23 16:50:37 -07001645 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001646 for (const auto &arg : method->results()) {
1647 emitCppReaderWriter(
1648 out,
1649 "_hidl_reply",
1650 true /* parcelObjIsPointer */,
1651 arg,
1652 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001653 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001654 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001655 }
1656
Yifan Hongbf459bc2016-08-23 16:50:37 -07001657 // Second DFS: resolve references
1658 for (const auto &arg : method->results()) {
1659 emitCppResolveReferences(
1660 out,
1661 "_hidl_reply",
1662 true /* parcelObjIsPointer */,
1663 arg,
1664 false /* reader */,
1665 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001666 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001667 }
1668
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001669 status_t status = generateCppInstrumentationCall(
1670 out,
1671 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001672 method);
1673 if (status != OK) {
1674 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001675 }
1676
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001677 out << "_hidl_cb(*_hidl_reply);\n";
1678
1679 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001680 out << "});\n\n";
1681 } else {
1682 out << ");\n\n";
1683 status_t status = generateCppInstrumentationCall(
1684 out,
1685 InstrumentationEvent::SERVER_API_EXIT,
1686 method);
1687 if (status != OK) {
1688 return status;
1689 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001690 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001691
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001692 if (returnsValue) {
1693 out << "if (!_hidl_callbackCalled) {\n";
1694 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001695 out << "LOG_ALWAYS_FATAL(\""
1696 << method->name()
1697 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001698 out.unindent();
1699 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001700 } else {
1701 out << "::android::hardware::writeToParcel("
1702 << "::android::hardware::Status::ok(), "
1703 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001704 }
Andreas Huber881227d2016-08-02 14:20:21 -07001705 }
1706
1707 out << "break;\n";
1708
1709 return OK;
1710}
1711
Steven Moreland69e7c702016-09-09 11:16:32 -07001712status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1713 std::string ifaceName;
1714 if (!AST::isInterface(&ifaceName)) {
1715 // types.hal does not get a stub header.
1716 return OK;
1717 }
1718
1719 const Interface *iface = mRootScope->getInterface();
1720
Yifan Hongeefe4f22017-01-04 15:32:42 -08001721 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001722
1723 bool supportOneway = iface->hasOnewayMethods();
1724
1725 std::string path = outputPath;
1726 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1727 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1728 path.append(klassName);
1729 path.append(".h");
1730
1731 CHECK(Coordinator::MakeParentHierarchy(path));
1732 FILE *file = fopen(path.c_str(), "w");
1733
1734 if (file == NULL) {
1735 return -errno;
1736 }
1737
1738 Formatter out(file);
1739
1740 const std::string guard = makeHeaderGuard(klassName);
1741
1742 out << "#ifndef " << guard << "\n";
1743 out << "#define " << guard << "\n\n";
1744
1745 std::vector<std::string> packageComponents;
1746 getPackageAndVersionComponents(
1747 &packageComponents, false /* cpp_compatible */);
1748
Yifan Hongb0949432016-12-15 15:32:24 -08001749 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001750 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001751
1752 generateCppPackageInclude(out, mPackage, ifaceName);
1753 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001754
Yifan Hong7a118f52016-12-07 11:21:15 -08001755 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001756 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001757 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001758 }
1759
1760 enterLeaveNamespace(out, true /* enter */);
1761 out << "\n";
1762
1763 out << "struct "
1764 << klassName
1765 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001766 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001767
1768 out.indent();
1769 out << "explicit "
1770 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001771 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001772 << ifaceName
1773 << "> impl);\n";
1774
Yifan Hong068c5522016-10-31 14:07:25 -07001775 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1776 return generatePassthroughMethod(out, method);
1777 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001778
1779 if (err != OK) {
1780 return err;
1781 }
1782
1783 out.unindent();
1784 out << "private:\n";
1785 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001786 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001787
1788 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001789 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001790
1791 out << "\n";
1792
1793 out << "::android::hardware::Return<void> addOnewayTask("
1794 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001795 }
1796
1797 out.unindent();
1798
1799 out << "};\n\n";
1800
1801 enterLeaveNamespace(out, false /* enter */);
1802
1803 out << "\n#endif // " << guard << "\n";
1804
1805 return OK;
1806}
1807
Yifan Hongfe95aa22016-10-19 17:26:45 -07001808status_t AST::generateInterfaceSource(Formatter &out) const {
1809 const Interface *iface = mRootScope->getInterface();
1810
Yifan Hong2d7126b2016-10-20 15:12:57 -07001811 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001812 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001813
Yifan Hong3d746092016-12-07 14:26:33 -08001814 for (const Interface *superType : iface->typeChain()) {
1815 out << "// static \n"
1816 << childTypeResult
Yifan Hongeefe4f22017-01-04 15:32:42 -08001817 << " "
1818 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001819 << "::castFrom("
1820 << superType->getCppArgumentType()
1821 << " parent) {\n";
1822 out.indent();
1823 if (iface == superType) {
1824 out << "return parent;\n";
1825 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001826 out << "return ::android::hardware::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001827 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001828 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001829 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001830 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001831 << ">(\n";
1832 out.indent();
1833 out.indent();
1834 out << "parent, \""
1835 << iface->fqName().string()
1836 << "\");\n";
1837 out.unindent();
1838 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001839 }
Yifan Hong3d746092016-12-07 14:26:33 -08001840 out.unindent();
1841 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001842 }
1843
1844 return OK;
1845}
1846
Steven Moreland69e7c702016-09-09 11:16:32 -07001847status_t AST::generatePassthroughSource(Formatter &out) const {
1848 const Interface *iface = mRootScope->getInterface();
1849
Yifan Hongeefe4f22017-01-04 15:32:42 -08001850 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001851
1852 out << klassName
1853 << "::"
1854 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001855 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001856 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001857 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001858 << mPackage.string()
1859 << "\", \""
1860 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001861 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001862 if (iface->hasOnewayMethods()) {
1863 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001864 out.indent([&] {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001865 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1866 });
1867 }
1868 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001869
1870 if (iface->hasOnewayMethods()) {
1871 out << "::android::hardware::Return<void> "
1872 << klassName
1873 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1874 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001875 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001876 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001877 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1878 out.indent();
1879 out.indent();
1880 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1881 out.unindent();
1882 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001883 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001884 out << "}\n";
1885
Steven Morelandd366c262016-10-11 15:29:10 -07001886 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001887
1888 out.unindent();
1889 out << "}\n\n";
1890
1891
1892 }
1893
1894 return OK;
1895}
1896
Martijn Coenen7b295242016-11-04 16:52:56 +01001897status_t AST::generateCppAtraceCall(Formatter &out,
1898 InstrumentationEvent event,
1899 const Method *method) const {
1900 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001901 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001902 switch (event) {
1903 case SERVER_API_ENTRY:
1904 {
1905 out << "atrace_begin(ATRACE_TAG_HAL, \""
1906 << baseString + "::server\");\n";
1907 break;
1908 }
1909 case CLIENT_API_ENTRY:
1910 {
1911 out << "atrace_begin(ATRACE_TAG_HAL, \""
1912 << baseString + "::client\");\n";
1913 break;
1914 }
1915 case PASSTHROUGH_ENTRY:
1916 {
1917 out << "atrace_begin(ATRACE_TAG_HAL, \""
1918 << baseString + "::passthrough\");\n";
1919 break;
1920 }
1921 case SERVER_API_EXIT:
1922 case CLIENT_API_EXIT:
1923 case PASSTHROUGH_EXIT:
1924 {
1925 out << "atrace_end(ATRACE_TAG_HAL);\n";
1926 break;
1927 }
1928 default:
1929 {
1930 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1931 return UNKNOWN_ERROR;
1932 }
1933 }
1934
1935 return OK;
1936}
1937
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001938status_t AST::generateCppInstrumentationCall(
1939 Formatter &out,
1940 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001941 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001942 status_t err = generateCppAtraceCall(out, event, method);
1943 if (err != OK) {
1944 return err;
1945 }
1946
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001947 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1948 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001949 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001950 std::string event_str = "";
1951 switch (event) {
1952 case SERVER_API_ENTRY:
1953 {
1954 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1955 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001956 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001957 << (arg->type().resultNeedsDeref() ? "" : "&")
1958 << arg->name()
1959 << ");\n";
1960 }
1961 break;
1962 }
1963 case SERVER_API_EXIT:
1964 {
1965 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001966 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001967 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001968 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001969 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001970 }
1971 break;
1972 }
1973 case CLIENT_API_ENTRY:
1974 {
1975 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1976 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001977 out << "_hidl_args.push_back((void *)&"
1978 << arg->name()
1979 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001980 }
1981 break;
1982 }
1983 case CLIENT_API_EXIT:
1984 {
1985 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1986 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001987 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001988 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001989 << "_hidl_out_"
1990 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001991 << ");\n";
1992 }
1993 break;
1994 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001995 case PASSTHROUGH_ENTRY:
1996 {
1997 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1998 for (const auto &arg : method->args()) {
1999 out << "_hidl_args.push_back((void *)&"
2000 << arg->name()
2001 << ");\n";
2002 }
2003 break;
2004 }
2005 case PASSTHROUGH_EXIT:
2006 {
2007 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002008 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002009 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002010 << arg->name()
2011 << ");\n";
2012 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002013 break;
2014 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002015 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002016 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002017 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002018 return UNKNOWN_ERROR;
2019 }
2020 }
2021
Steven Moreland031ccf12016-10-31 15:54:38 -07002022 const Interface *iface = mRootScope->getInterface();
2023
Steven Moreland1ab31442016-11-03 18:37:51 -07002024 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002025 out.indent();
2026 out << "callback("
2027 << event_str
2028 << ", \""
2029 << mPackage.package()
2030 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002031 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002032 << "\", \""
2033 << iface->localName()
2034 << "\", \""
2035 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002036 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002037 out.unindent();
2038 out << "}\n";
2039 out.unindent();
2040 out << "}\n\n";
2041
2042 return OK;
2043}
2044
Andreas Huber881227d2016-08-02 14:20:21 -07002045} // namespace android