blob: 9a51ff9d3dc71e9862d2f4e35dd88ece5c886a16 [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 || "
Steven Moreland15835172017-01-30 16:21:42 -0800167 "transport == ::android::vintf::Transport::TOGGLED || "
Steven Morelandf10af872017-01-25 16:01:56 +0000168 // TODO(b/34625838): Don't load in passthrough mode
169 "transport == ::android::vintf::Transport::PASSTHROUGH || "
170 "transport == ::android::vintf::Transport::EMPTY)", [&] {
171 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800172 out.indent(2, [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000173 out << "= ::android::hardware::defaultServiceManager();\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800174 });
Steven Morelandf10af872017-01-25 16:01:56 +0000175 out.sIf("sm != nullptr", [&] {
Steven Morelandbec74ed2017-01-25 17:42:35 -0800176 // TODO(b/34274385) remove sysprop check
Steven Moreland15835172017-01-30 16:21:42 -0800177 out.sIf("transport == ::android::vintf::Transport::HWBINDER ||"
178 "(transport == ::android::vintf::Transport::TOGGLED &&"
179 " ::android::hardware::details::blockingHalBinderizationEnabled())", [&]() {
Steven Moreland6d7b91c2017-01-24 18:58:07 -0800180 out << "::android::hardware::details::waitForHwService("
181 << interfaceName << "::descriptor" << ", serviceName);\n";
182 }).endl();
Steven Morelandf10af872017-01-25 16:01:56 +0000183 out << "::android::hardware::Return<::android::sp<" << gIBaseFqName.cppName() << ">> ret = \n";
184 out.indent(2, [&] {
185 out << "sm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
186 });
187 out.sIf("ret.isOk()", [&] {
188 out << "iface = " << interfaceName << "::castFrom(ret);\n";
189 out.sIf("iface != nullptr", [&] {
190 out << "return iface;\n";
191 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800192 }).endl();
193 }).endl();
194 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800195
Steven Morelandf10af872017-01-25 16:01:56 +0000196 out.sIf("getStub || "
197 "transport == ::android::vintf::Transport::PASSTHROUGH || "
Steven Moreland15835172017-01-30 16:21:42 -0800198 "(transport == ::android::vintf::Transport::TOGGLED &&"
Steven Morelandbec74ed2017-01-25 17:42:35 -0800199 " !::android::hardware::details::blockingHalBinderizationEnabled()) ||"
Steven Morelandf10af872017-01-25 16:01:56 +0000200 "transport == ::android::vintf::Transport::EMPTY", [&] {
201 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> pm\n";
Steven Morelande3fa5da2017-01-25 07:07:53 +0000202 out.indent(2, [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000203 out << "= ::android::hardware::getPassthroughServiceManager();\n";
Steven Morelande3fa5da2017-01-25 07:07:53 +0000204 });
Steven Morelandf10af872017-01-25 16:01:56 +0000205
206 out.sIf("pm != nullptr", [&] () {
207 out << "::android::hardware::Return<::android::sp<" << gIBaseFqName.cppName() << ">> ret = \n";
208 out.indent(2, [&] {
209 out << "pm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
Steven Moreland2c2dea82017-01-18 17:24:17 -0800210 });
Steven Morelandf10af872017-01-25 16:01:56 +0000211 out.sIf("ret.isOk()", [&] {
212 out << "::android::sp<" << gIBaseFqName.cppName()
213 << "> baseInterface = ret;\n";
214 out.sIf("baseInterface != nullptr", [&]() {
215 out << "iface = new " << fqName.getInterfacePassthroughName()
216 << "(" << interfaceName << "::castFrom(baseInterface));\n";
217 });
218 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800219 }).endl();
220 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800221
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800222 out << "return iface;\n";
223 }).endl().endl();
224
Yifan Hongeefe4f22017-01-04 15:32:42 -0800225 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800226 << "const std::string &serviceName) ";
227 out.block([&] {
228 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
229 out.indent(2, [&] {
230 out << "= ::android::hardware::defaultServiceManager();\n";
231 });
232 out.sIf("sm == nullptr", [&] {
233 out << "return ::android::INVALID_OPERATION;\n";
234 }).endl();
235 out << "bool success = false;\n"
236 << "::android::hardware::Return<void> ret =\n";
237 out.indent(2, [&] {
238 out << "this->interfaceChain("
239 << "[&success, &sm, &serviceName, this](const auto &chain) ";
240 out.block([&] {
241 out << "::android::hardware::Return<bool> addRet = "
242 << "sm->add(chain, serviceName.c_str(), this);\n";
243 out << "success = addRet.isOk() && addRet;\n";
244 });
245 out << ");\n";
Steven Morelandcd00b9b2016-12-29 10:34:03 -0800246 out << "success = success && ret.isOk();\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800247 });
248 out << "return success ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
249 }).endl().endl();
250
Yifan Hongeefe4f22017-01-04 15:32:42 -0800251 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800252 out.indent(2, [&] {
253 out << "const std::string &serviceName,\n"
254 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
255 << "&notification) ";
256 });
257 out.block([&] {
258 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
259 out.indent(2, [&] {
260 out << "= ::android::hardware::defaultServiceManager();\n";
261 });
262 out.sIf("sm == nullptr", [&] {
263 out << "return false;\n";
264 }).endl();
265 out << "::android::hardware::Return<bool> success =\n";
266 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800267 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800268 out.indent(2, [&] {
269 out << "serviceName, notification);\n";
270 });
271 });
272 out << "return success.isOk() && success;\n";
273 }).endl().endl();
274}
275
Andreas Huberb82318c2016-08-02 14:45:54 -0700276status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700277
Andreas Huberb82318c2016-08-02 14:45:54 -0700278 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700279 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700280 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700281
282 std::string ifaceName;
283 bool isInterface = true;
284 if (!AST::isInterface(&ifaceName)) {
285 ifaceName = "types";
286 isInterface = false;
287 }
288 path.append(ifaceName);
289 path.append(".h");
290
Andreas Huberd2943e12016-08-05 11:59:31 -0700291 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700292 FILE *file = fopen(path.c_str(), "w");
293
294 if (file == NULL) {
295 return -errno;
296 }
297
298 Formatter out(file);
299
300 const std::string guard = makeHeaderGuard(ifaceName);
301
302 out << "#ifndef " << guard << "\n";
303 out << "#define " << guard << "\n\n";
304
Andreas Huber737080b2016-08-02 15:38:04 -0700305 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700306 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700307 }
308
309 if (!mImportedNames.empty()) {
310 out << "\n";
311 }
312
Steven Moreland0693f312016-11-09 15:06:14 -0800313 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800314 if (isIBase()) {
315 out << "// skipped #include IServiceNotification.h\n\n";
316 } else {
317 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
318 }
Steven Moreland0693f312016-11-09 15:06:14 -0800319 }
320
Yifan Hongc8934042016-11-17 17:10:52 -0800321 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700322 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700323
324 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200325 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700326 }
327
Martijn Coenenaf712c02016-11-16 15:26:27 +0100328 out << "#include <utils/NativeHandle.h>\n";
329 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700330
331 enterLeaveNamespace(out, true /* enter */);
332 out << "\n";
333
334 if (isInterface) {
335 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700336 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700337
338 const Interface *iface = mRootScope->getInterface();
339 const Interface *superType = iface->superType();
340
Steven Moreland40786312016-08-16 10:29:40 -0700341 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800342 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700343 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000344 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700345 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700346 }
347
348 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700349
350 out.indent();
351
Andreas Huber881227d2016-08-02 14:20:21 -0700352 }
353
354 status_t err = emitTypeDeclarations(out);
355
356 if (err != OK) {
357 return err;
358 }
359
360 if (isInterface) {
361 const Interface *iface = mRootScope->getInterface();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700362 const Interface *superType = iface->superType();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800363
Yifan Hongc8934042016-11-17 17:10:52 -0800364 out << "virtual bool isRemote() const ";
365 if (!isIBase()) {
366 out << "override ";
367 }
368 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800369
Andreas Huber881227d2016-08-02 14:20:21 -0700370 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700371 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700372
Andreas Huber881227d2016-08-02 14:20:21 -0700373 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800374 const TypedVar *elidedReturn = method->canElideCallback();
375
376 if (elidedReturn == nullptr && returnsValue) {
377 out << "using "
378 << method->name()
379 << "_cb = std::function<void("
380 << Method::GetArgSignature(method->results(),
381 true /* specify namespaces */)
382 << ")>;\n";
383 }
Andreas Huber881227d2016-08-02 14:20:21 -0700384
Andreas Huber3599d922016-08-09 10:42:57 -0700385 method->dumpAnnotations(out);
386
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700387 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700388 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700389 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700390 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700391 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700392 }
393
394 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700395 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700396 << Method::GetArgSignature(method->args(),
397 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700398
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700399 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700400 if (!method->args().empty()) {
401 out << ", ";
402 }
403
Steven Moreland67f67b42016-09-29 08:59:02 -0700404 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700405 }
406
Yifan Hong10fe0b52016-10-19 14:20:17 -0700407 out << ")";
408 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800409 if (!isIBase()) {
410 out << " override";
411 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700412 out << " {\n";
413 out.indent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100414 method->cppImpl(IMPL_HEADER, out);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700415 out.unindent();
416 out << "\n}\n";
417 } else {
418 out << " = 0;\n";
419 }
Andreas Huber881227d2016-08-02 14:20:21 -0700420 }
Steven Moreland40786312016-08-16 10:29:40 -0700421
Yifan Hong3d746092016-12-07 14:26:33 -0800422 out << "// cast static functions\n";
423 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700424
Yifan Hong3d746092016-12-07 14:26:33 -0800425 for (const Interface *superType : iface->typeChain()) {
426 out << "static "
427 << childTypeResult
428 << " castFrom("
429 << superType->getCppArgumentType()
430 << " parent"
431 << ");\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700432 }
433
Steven Morelandd39133b2016-11-11 12:30:08 -0800434 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700435
Yifan Hongc8934042016-11-17 17:10:52 -0800436 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800437 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800438 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800439 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800440 }
Yifan Hong158655a2016-11-08 12:34:07 -0800441
442 out << "private: static int hidlStaticBlock;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700443 }
444
445 if (isInterface) {
446 out.unindent();
447
Andreas Hubere3f769a2016-10-10 10:54:44 -0700448 out << "};\n\n";
449 }
450
451 err = mRootScope->emitGlobalTypeDeclarations(out);
452
453 if (err != OK) {
454 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700455 }
456
457 out << "\n";
458 enterLeaveNamespace(out, false /* enter */);
459
460 out << "\n#endif // " << guard << "\n";
461
462 return OK;
463}
464
Steven Moreland40786312016-08-16 10:29:40 -0700465status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
466 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800467 bool isInterface = AST::isInterface(&ifaceName);
468 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800469 std::string klassName{};
470
471 if(isInterface) {
472 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800473 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800474 } else {
475 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700476 }
477
Steven Moreland40786312016-08-16 10:29:40 -0700478 std::string path = outputPath;
479 path.append(mCoordinator->convertPackageRootToPath(mPackage));
480 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
481 path.append(klassName + ".h");
482
Yifan Hong244e82d2016-11-11 11:13:57 -0800483 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700484
485 if (file == NULL) {
486 return -errno;
487 }
488
489 Formatter out(file);
490
491 const std::string guard = makeHeaderGuard(klassName);
492
493 out << "#ifndef " << guard << "\n";
494 out << "#define " << guard << "\n\n";
495
Yifan Hong244e82d2016-11-11 11:13:57 -0800496 if (isInterface) {
497 generateCppPackageInclude(out, mPackage, ifaceName);
498 } else {
499 generateCppPackageInclude(out, mPackage, "types");
500 }
Steven Moreland40786312016-08-16 10:29:40 -0700501
Steven Morelandee88eed2016-10-31 17:49:00 -0700502 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700503
504 for (const auto &item : mImportedNames) {
505 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800506 generateCppPackageInclude(out, item, "hwtypes");
507 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800508 generateCppPackageInclude(out, item, item.getInterfaceStubName());
509 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700510 }
Steven Moreland40786312016-08-16 10:29:40 -0700511 }
512
513 out << "\n";
514
Martijn Coenen93915102016-09-01 01:35:52 +0200515 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700516 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100517 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700518
519 out << "\n";
520
521 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700522
Yifan Hong244e82d2016-11-11 11:13:57 -0800523 status_t err = mRootScope->emitGlobalHwDeclarations(out);
524 if (err != OK) {
525 return err;
526 }
Steven Moreland40786312016-08-16 10:29:40 -0700527
528 enterLeaveNamespace(out, false /* enter */);
529
530 out << "\n#endif // " << guard << "\n";
531
532 return OK;
533}
534
Andreas Huber881227d2016-08-02 14:20:21 -0700535status_t AST::emitTypeDeclarations(Formatter &out) const {
536 return mRootScope->emitTypeDeclarations(out);
537}
538
Yifan Hong7a118f52016-12-07 11:21:15 -0800539static void wrapPassthroughArg(Formatter &out,
540 const TypedVar *arg, bool addPrefixToName,
541 std::function<void(void)> handleError) {
542 if (!arg->type().isInterface()) {
543 return;
544 }
545 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
546 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
547 + arg->name();
548 const Interface &iface = static_cast<const Interface &>(arg->type());
549 out << iface.getCppStackType() << " " << wrappedName << ";\n";
550 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
551 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
552 out << wrappedName
553 << " = "
554 << iface.fqName().cppName()
555 << "::castFrom(::android::hardware::wrapPassthrough("
556 << name << "));\n";
557 out.sIf(wrappedName + " == nullptr", [&] {
558 // Fatal error. Happens when the BsFoo class is not found in the binary
559 // or any dynamic libraries.
560 handleError();
561 }).endl();
562 }).sElse([&] {
563 out << wrappedName << " = " << name << ";\n";
564 }).endl().endl();
565}
566
Steven Moreland69e7c702016-09-09 11:16:32 -0700567status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700568 const Method *method) const {
569 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700570
571 out << " {\n";
572 out.indent();
573
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800574 if (method->isHidlReserved()
575 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
576 method->cppImpl(IMPL_PASSTHROUGH, out);
577 out.unindent();
578 out << "}\n\n";
579 return OK;
580 }
581
Steven Moreland69e7c702016-09-09 11:16:32 -0700582 const bool returnsValue = !method->results().empty();
583 const TypedVar *elidedReturn = method->canElideCallback();
584
Steven Moreland67f67b42016-09-29 08:59:02 -0700585 if (returnsValue && elidedReturn == nullptr) {
586 generateCheckNonNull(out, "_hidl_cb");
587 }
588
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700589 generateCppInstrumentationCall(
590 out,
591 InstrumentationEvent::PASSTHROUGH_ENTRY,
592 method);
593
Yifan Hong7a118f52016-12-07 11:21:15 -0800594
595 for (const auto &arg : method->args()) {
596 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
597 out << "return ::android::hardware::Status::fromExceptionCode(\n";
598 out.indent(2, [&] {
599 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800600 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800601 });
602 });
603 }
604
605 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700606 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700607
608 if (method->isOneway()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800609 out << "addOnewayTask([this, &_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700610 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800611 out << ", "
612 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
613 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700614 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700615 out << "] {\n";
616 out.indent();
617 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700618 }
619
620 out << "mImpl->"
621 << method->name()
622 << "(";
623
624 bool first = true;
625 for (const auto &arg : method->args()) {
626 if (!first) {
627 out << ", ";
628 }
629 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800630 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700631 }
632 if (returnsValue && elidedReturn == nullptr) {
633 if (!method->args().empty()) {
634 out << ", ";
635 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800636 out << "[&](";
637 first = true;
638 for (const auto &arg : method->results()) {
639 if (!first) {
640 out << ", ";
641 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700642
Yifan Hong7a118f52016-12-07 11:21:15 -0800643 out << "const auto &_hidl_out_"
644 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800645
646 first = false;
647 }
648
649 out << ") {\n";
650 out.indent();
651 status_t status = generateCppInstrumentationCall(
652 out,
653 InstrumentationEvent::PASSTHROUGH_EXIT,
654 method);
655 if (status != OK) {
656 return status;
657 }
658
Yifan Hong7a118f52016-12-07 11:21:15 -0800659 for (const auto &arg : method->results()) {
660 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
661 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
662 out.indent(2, [&] {
663 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800664 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800665 });
666 out << "return;\n";
667 });
668 }
669
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800670 out << "_hidl_cb(";
671 first = true;
672 for (const auto &arg : method->results()) {
673 if (!first) {
674 out << ", ";
675 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800676 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800677 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
678 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800679 }
680 out << ");\n";
681 out.unindent();
682 out << "});\n\n";
683 } else {
684 out << ");\n\n";
685 if (elidedReturn != nullptr) {
686 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800687 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800688 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000689 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800690 }
691 status_t status = generateCppInstrumentationCall(
692 out,
693 InstrumentationEvent::PASSTHROUGH_EXIT,
694 method);
695 if (status != OK) {
696 return status;
697 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700698 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700699
700 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700701 out.unindent();
702 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700703 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700704
705 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700706
707 out.unindent();
708 out << "}\n";
709
710 return OK;
711}
712
Yifan Hong068c5522016-10-31 14:07:25 -0700713status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700714
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700715 const Interface *iface = mRootScope->getInterface();
716
Yifan Hong10fe0b52016-10-19 14:20:17 -0700717 const Interface *prevIterface = nullptr;
718 for (const auto &tuple : iface->allMethodsFromRoot()) {
719 const Method *method = tuple.method();
720 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700721
Yifan Hong10fe0b52016-10-19 14:20:17 -0700722 if(prevIterface != superInterface) {
723 if (prevIterface != nullptr) {
724 out << "\n";
725 }
726 out << "// Methods from "
727 << superInterface->fullName()
728 << " follow.\n";
729 prevIterface = superInterface;
730 }
Yifan Hong068c5522016-10-31 14:07:25 -0700731 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700732
Yifan Hong10fe0b52016-10-19 14:20:17 -0700733 if (err != OK) {
734 return err;
735 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700736 }
737
Yifan Hong10fe0b52016-10-19 14:20:17 -0700738 out << "\n";
739
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700740 return OK;
741}
742
Andreas Huberb82318c2016-08-02 14:45:54 -0700743status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700744 std::string ifaceName;
745 if (!AST::isInterface(&ifaceName)) {
746 // types.hal does not get a stub header.
747 return OK;
748 }
749
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700750 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800751 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700752
Andreas Huberb82318c2016-08-02 14:45:54 -0700753 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700754 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700755 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700756 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700757 path.append(".h");
758
Andreas Huberd2943e12016-08-05 11:59:31 -0700759 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700760 FILE *file = fopen(path.c_str(), "w");
761
762 if (file == NULL) {
763 return -errno;
764 }
765
766 Formatter out(file);
767
Steven Moreland40786312016-08-16 10:29:40 -0700768 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700769
770 out << "#ifndef " << guard << "\n";
771 out << "#define " << guard << "\n\n";
772
Yifan Hongeefe4f22017-01-04 15:32:42 -0800773 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700774 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700775
776 enterLeaveNamespace(out, true /* enter */);
777 out << "\n";
778
779 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800780 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100781 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800782 out << " : public ::android::hardware::BHwBinder";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100783 out << ", public ::android::hardware::HidlInstrumentor {\n";
784 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800785 out << " : public "
786 << gIBaseFqName.getInterfaceStubFqName().cppName()
787 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100788 }
Andreas Huber881227d2016-08-02 14:20:21 -0700789
790 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800791 out << "explicit "
792 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700793 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100794 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800795 out << "explicit "
796 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100797 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800798 << " const std::string& HidlInstrumentor_package,"
799 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700800 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700801 out << "::android::status_t onTransact(\n";
802 out.indent();
803 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700804 out << "uint32_t _hidl_code,\n";
805 out << "const ::android::hardware::Parcel &_hidl_data,\n";
806 out << "::android::hardware::Parcel *_hidl_reply,\n";
807 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700808 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700809 out.unindent();
810 out.unindent();
811
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100812 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
813 out.unindent();
814 out << "private:\n";
815 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800816
817 status_t err = generateMethods(out, [&](const Method *method, const Interface *iface) {
818 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
819 return OK;
820 }
821 const bool returnsValue = !method->results().empty();
822 const TypedVar *elidedReturn = method->canElideCallback();
823
824 if (elidedReturn == nullptr && returnsValue) {
825 out << "using " << method->name() << "_cb = "
826 << iface->fqName().cppName()
827 << "::" << method->name() << "_cb;\n";
828 }
829 method->generateCppSignature(out);
830 out << " ";
831 out.block([&] {
832 method->cppImpl(IMPL_STUB_IMPL, out);
833 out << "\n";
834 }).endl();
835 return OK;
836 });
837 if (err != OK) {
838 return err;
839 }
840
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100841 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700842 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700843 out << "};\n\n";
844
845 enterLeaveNamespace(out, false /* enter */);
846
847 out << "\n#endif // " << guard << "\n";
848
849 return OK;
850}
851
Andreas Huberb82318c2016-08-02 14:45:54 -0700852status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700853 std::string ifaceName;
854 if (!AST::isInterface(&ifaceName)) {
855 // types.hal does not get a proxy header.
856 return OK;
857 }
858
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700859 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800860 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700861
Andreas Huberb82318c2016-08-02 14:45:54 -0700862 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700863 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700864 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800865 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700866 path.append(".h");
867
Andreas Huberd2943e12016-08-05 11:59:31 -0700868 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700869 FILE *file = fopen(path.c_str(), "w");
870
871 if (file == NULL) {
872 return -errno;
873 }
874
875 Formatter out(file);
876
Yifan Hongeefe4f22017-01-04 15:32:42 -0800877 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700878
879 out << "#ifndef " << guard << "\n";
880 out << "#define " << guard << "\n\n";
881
Martijn Coenen115d4282016-12-19 05:14:04 +0100882 out << "#include <hidl/HidlTransportSupport.h>\n\n";
883
Andreas Huber881227d2016-08-02 14:20:21 -0700884 std::vector<std::string> packageComponents;
885 getPackageAndVersionComponents(
886 &packageComponents, false /* cpp_compatible */);
887
Yifan Hongeefe4f22017-01-04 15:32:42 -0800888 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700889 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700890
891 enterLeaveNamespace(out, true /* enter */);
892 out << "\n";
893
894 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800895 << proxyName
896 << " : public ::android::hardware::BpInterface<"
897 << iface->localName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700898 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700899
900 out.indent();
901
Yifan Hongeefe4f22017-01-04 15:32:42 -0800902 out << "explicit "
903 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700904 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700905 << "\n\n";
906
Yifan Hong10fe0b52016-10-19 14:20:17 -0700907 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700908
Yifan Hong068c5522016-10-31 14:07:25 -0700909 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
910 method->generateCppSignature(out);
911 out << " override;\n";
912 return OK;
913 });
Steven Moreland9c387612016-09-07 09:54:26 -0700914
915 if (err != OK) {
916 return err;
917 }
Andreas Huber881227d2016-08-02 14:20:21 -0700918
919 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100920 out << "private:\n";
921 out.indent();
922 out << "std::mutex _hidl_mMutex;\n"
923 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
924 << " _hidl_mDeathRecipients;\n";
925 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700926 out << "};\n\n";
927
928 enterLeaveNamespace(out, false /* enter */);
929
930 out << "\n#endif // " << guard << "\n";
931
932 return OK;
933}
934
Andreas Huberb82318c2016-08-02 14:45:54 -0700935status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700936
Andreas Huberb82318c2016-08-02 14:45:54 -0700937 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700938 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700939 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700940
941 std::string ifaceName;
942 std::string baseName;
943
Yifan Hongfe95aa22016-10-19 17:26:45 -0700944 const Interface *iface = nullptr;
945 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700946 if (!AST::isInterface(&ifaceName)) {
947 baseName = "types";
948 isInterface = false;
949 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700950 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700951 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700952 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700953 }
954
955 path.append(baseName);
956
957 if (baseName != "types") {
958 path.append("All");
959 }
960
961 path.append(".cpp");
962
Andreas Huberd2943e12016-08-05 11:59:31 -0700963 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700964 FILE *file = fopen(path.c_str(), "w");
965
966 if (file == NULL) {
967 return -errno;
968 }
969
970 Formatter out(file);
971
Steven Moreland623c0042017-01-13 14:42:29 -0800972 out << "#define LOG_TAG \""
973 << mPackage.string() << "::" << baseName
974 << "\"\n\n";
975
Steven Moreland05cd4232016-11-21 16:01:12 -0800976 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100977 out << "#include <cutils/trace.h>\n";
978 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700979 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700980 // This is a no-op for IServiceManager itself.
981 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
982
Steven Morelandbec74ed2017-01-25 17:42:35 -0800983 // TODO(b/34274385) remove this
984 out << "#include <hidl/LegacySupport.h>\n";
985
Yifan Hongeefe4f22017-01-04 15:32:42 -0800986 generateCppPackageInclude(out, mPackage, iface->getProxyName());
987 generateCppPackageInclude(out, mPackage, iface->getStubName());
988 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700989
990 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700991 generateCppPackageInclude(out,
992 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800993 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700994 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800995
996 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700997 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700998 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800999 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -07001000 }
1001
1002 out << "\n";
1003
1004 enterLeaveNamespace(out, true /* enter */);
1005 out << "\n";
1006
1007 status_t err = generateTypeSource(out, ifaceName);
1008
1009 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001010 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001011
1012 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -08001013 out << "const char* "
1014 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -07001015 << "::descriptor(\""
1016 << iface->fqName().string()
1017 << "\");\n\n";
1018
Yifan Hongeefe4f22017-01-04 15:32:42 -08001019 out << "int "
1020 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001021 << "::hidlStaticBlock = []() -> int {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001022 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001023 out << "::android::hardware::gBnConstructorMap["
1024 << iface->localName()
Steven Morelandd39133b2016-11-11 12:30:08 -08001025 << "::descriptor]\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001026 out.indent(2, [&] {
Yifan Hong158655a2016-11-08 12:34:07 -08001027 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001028 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001029 out << "return new "
1030 << iface->getStubName()
1031 << "(reinterpret_cast<"
1032 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001033 << " *>(iIntf));\n";
1034 });
1035 out << "};\n";
1036 });
Yifan Hongeefe4f22017-01-04 15:32:42 -08001037 out << "::android::hardware::gBsConstructorMap["
1038 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001039 << "::descriptor]\n";
1040 out.indent(2, [&] {
1041 out << "= [](void *iIntf) -> ::android::sp<"
1042 << gIBaseFqName.cppName()
1043 << "> {\n";
1044 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001045 out << "return new "
1046 << iface->getPassthroughName()
1047 << "(reinterpret_cast<"
1048 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001049 << " *>(iIntf));\n";
1050 });
1051 out << "};\n";
1052 });
Yifan Hong158655a2016-11-08 12:34:07 -08001053 out << "return 1;\n";
1054 });
1055 out << "}();\n\n";
1056
Yifan Hongfe95aa22016-10-19 17:26:45 -07001057 err = generateInterfaceSource(out);
1058 }
1059
1060 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001061 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001062 }
1063
1064 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001065 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001066 }
1067
Steven Moreland40786312016-08-16 10:29:40 -07001068 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001069 err = generatePassthroughSource(out);
1070 }
1071
1072 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001073 const Interface *iface = mRootScope->getInterface();
1074
Yifan Hongc8934042016-11-17 17:10:52 -08001075 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001076 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001077 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001078 std::string package = iface->fqName().package()
1079 + iface->fqName().atVersion();
1080
Yifan Hongeefe4f22017-01-04 15:32:42 -08001081 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001082 }
Steven Moreland40786312016-08-16 10:29:40 -07001083 }
1084
Andreas Huber881227d2016-08-02 14:20:21 -07001085 enterLeaveNamespace(out, false /* enter */);
1086
1087 return err;
1088}
1089
Steven Moreland67f67b42016-09-29 08:59:02 -07001090// static
1091void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001092 out.sIf(nonNull + " == nullptr", [&] {
1093 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1094 out.indent(2, [&] {
1095 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1096 });
1097 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001098}
1099
Andreas Huber881227d2016-08-02 14:20:21 -07001100status_t AST::generateTypeSource(
1101 Formatter &out, const std::string &ifaceName) const {
1102 return mRootScope->emitTypeDefinitions(out, ifaceName);
1103}
1104
Andreas Hubere7ff2282016-08-16 13:50:03 -07001105void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001106 Formatter &out,
1107 const std::vector<TypedVar *> &args,
1108 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001109 if (args.empty()) {
1110 return;
1111 }
1112
1113 for (const auto &arg : args) {
1114 const Type &type = arg->type();
1115
Yifan Hong3b320f82016-11-01 15:15:54 -07001116 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001117 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001118 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001119 << ";\n";
1120 }
1121
1122 out << "\n";
1123}
1124
Andreas Huber881227d2016-08-02 14:20:21 -07001125void AST::emitCppReaderWriter(
1126 Formatter &out,
1127 const std::string &parcelObj,
1128 bool parcelObjIsPointer,
1129 const TypedVar *arg,
1130 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001131 Type::ErrorMode mode,
1132 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001133 const Type &type = arg->type();
1134
Andreas Huber881227d2016-08-02 14:20:21 -07001135 type.emitReaderWriter(
1136 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001137 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001138 parcelObj,
1139 parcelObjIsPointer,
1140 isReader,
1141 mode);
1142}
1143
Yifan Hongbf459bc2016-08-23 16:50:37 -07001144void AST::emitCppResolveReferences(
1145 Formatter &out,
1146 const std::string &parcelObj,
1147 bool parcelObjIsPointer,
1148 const TypedVar *arg,
1149 bool isReader,
1150 Type::ErrorMode mode,
1151 bool addPrefixToName) const {
1152 const Type &type = arg->type();
1153 if(type.needsResolveReferences()) {
1154 type.emitResolveReferences(
1155 out,
1156 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1157 isReader, // nameIsPointer
1158 parcelObj,
1159 parcelObjIsPointer,
1160 isReader,
1161 mode);
1162 }
1163}
1164
Yifan Hong068c5522016-10-31 14:07:25 -07001165status_t AST::generateProxyMethodSource(Formatter &out,
1166 const std::string &klassName,
1167 const Method *method,
1168 const Interface *superInterface) const {
1169
1170 method->generateCppSignature(out,
1171 klassName,
1172 true /* specify namespaces */);
1173
1174 const bool returnsValue = !method->results().empty();
1175 const TypedVar *elidedReturn = method->canElideCallback();
1176
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001177 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001178
1179 out.indent();
1180
Martijn Coenen115d4282016-12-19 05:14:04 +01001181 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1182 method->cppImpl(IMPL_PROXY, out);
1183 out.unindent();
1184 out << "}\n\n";
1185 return OK;
1186 }
1187
Yifan Hong068c5522016-10-31 14:07:25 -07001188 if (returnsValue && elidedReturn == nullptr) {
1189 generateCheckNonNull(out, "_hidl_cb");
1190 }
1191
1192 status_t status = generateCppInstrumentationCall(
1193 out,
1194 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001195 method);
1196 if (status != OK) {
1197 return status;
1198 }
1199
1200 out << "::android::hardware::Parcel _hidl_data;\n";
1201 out << "::android::hardware::Parcel _hidl_reply;\n";
1202 out << "::android::status_t _hidl_err;\n";
1203 out << "::android::hardware::Status _hidl_status;\n\n";
1204
1205 declareCppReaderLocals(
1206 out, method->results(), true /* forResults */);
1207
1208 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001209 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001210 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001211 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1212
Martijn Coenenfff73352017-01-04 16:36:31 +01001213 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001214 // First DFS: write all buffers and resolve pointers for parent
1215 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001216 if (arg->type().isInterface()) {
1217 hasInterfaceArgument = true;
1218 }
Yifan Hong068c5522016-10-31 14:07:25 -07001219 emitCppReaderWriter(
1220 out,
1221 "_hidl_data",
1222 false /* parcelObjIsPointer */,
1223 arg,
1224 false /* reader */,
1225 Type::ErrorMode_Goto,
1226 false /* addPrefixToName */);
1227 }
1228
1229 // Second DFS: resolve references.
1230 for (const auto &arg : method->args()) {
1231 emitCppResolveReferences(
1232 out,
1233 "_hidl_data",
1234 false /* parcelObjIsPointer */,
1235 arg,
1236 false /* reader */,
1237 Type::ErrorMode_Goto,
1238 false /* addPrefixToName */);
1239 }
1240
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001241 if (hasInterfaceArgument) {
1242 // Start binder threadpool to handle incoming transactions
1243 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1244 }
Yifan Hong068c5522016-10-31 14:07:25 -07001245 out << "_hidl_err = remote()->transact("
1246 << method->getSerialId()
1247 << " /* "
1248 << method->name()
1249 << " */, _hidl_data, &_hidl_reply";
1250
1251 if (method->isOneway()) {
1252 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1253 }
1254 out << ");\n";
1255
1256 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1257
1258 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001259 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001260 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1261 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1262
1263
1264 // First DFS: write all buffers and resolve pointers for parent
1265 for (const auto &arg : method->results()) {
1266 emitCppReaderWriter(
1267 out,
1268 "_hidl_reply",
1269 false /* parcelObjIsPointer */,
1270 arg,
1271 true /* reader */,
1272 Type::ErrorMode_Goto,
1273 true /* addPrefixToName */);
1274 }
1275
1276 // Second DFS: resolve references.
1277 for (const auto &arg : method->results()) {
1278 emitCppResolveReferences(
1279 out,
1280 "_hidl_reply",
1281 false /* parcelObjIsPointer */,
1282 arg,
1283 true /* reader */,
1284 Type::ErrorMode_Goto,
1285 true /* addPrefixToName */);
1286 }
1287
1288 if (returnsValue && elidedReturn == nullptr) {
1289 out << "_hidl_cb(";
1290
1291 bool first = true;
1292 for (const auto &arg : method->results()) {
1293 if (!first) {
1294 out << ", ";
1295 }
1296
1297 if (arg->type().resultNeedsDeref()) {
1298 out << "*";
1299 }
1300 out << "_hidl_out_" << arg->name();
1301
1302 first = false;
1303 }
1304
1305 out << ");\n\n";
1306 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001307 }
1308 status = generateCppInstrumentationCall(
1309 out,
1310 InstrumentationEvent::CLIENT_API_EXIT,
1311 method);
1312 if (status != OK) {
1313 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001314 }
1315
1316 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001317 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1318 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001319 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001320 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1321 } else {
1322 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1323 out << "return ::android::hardware::Return<void>();\n\n";
1324 }
1325
1326 out.unindent();
1327 out << "_hidl_error:\n";
1328 out.indent();
1329 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1330 out << "return ::android::hardware::Return<";
1331 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001332 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001333 } else {
1334 out << "void";
1335 }
1336 out << ">(_hidl_status);\n";
1337
1338 out.unindent();
1339 out << "}\n\n";
1340 return OK;
1341}
1342
Andreas Huber881227d2016-08-02 14:20:21 -07001343status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001344 Formatter &out, const FQName &fqName) const {
1345 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001346
1347 out << klassName
1348 << "::"
1349 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001350 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001351
1352 out.indent();
1353 out.indent();
1354
1355 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001356 << "<"
1357 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001358 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001359 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001360 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001361 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001362 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001363 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001364
Andreas Huber881227d2016-08-02 14:20:21 -07001365 out.unindent();
1366 out.unindent();
1367 out << "}\n\n";
1368
Yifan Hong068c5522016-10-31 14:07:25 -07001369 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1370 return generateProxyMethodSource(out, klassName, method, superInterface);
1371 });
Andreas Huber881227d2016-08-02 14:20:21 -07001372
Yifan Hong068c5522016-10-31 14:07:25 -07001373 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001374}
1375
1376status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001377 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001378 const Interface *iface) const {
1379 const std::string interfaceName = iface->localName();
1380 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001381
Steven Moreland40786312016-08-16 10:29:40 -07001382 out << klassName
1383 << "::"
1384 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001385 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001386
1387 out.indent();
1388 out.indent();
1389
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001390 if (iface->isIBase()) {
1391 out << ": ::android::hardware::HidlInstrumentor(\"";
1392 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001393 out << ": "
1394 << gIBaseFqName.getInterfaceStubFqName().cppName()
1395 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001396 }
1397
1398 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001399 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001400 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001401 << "\") { \n";
1402 out.indent();
1403 out << "_hidl_mImpl = _hidl_impl;\n";
1404 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001405
1406 out.unindent();
1407 out.unindent();
1408 out << "}\n\n";
1409
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001410 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001411 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001412 // class properly.
1413 out << klassName
1414 << "::"
1415 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001416 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1417 << " const std::string &HidlInstrumentor_package,"
1418 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001419
1420 out.indent();
1421 out.indent();
1422
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001423 out << ": ::android::hardware::HidlInstrumentor("
1424 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001425 out.indent();
1426 out << "_hidl_mImpl = _hidl_impl;\n";
1427 out.unindent();
1428
1429 out.unindent();
1430 out.unindent();
1431 out << "}\n\n";
1432 }
1433
1434
Andreas Huber881227d2016-08-02 14:20:21 -07001435 out << "::android::status_t " << klassName << "::onTransact(\n";
1436
1437 out.indent();
1438 out.indent();
1439
Iliyan Malchev549e2592016-08-10 08:59:12 -07001440 out << "uint32_t _hidl_code,\n"
1441 << "const ::android::hardware::Parcel &_hidl_data,\n"
1442 << "::android::hardware::Parcel *_hidl_reply,\n"
1443 << "uint32_t _hidl_flags,\n"
1444 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001445
1446 out.unindent();
1447
Iliyan Malchev549e2592016-08-10 08:59:12 -07001448 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001449 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001450 out.indent();
1451
Yifan Hong10fe0b52016-10-19 14:20:17 -07001452 for (const auto &tuple : iface->allMethodsFromRoot()) {
1453 const Method *method = tuple.method();
1454 const Interface *superInterface = tuple.interface();
1455 out << "case "
1456 << method->getSerialId()
1457 << " /* "
1458 << method->name()
1459 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001460
Yifan Hong10fe0b52016-10-19 14:20:17 -07001461 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001462
Yifan Hong10fe0b52016-10-19 14:20:17 -07001463 status_t err =
1464 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001465
Yifan Hong10fe0b52016-10-19 14:20:17 -07001466 if (err != OK) {
1467 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001468 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001469
1470 out.unindent();
1471 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001472 }
1473
1474 out << "default:\n{\n";
1475 out.indent();
1476
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001477 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001478
1479 out.indent();
1480 out.indent();
1481
Iliyan Malchev549e2592016-08-10 08:59:12 -07001482 out << "_hidl_code, _hidl_data, _hidl_reply, "
1483 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001484
1485 out.unindent();
1486 out.unindent();
1487
1488 out.unindent();
1489 out << "}\n";
1490
1491 out.unindent();
1492 out << "}\n\n";
1493
Yifan Honga018ed52016-12-13 16:35:08 -08001494 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1495 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1496 out.indent(2, [&] {
1497 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1498 out << "_hidl_reply);\n";
1499 });
1500 });
Andreas Huber881227d2016-08-02 14:20:21 -07001501
Iliyan Malchev549e2592016-08-10 08:59:12 -07001502 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001503
1504 out.unindent();
1505 out << "}\n\n";
1506
1507 return OK;
1508}
1509
1510status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001511 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001512 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1513 method->cppImpl(IMPL_STUB, out);
1514 out << "break;\n";
1515 return OK;
1516 }
1517
Yifan Hongeefe4f22017-01-04 15:32:42 -08001518 out << "if (!_hidl_data.enforceInterface("
1519 << iface->fullName()
1520 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001521
Andreas Huber881227d2016-08-02 14:20:21 -07001522 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001523 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001524 out << "break;\n";
1525 out.unindent();
1526 out << "}\n\n";
1527
Andreas Huber5e44a292016-09-27 14:52:39 -07001528 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001529
Yifan Hongbf459bc2016-08-23 16:50:37 -07001530 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001531 for (const auto &arg : method->args()) {
1532 emitCppReaderWriter(
1533 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001534 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001535 false /* parcelObjIsPointer */,
1536 arg,
1537 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001538 Type::ErrorMode_Break,
1539 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001540 }
1541
Yifan Hongbf459bc2016-08-23 16:50:37 -07001542 // Second DFS: resolve references
1543 for (const auto &arg : method->args()) {
1544 emitCppResolveReferences(
1545 out,
1546 "_hidl_data",
1547 false /* parcelObjIsPointer */,
1548 arg,
1549 true /* reader */,
1550 Type::ErrorMode_Break,
1551 false /* addPrefixToName */);
1552 }
1553
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001554 status_t status = generateCppInstrumentationCall(
1555 out,
1556 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001557 method);
1558 if (status != OK) {
1559 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001560 }
1561
Andreas Huber881227d2016-08-02 14:20:21 -07001562 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001563 const TypedVar *elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -08001564 const std::string callee =
1565 (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL))
1566 ? "this" : "_hidl_mImpl";
Andreas Huber881227d2016-08-02 14:20:21 -07001567
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001568 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001569 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001570 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001571 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001572 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001573 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001574 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001575
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001576 bool first = true;
1577 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001578 if (!first) {
1579 out << ", ";
1580 }
1581
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001582 if (arg->type().resultNeedsDeref()) {
1583 out << "*";
1584 }
1585
1586 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001587
1588 first = false;
1589 }
1590
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001591 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001592 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1593 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001594
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001595 elidedReturn->type().emitReaderWriter(
1596 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001597 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001598 "_hidl_reply",
1599 true, /* parcelObjIsPointer */
1600 false, /* isReader */
1601 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001602
Yifan Hongbf459bc2016-08-23 16:50:37 -07001603 emitCppResolveReferences(
1604 out,
1605 "_hidl_reply",
1606 true /* parcelObjIsPointer */,
1607 elidedReturn,
1608 false /* reader */,
1609 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001610 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001611
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001612 status_t status = generateCppInstrumentationCall(
1613 out,
1614 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001615 method);
1616 if (status != OK) {
1617 return status;
1618 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001619
Iliyan Malchev549e2592016-08-10 08:59:12 -07001620 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001621 } else {
1622 if (returnsValue) {
1623 out << "bool _hidl_callbackCalled = false;\n\n";
1624 }
Andreas Huber881227d2016-08-02 14:20:21 -07001625
Yifan Hongcd2ae452017-01-31 14:33:40 -08001626 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001627
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001628 bool first = true;
1629 for (const auto &arg : method->args()) {
1630 if (!first) {
1631 out << ", ";
1632 }
Andreas Huber881227d2016-08-02 14:20:21 -07001633
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001634 if (arg->type().resultNeedsDeref()) {
1635 out << "*";
1636 }
1637
1638 out << arg->name();
1639
1640 first = false;
1641 }
1642
1643 if (returnsValue) {
1644 if (!first) {
1645 out << ", ";
1646 }
1647
1648 out << "[&](";
1649
1650 first = true;
1651 for (const auto &arg : method->results()) {
1652 if (!first) {
1653 out << ", ";
1654 }
1655
Yifan Honga47eef32016-12-12 10:38:54 -08001656 out << "const auto &_hidl_out_" << arg->name();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001657
1658 first = false;
1659 }
1660
1661 out << ") {\n";
1662 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001663 out << "if (_hidl_callbackCalled) {\n";
1664 out.indent();
1665 out << "LOG_ALWAYS_FATAL(\""
1666 << method->name()
1667 << ": _hidl_cb called a second time, but must be called once.\");\n";
1668 out.unindent();
1669 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001670 out << "_hidl_callbackCalled = true;\n\n";
1671
Yifan Hong859e53f2016-11-14 19:08:24 -08001672 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1673 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001674
Yifan Hongbf459bc2016-08-23 16:50:37 -07001675 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001676 for (const auto &arg : method->results()) {
1677 emitCppReaderWriter(
1678 out,
1679 "_hidl_reply",
1680 true /* parcelObjIsPointer */,
1681 arg,
1682 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001683 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001684 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001685 }
1686
Yifan Hongbf459bc2016-08-23 16:50:37 -07001687 // Second DFS: resolve references
1688 for (const auto &arg : method->results()) {
1689 emitCppResolveReferences(
1690 out,
1691 "_hidl_reply",
1692 true /* parcelObjIsPointer */,
1693 arg,
1694 false /* reader */,
1695 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001696 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001697 }
1698
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001699 status_t status = generateCppInstrumentationCall(
1700 out,
1701 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001702 method);
1703 if (status != OK) {
1704 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001705 }
1706
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001707 out << "_hidl_cb(*_hidl_reply);\n";
1708
1709 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001710 out << "});\n\n";
1711 } else {
1712 out << ");\n\n";
1713 status_t status = generateCppInstrumentationCall(
1714 out,
1715 InstrumentationEvent::SERVER_API_EXIT,
1716 method);
1717 if (status != OK) {
1718 return status;
1719 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001720 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001721
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001722 if (returnsValue) {
1723 out << "if (!_hidl_callbackCalled) {\n";
1724 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001725 out << "LOG_ALWAYS_FATAL(\""
1726 << method->name()
1727 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001728 out.unindent();
1729 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001730 } else {
1731 out << "::android::hardware::writeToParcel("
1732 << "::android::hardware::Status::ok(), "
1733 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001734 }
Andreas Huber881227d2016-08-02 14:20:21 -07001735 }
1736
1737 out << "break;\n";
1738
1739 return OK;
1740}
1741
Steven Moreland69e7c702016-09-09 11:16:32 -07001742status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1743 std::string ifaceName;
1744 if (!AST::isInterface(&ifaceName)) {
1745 // types.hal does not get a stub header.
1746 return OK;
1747 }
1748
1749 const Interface *iface = mRootScope->getInterface();
1750
Yifan Hongeefe4f22017-01-04 15:32:42 -08001751 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001752
1753 bool supportOneway = iface->hasOnewayMethods();
1754
1755 std::string path = outputPath;
1756 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1757 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1758 path.append(klassName);
1759 path.append(".h");
1760
1761 CHECK(Coordinator::MakeParentHierarchy(path));
1762 FILE *file = fopen(path.c_str(), "w");
1763
1764 if (file == NULL) {
1765 return -errno;
1766 }
1767
1768 Formatter out(file);
1769
1770 const std::string guard = makeHeaderGuard(klassName);
1771
1772 out << "#ifndef " << guard << "\n";
1773 out << "#define " << guard << "\n\n";
1774
1775 std::vector<std::string> packageComponents;
1776 getPackageAndVersionComponents(
1777 &packageComponents, false /* cpp_compatible */);
1778
Yifan Hongb0949432016-12-15 15:32:24 -08001779 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001780 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001781
1782 generateCppPackageInclude(out, mPackage, ifaceName);
1783 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001784
Yifan Hong7a118f52016-12-07 11:21:15 -08001785 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001786 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001787 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001788 }
1789
1790 enterLeaveNamespace(out, true /* enter */);
1791 out << "\n";
1792
1793 out << "struct "
1794 << klassName
1795 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001796 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001797
1798 out.indent();
1799 out << "explicit "
1800 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001801 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001802 << ifaceName
1803 << "> impl);\n";
1804
Yifan Hong068c5522016-10-31 14:07:25 -07001805 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1806 return generatePassthroughMethod(out, method);
1807 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001808
1809 if (err != OK) {
1810 return err;
1811 }
1812
1813 out.unindent();
1814 out << "private:\n";
1815 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001816 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001817
1818 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001819 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001820
1821 out << "\n";
1822
1823 out << "::android::hardware::Return<void> addOnewayTask("
1824 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001825 }
1826
1827 out.unindent();
1828
1829 out << "};\n\n";
1830
1831 enterLeaveNamespace(out, false /* enter */);
1832
1833 out << "\n#endif // " << guard << "\n";
1834
1835 return OK;
1836}
1837
Yifan Hongfe95aa22016-10-19 17:26:45 -07001838status_t AST::generateInterfaceSource(Formatter &out) const {
1839 const Interface *iface = mRootScope->getInterface();
1840
Yifan Hong2d7126b2016-10-20 15:12:57 -07001841 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001842 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001843
Yifan Hong3d746092016-12-07 14:26:33 -08001844 for (const Interface *superType : iface->typeChain()) {
1845 out << "// static \n"
1846 << childTypeResult
Yifan Hongeefe4f22017-01-04 15:32:42 -08001847 << " "
1848 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001849 << "::castFrom("
1850 << superType->getCppArgumentType()
1851 << " parent) {\n";
1852 out.indent();
1853 if (iface == superType) {
1854 out << "return parent;\n";
1855 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001856 out << "return ::android::hardware::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001857 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001858 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001859 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001860 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001861 << ">(\n";
1862 out.indent();
1863 out.indent();
1864 out << "parent, \""
1865 << iface->fqName().string()
1866 << "\");\n";
1867 out.unindent();
1868 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001869 }
Yifan Hong3d746092016-12-07 14:26:33 -08001870 out.unindent();
1871 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001872 }
1873
1874 return OK;
1875}
1876
Steven Moreland69e7c702016-09-09 11:16:32 -07001877status_t AST::generatePassthroughSource(Formatter &out) const {
1878 const Interface *iface = mRootScope->getInterface();
1879
Yifan Hongeefe4f22017-01-04 15:32:42 -08001880 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001881
1882 out << klassName
1883 << "::"
1884 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001885 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001886 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001887 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001888 << mPackage.string()
1889 << "\", \""
1890 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001891 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001892 if (iface->hasOnewayMethods()) {
1893 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001894 out.indent([&] {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001895 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1896 });
1897 }
1898 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001899
1900 if (iface->hasOnewayMethods()) {
1901 out << "::android::hardware::Return<void> "
1902 << klassName
1903 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1904 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001905 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001906 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001907 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1908 out.indent();
1909 out.indent();
1910 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1911 out.unindent();
1912 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001913 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001914 out << "}\n";
1915
Steven Morelandd366c262016-10-11 15:29:10 -07001916 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001917
1918 out.unindent();
1919 out << "}\n\n";
1920
1921
1922 }
1923
1924 return OK;
1925}
1926
Martijn Coenen7b295242016-11-04 16:52:56 +01001927status_t AST::generateCppAtraceCall(Formatter &out,
1928 InstrumentationEvent event,
1929 const Method *method) const {
1930 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001931 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001932 switch (event) {
1933 case SERVER_API_ENTRY:
1934 {
1935 out << "atrace_begin(ATRACE_TAG_HAL, \""
1936 << baseString + "::server\");\n";
1937 break;
1938 }
1939 case CLIENT_API_ENTRY:
1940 {
1941 out << "atrace_begin(ATRACE_TAG_HAL, \""
1942 << baseString + "::client\");\n";
1943 break;
1944 }
1945 case PASSTHROUGH_ENTRY:
1946 {
1947 out << "atrace_begin(ATRACE_TAG_HAL, \""
1948 << baseString + "::passthrough\");\n";
1949 break;
1950 }
1951 case SERVER_API_EXIT:
1952 case CLIENT_API_EXIT:
1953 case PASSTHROUGH_EXIT:
1954 {
1955 out << "atrace_end(ATRACE_TAG_HAL);\n";
1956 break;
1957 }
1958 default:
1959 {
1960 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1961 return UNKNOWN_ERROR;
1962 }
1963 }
1964
1965 return OK;
1966}
1967
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001968status_t AST::generateCppInstrumentationCall(
1969 Formatter &out,
1970 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001971 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001972 status_t err = generateCppAtraceCall(out, event, method);
1973 if (err != OK) {
1974 return err;
1975 }
1976
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001977 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1978 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001979 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001980 std::string event_str = "";
1981 switch (event) {
1982 case SERVER_API_ENTRY:
1983 {
1984 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1985 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001986 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001987 << (arg->type().resultNeedsDeref() ? "" : "&")
1988 << arg->name()
1989 << ");\n";
1990 }
1991 break;
1992 }
1993 case SERVER_API_EXIT:
1994 {
1995 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001996 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001997 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001998 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001999 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002000 }
2001 break;
2002 }
2003 case CLIENT_API_ENTRY:
2004 {
2005 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2006 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002007 out << "_hidl_args.push_back((void *)&"
2008 << arg->name()
2009 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002010 }
2011 break;
2012 }
2013 case CLIENT_API_EXIT:
2014 {
2015 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2016 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002017 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002018 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002019 << "_hidl_out_"
2020 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002021 << ");\n";
2022 }
2023 break;
2024 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002025 case PASSTHROUGH_ENTRY:
2026 {
2027 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2028 for (const auto &arg : method->args()) {
2029 out << "_hidl_args.push_back((void *)&"
2030 << arg->name()
2031 << ");\n";
2032 }
2033 break;
2034 }
2035 case PASSTHROUGH_EXIT:
2036 {
2037 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002038 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002039 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002040 << arg->name()
2041 << ");\n";
2042 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002043 break;
2044 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002045 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002046 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002047 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002048 return UNKNOWN_ERROR;
2049 }
2050 }
2051
Steven Moreland031ccf12016-10-31 15:54:38 -07002052 const Interface *iface = mRootScope->getInterface();
2053
Steven Moreland1ab31442016-11-03 18:37:51 -07002054 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002055 out.indent();
2056 out << "callback("
2057 << event_str
2058 << ", \""
2059 << mPackage.package()
2060 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002061 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002062 << "\", \""
2063 << iface->localName()
2064 << "\", \""
2065 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002066 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002067 out.unindent();
2068 out << "}\n";
2069 out.unindent();
2070 out << "}\n\n";
2071
2072 return OK;
2073}
2074
Andreas Huber881227d2016-08-02 14:20:21 -07002075} // namespace android