blob: 1a2b45baabd065b86c2d5237e8c27a51f5c10775 [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";
Yifan Hongd3b58ed2017-01-30 14:13:10 -0800162 out << "::android::vintf::Transport transport = ::android::hardware::getTransport("
163 << interfaceName << "::descriptor);\n";
Steven Morelandf10af872017-01-25 16:01:56 +0000164
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);
Yifan Hongbcffce22017-02-01 15:52:06 -0800830 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800831 return OK;
832 });
833 if (err != OK) {
834 return err;
835 }
836
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100837 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700838 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700839 out << "};\n\n";
840
841 enterLeaveNamespace(out, false /* enter */);
842
843 out << "\n#endif // " << guard << "\n";
844
845 return OK;
846}
847
Andreas Huberb82318c2016-08-02 14:45:54 -0700848status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700849 std::string ifaceName;
850 if (!AST::isInterface(&ifaceName)) {
851 // types.hal does not get a proxy header.
852 return OK;
853 }
854
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700855 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800856 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700857
Andreas Huberb82318c2016-08-02 14:45:54 -0700858 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700859 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700860 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800861 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700862 path.append(".h");
863
Andreas Huberd2943e12016-08-05 11:59:31 -0700864 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700865 FILE *file = fopen(path.c_str(), "w");
866
867 if (file == NULL) {
868 return -errno;
869 }
870
871 Formatter out(file);
872
Yifan Hongeefe4f22017-01-04 15:32:42 -0800873 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700874
875 out << "#ifndef " << guard << "\n";
876 out << "#define " << guard << "\n\n";
877
Martijn Coenen115d4282016-12-19 05:14:04 +0100878 out << "#include <hidl/HidlTransportSupport.h>\n\n";
879
Andreas Huber881227d2016-08-02 14:20:21 -0700880 std::vector<std::string> packageComponents;
881 getPackageAndVersionComponents(
882 &packageComponents, false /* cpp_compatible */);
883
Yifan Hongeefe4f22017-01-04 15:32:42 -0800884 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700885 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700886
887 enterLeaveNamespace(out, true /* enter */);
888 out << "\n";
889
890 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800891 << proxyName
892 << " : public ::android::hardware::BpInterface<"
893 << iface->localName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700894 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700895
896 out.indent();
897
Yifan Hongeefe4f22017-01-04 15:32:42 -0800898 out << "explicit "
899 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700900 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700901 << "\n\n";
902
Yifan Hong10fe0b52016-10-19 14:20:17 -0700903 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700904
Yifan Hong068c5522016-10-31 14:07:25 -0700905 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
906 method->generateCppSignature(out);
907 out << " override;\n";
908 return OK;
909 });
Steven Moreland9c387612016-09-07 09:54:26 -0700910
911 if (err != OK) {
912 return err;
913 }
Andreas Huber881227d2016-08-02 14:20:21 -0700914
915 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100916 out << "private:\n";
917 out.indent();
918 out << "std::mutex _hidl_mMutex;\n"
919 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
920 << " _hidl_mDeathRecipients;\n";
921 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700922 out << "};\n\n";
923
924 enterLeaveNamespace(out, false /* enter */);
925
926 out << "\n#endif // " << guard << "\n";
927
928 return OK;
929}
930
Andreas Huberb82318c2016-08-02 14:45:54 -0700931status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700932
Andreas Huberb82318c2016-08-02 14:45:54 -0700933 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700934 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700935 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700936
937 std::string ifaceName;
938 std::string baseName;
939
Yifan Hongfe95aa22016-10-19 17:26:45 -0700940 const Interface *iface = nullptr;
941 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700942 if (!AST::isInterface(&ifaceName)) {
943 baseName = "types";
944 isInterface = false;
945 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700946 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700947 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700948 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700949 }
950
951 path.append(baseName);
952
953 if (baseName != "types") {
954 path.append("All");
955 }
956
957 path.append(".cpp");
958
Andreas Huberd2943e12016-08-05 11:59:31 -0700959 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700960 FILE *file = fopen(path.c_str(), "w");
961
962 if (file == NULL) {
963 return -errno;
964 }
965
966 Formatter out(file);
967
Steven Moreland623c0042017-01-13 14:42:29 -0800968 out << "#define LOG_TAG \""
969 << mPackage.string() << "::" << baseName
970 << "\"\n\n";
971
Steven Moreland05cd4232016-11-21 16:01:12 -0800972 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100973 out << "#include <cutils/trace.h>\n";
974 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700975 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700976 // This is a no-op for IServiceManager itself.
977 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
978
Steven Morelandbec74ed2017-01-25 17:42:35 -0800979 // TODO(b/34274385) remove this
980 out << "#include <hidl/LegacySupport.h>\n";
981
Yifan Hongeefe4f22017-01-04 15:32:42 -0800982 generateCppPackageInclude(out, mPackage, iface->getProxyName());
983 generateCppPackageInclude(out, mPackage, iface->getStubName());
984 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700985
986 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700987 generateCppPackageInclude(out,
988 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800989 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700990 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800991
992 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700993 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700994 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800995 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700996 }
997
998 out << "\n";
999
1000 enterLeaveNamespace(out, true /* enter */);
1001 out << "\n";
1002
1003 status_t err = generateTypeSource(out, ifaceName);
1004
1005 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001006 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001007
1008 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -08001009 out << "const char* "
1010 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -07001011 << "::descriptor(\""
1012 << iface->fqName().string()
1013 << "\");\n\n";
1014
Yifan Hongeefe4f22017-01-04 15:32:42 -08001015 out << "int "
1016 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001017 << "::hidlStaticBlock = []() -> int {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001018 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001019 out << "::android::hardware::gBnConstructorMap["
1020 << iface->localName()
Steven Morelandd39133b2016-11-11 12:30:08 -08001021 << "::descriptor]\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001022 out.indent(2, [&] {
Yifan Hong158655a2016-11-08 12:34:07 -08001023 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001024 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001025 out << "return new "
1026 << iface->getStubName()
1027 << "(reinterpret_cast<"
1028 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001029 << " *>(iIntf));\n";
1030 });
1031 out << "};\n";
1032 });
Yifan Hongeefe4f22017-01-04 15:32:42 -08001033 out << "::android::hardware::gBsConstructorMap["
1034 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001035 << "::descriptor]\n";
1036 out.indent(2, [&] {
1037 out << "= [](void *iIntf) -> ::android::sp<"
1038 << gIBaseFqName.cppName()
1039 << "> {\n";
1040 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001041 out << "return new "
1042 << iface->getPassthroughName()
1043 << "(reinterpret_cast<"
1044 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001045 << " *>(iIntf));\n";
1046 });
1047 out << "};\n";
1048 });
Yifan Hong158655a2016-11-08 12:34:07 -08001049 out << "return 1;\n";
1050 });
1051 out << "}();\n\n";
1052
Yifan Hongfe95aa22016-10-19 17:26:45 -07001053 err = generateInterfaceSource(out);
1054 }
1055
1056 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001057 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001058 }
1059
1060 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001061 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001062 }
1063
Steven Moreland40786312016-08-16 10:29:40 -07001064 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001065 err = generatePassthroughSource(out);
1066 }
1067
1068 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001069 const Interface *iface = mRootScope->getInterface();
1070
Yifan Hongc8934042016-11-17 17:10:52 -08001071 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001072 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001073 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001074 std::string package = iface->fqName().package()
1075 + iface->fqName().atVersion();
1076
Yifan Hongeefe4f22017-01-04 15:32:42 -08001077 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001078 }
Steven Moreland40786312016-08-16 10:29:40 -07001079 }
1080
Andreas Huber881227d2016-08-02 14:20:21 -07001081 enterLeaveNamespace(out, false /* enter */);
1082
1083 return err;
1084}
1085
Steven Moreland67f67b42016-09-29 08:59:02 -07001086// static
1087void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001088 out.sIf(nonNull + " == nullptr", [&] {
1089 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1090 out.indent(2, [&] {
1091 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1092 });
1093 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001094}
1095
Andreas Huber881227d2016-08-02 14:20:21 -07001096status_t AST::generateTypeSource(
1097 Formatter &out, const std::string &ifaceName) const {
1098 return mRootScope->emitTypeDefinitions(out, ifaceName);
1099}
1100
Andreas Hubere7ff2282016-08-16 13:50:03 -07001101void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001102 Formatter &out,
1103 const std::vector<TypedVar *> &args,
1104 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001105 if (args.empty()) {
1106 return;
1107 }
1108
1109 for (const auto &arg : args) {
1110 const Type &type = arg->type();
1111
Yifan Hong3b320f82016-11-01 15:15:54 -07001112 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001113 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001114 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001115 << ";\n";
1116 }
1117
1118 out << "\n";
1119}
1120
Andreas Huber881227d2016-08-02 14:20:21 -07001121void AST::emitCppReaderWriter(
1122 Formatter &out,
1123 const std::string &parcelObj,
1124 bool parcelObjIsPointer,
1125 const TypedVar *arg,
1126 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001127 Type::ErrorMode mode,
1128 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001129 const Type &type = arg->type();
1130
Andreas Huber881227d2016-08-02 14:20:21 -07001131 type.emitReaderWriter(
1132 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001133 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001134 parcelObj,
1135 parcelObjIsPointer,
1136 isReader,
1137 mode);
1138}
1139
Yifan Hongbf459bc2016-08-23 16:50:37 -07001140void AST::emitCppResolveReferences(
1141 Formatter &out,
1142 const std::string &parcelObj,
1143 bool parcelObjIsPointer,
1144 const TypedVar *arg,
1145 bool isReader,
1146 Type::ErrorMode mode,
1147 bool addPrefixToName) const {
1148 const Type &type = arg->type();
1149 if(type.needsResolveReferences()) {
1150 type.emitResolveReferences(
1151 out,
1152 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1153 isReader, // nameIsPointer
1154 parcelObj,
1155 parcelObjIsPointer,
1156 isReader,
1157 mode);
1158 }
1159}
1160
Yifan Hong068c5522016-10-31 14:07:25 -07001161status_t AST::generateProxyMethodSource(Formatter &out,
1162 const std::string &klassName,
1163 const Method *method,
1164 const Interface *superInterface) const {
1165
1166 method->generateCppSignature(out,
1167 klassName,
1168 true /* specify namespaces */);
1169
1170 const bool returnsValue = !method->results().empty();
1171 const TypedVar *elidedReturn = method->canElideCallback();
1172
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001173 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001174
1175 out.indent();
1176
Martijn Coenen115d4282016-12-19 05:14:04 +01001177 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1178 method->cppImpl(IMPL_PROXY, out);
1179 out.unindent();
1180 out << "}\n\n";
1181 return OK;
1182 }
1183
Yifan Hong068c5522016-10-31 14:07:25 -07001184 if (returnsValue && elidedReturn == nullptr) {
1185 generateCheckNonNull(out, "_hidl_cb");
1186 }
1187
1188 status_t status = generateCppInstrumentationCall(
1189 out,
1190 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001191 method);
1192 if (status != OK) {
1193 return status;
1194 }
1195
1196 out << "::android::hardware::Parcel _hidl_data;\n";
1197 out << "::android::hardware::Parcel _hidl_reply;\n";
1198 out << "::android::status_t _hidl_err;\n";
1199 out << "::android::hardware::Status _hidl_status;\n\n";
1200
1201 declareCppReaderLocals(
1202 out, method->results(), true /* forResults */);
1203
1204 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001205 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001206 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001207 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1208
Martijn Coenenfff73352017-01-04 16:36:31 +01001209 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001210 // First DFS: write all buffers and resolve pointers for parent
1211 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001212 if (arg->type().isInterface()) {
1213 hasInterfaceArgument = true;
1214 }
Yifan Hong068c5522016-10-31 14:07:25 -07001215 emitCppReaderWriter(
1216 out,
1217 "_hidl_data",
1218 false /* parcelObjIsPointer */,
1219 arg,
1220 false /* reader */,
1221 Type::ErrorMode_Goto,
1222 false /* addPrefixToName */);
1223 }
1224
1225 // Second DFS: resolve references.
1226 for (const auto &arg : method->args()) {
1227 emitCppResolveReferences(
1228 out,
1229 "_hidl_data",
1230 false /* parcelObjIsPointer */,
1231 arg,
1232 false /* reader */,
1233 Type::ErrorMode_Goto,
1234 false /* addPrefixToName */);
1235 }
1236
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001237 if (hasInterfaceArgument) {
1238 // Start binder threadpool to handle incoming transactions
1239 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1240 }
Yifan Hong068c5522016-10-31 14:07:25 -07001241 out << "_hidl_err = remote()->transact("
1242 << method->getSerialId()
1243 << " /* "
1244 << method->name()
1245 << " */, _hidl_data, &_hidl_reply";
1246
1247 if (method->isOneway()) {
1248 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1249 }
1250 out << ");\n";
1251
1252 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1253
1254 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001255 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001256 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1257 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1258
1259
1260 // First DFS: write all buffers and resolve pointers for parent
1261 for (const auto &arg : method->results()) {
1262 emitCppReaderWriter(
1263 out,
1264 "_hidl_reply",
1265 false /* parcelObjIsPointer */,
1266 arg,
1267 true /* reader */,
1268 Type::ErrorMode_Goto,
1269 true /* addPrefixToName */);
1270 }
1271
1272 // Second DFS: resolve references.
1273 for (const auto &arg : method->results()) {
1274 emitCppResolveReferences(
1275 out,
1276 "_hidl_reply",
1277 false /* parcelObjIsPointer */,
1278 arg,
1279 true /* reader */,
1280 Type::ErrorMode_Goto,
1281 true /* addPrefixToName */);
1282 }
1283
1284 if (returnsValue && elidedReturn == nullptr) {
1285 out << "_hidl_cb(";
1286
1287 bool first = true;
1288 for (const auto &arg : method->results()) {
1289 if (!first) {
1290 out << ", ";
1291 }
1292
1293 if (arg->type().resultNeedsDeref()) {
1294 out << "*";
1295 }
1296 out << "_hidl_out_" << arg->name();
1297
1298 first = false;
1299 }
1300
1301 out << ");\n\n";
1302 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001303 }
1304 status = generateCppInstrumentationCall(
1305 out,
1306 InstrumentationEvent::CLIENT_API_EXIT,
1307 method);
1308 if (status != OK) {
1309 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001310 }
1311
1312 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001313 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1314 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001315 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001316 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1317 } else {
1318 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1319 out << "return ::android::hardware::Return<void>();\n\n";
1320 }
1321
1322 out.unindent();
1323 out << "_hidl_error:\n";
1324 out.indent();
1325 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1326 out << "return ::android::hardware::Return<";
1327 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001328 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001329 } else {
1330 out << "void";
1331 }
1332 out << ">(_hidl_status);\n";
1333
1334 out.unindent();
1335 out << "}\n\n";
1336 return OK;
1337}
1338
Andreas Huber881227d2016-08-02 14:20:21 -07001339status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001340 Formatter &out, const FQName &fqName) const {
1341 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001342
1343 out << klassName
1344 << "::"
1345 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001346 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001347
1348 out.indent();
1349 out.indent();
1350
1351 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001352 << "<"
1353 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001354 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001355 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001356 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001357 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001358 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001359 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001360
Andreas Huber881227d2016-08-02 14:20:21 -07001361 out.unindent();
1362 out.unindent();
1363 out << "}\n\n";
1364
Yifan Hong068c5522016-10-31 14:07:25 -07001365 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1366 return generateProxyMethodSource(out, klassName, method, superInterface);
1367 });
Andreas Huber881227d2016-08-02 14:20:21 -07001368
Yifan Hong068c5522016-10-31 14:07:25 -07001369 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001370}
1371
1372status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001373 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001374 const Interface *iface) const {
1375 const std::string interfaceName = iface->localName();
1376 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001377
Steven Moreland40786312016-08-16 10:29:40 -07001378 out << klassName
1379 << "::"
1380 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001381 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001382
1383 out.indent();
1384 out.indent();
1385
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001386 if (iface->isIBase()) {
1387 out << ": ::android::hardware::HidlInstrumentor(\"";
1388 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001389 out << ": "
1390 << gIBaseFqName.getInterfaceStubFqName().cppName()
1391 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001392 }
1393
1394 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001395 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001396 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001397 << "\") { \n";
1398 out.indent();
1399 out << "_hidl_mImpl = _hidl_impl;\n";
1400 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001401
1402 out.unindent();
1403 out.unindent();
1404 out << "}\n\n";
1405
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001406 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001407 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001408 // class properly.
1409 out << klassName
1410 << "::"
1411 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001412 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1413 << " const std::string &HidlInstrumentor_package,"
1414 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001415
1416 out.indent();
1417 out.indent();
1418
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001419 out << ": ::android::hardware::HidlInstrumentor("
1420 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001421 out.indent();
1422 out << "_hidl_mImpl = _hidl_impl;\n";
1423 out.unindent();
1424
1425 out.unindent();
1426 out.unindent();
1427 out << "}\n\n";
1428 }
1429
Yifan Hongbcffce22017-02-01 15:52:06 -08001430 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1431 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1432 return OK;
1433 }
1434 method->generateCppSignature(out, iface->getStubName());
1435 out << " ";
1436 out.block([&] {
1437 method->cppImpl(IMPL_STUB_IMPL, out);
1438 }).endl();
1439 return OK;
1440 });
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001441
Andreas Huber881227d2016-08-02 14:20:21 -07001442 out << "::android::status_t " << klassName << "::onTransact(\n";
1443
1444 out.indent();
1445 out.indent();
1446
Iliyan Malchev549e2592016-08-10 08:59:12 -07001447 out << "uint32_t _hidl_code,\n"
1448 << "const ::android::hardware::Parcel &_hidl_data,\n"
1449 << "::android::hardware::Parcel *_hidl_reply,\n"
1450 << "uint32_t _hidl_flags,\n"
1451 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001452
1453 out.unindent();
1454
Iliyan Malchev549e2592016-08-10 08:59:12 -07001455 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001456 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001457 out.indent();
1458
Yifan Hong10fe0b52016-10-19 14:20:17 -07001459 for (const auto &tuple : iface->allMethodsFromRoot()) {
1460 const Method *method = tuple.method();
1461 const Interface *superInterface = tuple.interface();
1462 out << "case "
1463 << method->getSerialId()
1464 << " /* "
1465 << method->name()
1466 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001467
Yifan Hong10fe0b52016-10-19 14:20:17 -07001468 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001469
Yifan Hong10fe0b52016-10-19 14:20:17 -07001470 status_t err =
1471 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001472
Yifan Hong10fe0b52016-10-19 14:20:17 -07001473 if (err != OK) {
1474 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001475 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001476
1477 out.unindent();
1478 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001479 }
1480
1481 out << "default:\n{\n";
1482 out.indent();
1483
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001484 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001485
1486 out.indent();
1487 out.indent();
1488
Iliyan Malchev549e2592016-08-10 08:59:12 -07001489 out << "_hidl_code, _hidl_data, _hidl_reply, "
1490 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001491
1492 out.unindent();
1493 out.unindent();
1494
1495 out.unindent();
1496 out << "}\n";
1497
1498 out.unindent();
1499 out << "}\n\n";
1500
Yifan Honga018ed52016-12-13 16:35:08 -08001501 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1502 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1503 out.indent(2, [&] {
1504 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1505 out << "_hidl_reply);\n";
1506 });
1507 });
Andreas Huber881227d2016-08-02 14:20:21 -07001508
Iliyan Malchev549e2592016-08-10 08:59:12 -07001509 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001510
1511 out.unindent();
1512 out << "}\n\n";
1513
1514 return OK;
1515}
1516
1517status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001518 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001519 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1520 method->cppImpl(IMPL_STUB, out);
1521 out << "break;\n";
1522 return OK;
1523 }
1524
Yifan Hongeefe4f22017-01-04 15:32:42 -08001525 out << "if (!_hidl_data.enforceInterface("
1526 << iface->fullName()
1527 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001528
Andreas Huber881227d2016-08-02 14:20:21 -07001529 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001530 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001531 out << "break;\n";
1532 out.unindent();
1533 out << "}\n\n";
1534
Andreas Huber5e44a292016-09-27 14:52:39 -07001535 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001536
Yifan Hongbf459bc2016-08-23 16:50:37 -07001537 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001538 for (const auto &arg : method->args()) {
1539 emitCppReaderWriter(
1540 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001541 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001542 false /* parcelObjIsPointer */,
1543 arg,
1544 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001545 Type::ErrorMode_Break,
1546 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001547 }
1548
Yifan Hongbf459bc2016-08-23 16:50:37 -07001549 // Second DFS: resolve references
1550 for (const auto &arg : method->args()) {
1551 emitCppResolveReferences(
1552 out,
1553 "_hidl_data",
1554 false /* parcelObjIsPointer */,
1555 arg,
1556 true /* reader */,
1557 Type::ErrorMode_Break,
1558 false /* addPrefixToName */);
1559 }
1560
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001561 status_t status = generateCppInstrumentationCall(
1562 out,
1563 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001564 method);
1565 if (status != OK) {
1566 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001567 }
1568
Andreas Huber881227d2016-08-02 14:20:21 -07001569 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001570 const TypedVar *elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -08001571 const std::string callee =
1572 (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL))
1573 ? "this" : "_hidl_mImpl";
Andreas Huber881227d2016-08-02 14:20:21 -07001574
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001575 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001576 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001577 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001578 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001579 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001580 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001581 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001582
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001583 bool first = true;
1584 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001585 if (!first) {
1586 out << ", ";
1587 }
1588
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001589 if (arg->type().resultNeedsDeref()) {
1590 out << "*";
1591 }
1592
1593 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001594
1595 first = false;
1596 }
1597
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001598 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001599 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1600 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001601
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001602 elidedReturn->type().emitReaderWriter(
1603 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001604 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001605 "_hidl_reply",
1606 true, /* parcelObjIsPointer */
1607 false, /* isReader */
1608 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001609
Yifan Hongbf459bc2016-08-23 16:50:37 -07001610 emitCppResolveReferences(
1611 out,
1612 "_hidl_reply",
1613 true /* parcelObjIsPointer */,
1614 elidedReturn,
1615 false /* reader */,
1616 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001617 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001618
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001619 status_t status = generateCppInstrumentationCall(
1620 out,
1621 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001622 method);
1623 if (status != OK) {
1624 return status;
1625 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001626
Iliyan Malchev549e2592016-08-10 08:59:12 -07001627 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001628 } else {
1629 if (returnsValue) {
1630 out << "bool _hidl_callbackCalled = false;\n\n";
1631 }
Andreas Huber881227d2016-08-02 14:20:21 -07001632
Yifan Hongcd2ae452017-01-31 14:33:40 -08001633 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001634
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001635 bool first = true;
1636 for (const auto &arg : method->args()) {
1637 if (!first) {
1638 out << ", ";
1639 }
Andreas Huber881227d2016-08-02 14:20:21 -07001640
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001641 if (arg->type().resultNeedsDeref()) {
1642 out << "*";
1643 }
1644
1645 out << arg->name();
1646
1647 first = false;
1648 }
1649
1650 if (returnsValue) {
1651 if (!first) {
1652 out << ", ";
1653 }
1654
1655 out << "[&](";
1656
1657 first = true;
1658 for (const auto &arg : method->results()) {
1659 if (!first) {
1660 out << ", ";
1661 }
1662
Yifan Honga47eef32016-12-12 10:38:54 -08001663 out << "const auto &_hidl_out_" << arg->name();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001664
1665 first = false;
1666 }
1667
1668 out << ") {\n";
1669 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001670 out << "if (_hidl_callbackCalled) {\n";
1671 out.indent();
1672 out << "LOG_ALWAYS_FATAL(\""
1673 << method->name()
1674 << ": _hidl_cb called a second time, but must be called once.\");\n";
1675 out.unindent();
1676 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001677 out << "_hidl_callbackCalled = true;\n\n";
1678
Yifan Hong859e53f2016-11-14 19:08:24 -08001679 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1680 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001681
Yifan Hongbf459bc2016-08-23 16:50:37 -07001682 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001683 for (const auto &arg : method->results()) {
1684 emitCppReaderWriter(
1685 out,
1686 "_hidl_reply",
1687 true /* parcelObjIsPointer */,
1688 arg,
1689 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001690 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001691 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001692 }
1693
Yifan Hongbf459bc2016-08-23 16:50:37 -07001694 // Second DFS: resolve references
1695 for (const auto &arg : method->results()) {
1696 emitCppResolveReferences(
1697 out,
1698 "_hidl_reply",
1699 true /* parcelObjIsPointer */,
1700 arg,
1701 false /* reader */,
1702 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001703 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001704 }
1705
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001706 status_t status = generateCppInstrumentationCall(
1707 out,
1708 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001709 method);
1710 if (status != OK) {
1711 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001712 }
1713
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001714 out << "_hidl_cb(*_hidl_reply);\n";
1715
1716 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001717 out << "});\n\n";
1718 } else {
1719 out << ");\n\n";
1720 status_t status = generateCppInstrumentationCall(
1721 out,
1722 InstrumentationEvent::SERVER_API_EXIT,
1723 method);
1724 if (status != OK) {
1725 return status;
1726 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001727 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001728
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001729 if (returnsValue) {
1730 out << "if (!_hidl_callbackCalled) {\n";
1731 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001732 out << "LOG_ALWAYS_FATAL(\""
1733 << method->name()
1734 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001735 out.unindent();
1736 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001737 } else {
1738 out << "::android::hardware::writeToParcel("
1739 << "::android::hardware::Status::ok(), "
1740 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001741 }
Andreas Huber881227d2016-08-02 14:20:21 -07001742 }
1743
1744 out << "break;\n";
1745
1746 return OK;
1747}
1748
Steven Moreland69e7c702016-09-09 11:16:32 -07001749status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1750 std::string ifaceName;
1751 if (!AST::isInterface(&ifaceName)) {
1752 // types.hal does not get a stub header.
1753 return OK;
1754 }
1755
1756 const Interface *iface = mRootScope->getInterface();
1757
Yifan Hongeefe4f22017-01-04 15:32:42 -08001758 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001759
1760 bool supportOneway = iface->hasOnewayMethods();
1761
1762 std::string path = outputPath;
1763 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1764 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1765 path.append(klassName);
1766 path.append(".h");
1767
1768 CHECK(Coordinator::MakeParentHierarchy(path));
1769 FILE *file = fopen(path.c_str(), "w");
1770
1771 if (file == NULL) {
1772 return -errno;
1773 }
1774
1775 Formatter out(file);
1776
1777 const std::string guard = makeHeaderGuard(klassName);
1778
1779 out << "#ifndef " << guard << "\n";
1780 out << "#define " << guard << "\n\n";
1781
1782 std::vector<std::string> packageComponents;
1783 getPackageAndVersionComponents(
1784 &packageComponents, false /* cpp_compatible */);
1785
Yifan Hongb0949432016-12-15 15:32:24 -08001786 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001787 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001788
1789 generateCppPackageInclude(out, mPackage, ifaceName);
1790 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001791
Yifan Hong7a118f52016-12-07 11:21:15 -08001792 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001793 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001794 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001795 }
1796
1797 enterLeaveNamespace(out, true /* enter */);
1798 out << "\n";
1799
1800 out << "struct "
1801 << klassName
1802 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001803 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001804
1805 out.indent();
1806 out << "explicit "
1807 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001808 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001809 << ifaceName
1810 << "> impl);\n";
1811
Yifan Hong068c5522016-10-31 14:07:25 -07001812 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1813 return generatePassthroughMethod(out, method);
1814 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001815
1816 if (err != OK) {
1817 return err;
1818 }
1819
1820 out.unindent();
1821 out << "private:\n";
1822 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001823 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001824
1825 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001826 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001827
1828 out << "\n";
1829
1830 out << "::android::hardware::Return<void> addOnewayTask("
1831 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001832 }
1833
1834 out.unindent();
1835
1836 out << "};\n\n";
1837
1838 enterLeaveNamespace(out, false /* enter */);
1839
1840 out << "\n#endif // " << guard << "\n";
1841
1842 return OK;
1843}
1844
Yifan Hongfe95aa22016-10-19 17:26:45 -07001845status_t AST::generateInterfaceSource(Formatter &out) const {
1846 const Interface *iface = mRootScope->getInterface();
1847
Yifan Hong2d7126b2016-10-20 15:12:57 -07001848 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001849 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001850
Yifan Hong3d746092016-12-07 14:26:33 -08001851 for (const Interface *superType : iface->typeChain()) {
1852 out << "// static \n"
1853 << childTypeResult
Yifan Hongeefe4f22017-01-04 15:32:42 -08001854 << " "
1855 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001856 << "::castFrom("
1857 << superType->getCppArgumentType()
1858 << " parent) {\n";
1859 out.indent();
1860 if (iface == superType) {
1861 out << "return parent;\n";
1862 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001863 out << "return ::android::hardware::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001864 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001865 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001866 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001867 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001868 << ">(\n";
1869 out.indent();
1870 out.indent();
1871 out << "parent, \""
1872 << iface->fqName().string()
1873 << "\");\n";
1874 out.unindent();
1875 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001876 }
Yifan Hong3d746092016-12-07 14:26:33 -08001877 out.unindent();
1878 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001879 }
1880
1881 return OK;
1882}
1883
Steven Moreland69e7c702016-09-09 11:16:32 -07001884status_t AST::generatePassthroughSource(Formatter &out) const {
1885 const Interface *iface = mRootScope->getInterface();
1886
Yifan Hongeefe4f22017-01-04 15:32:42 -08001887 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001888
1889 out << klassName
1890 << "::"
1891 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001892 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001893 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001894 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001895 << mPackage.string()
1896 << "\", \""
1897 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001898 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001899 if (iface->hasOnewayMethods()) {
1900 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001901 out.indent([&] {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001902 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1903 });
1904 }
1905 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001906
1907 if (iface->hasOnewayMethods()) {
1908 out << "::android::hardware::Return<void> "
1909 << klassName
1910 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1911 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001912 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001913 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001914 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1915 out.indent();
1916 out.indent();
1917 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1918 out.unindent();
1919 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001920 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001921 out << "}\n";
1922
Steven Morelandd366c262016-10-11 15:29:10 -07001923 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001924
1925 out.unindent();
1926 out << "}\n\n";
1927
1928
1929 }
1930
1931 return OK;
1932}
1933
Martijn Coenen7b295242016-11-04 16:52:56 +01001934status_t AST::generateCppAtraceCall(Formatter &out,
1935 InstrumentationEvent event,
1936 const Method *method) const {
1937 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001938 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001939 switch (event) {
1940 case SERVER_API_ENTRY:
1941 {
1942 out << "atrace_begin(ATRACE_TAG_HAL, \""
1943 << baseString + "::server\");\n";
1944 break;
1945 }
1946 case CLIENT_API_ENTRY:
1947 {
1948 out << "atrace_begin(ATRACE_TAG_HAL, \""
1949 << baseString + "::client\");\n";
1950 break;
1951 }
1952 case PASSTHROUGH_ENTRY:
1953 {
1954 out << "atrace_begin(ATRACE_TAG_HAL, \""
1955 << baseString + "::passthrough\");\n";
1956 break;
1957 }
1958 case SERVER_API_EXIT:
1959 case CLIENT_API_EXIT:
1960 case PASSTHROUGH_EXIT:
1961 {
1962 out << "atrace_end(ATRACE_TAG_HAL);\n";
1963 break;
1964 }
1965 default:
1966 {
1967 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1968 return UNKNOWN_ERROR;
1969 }
1970 }
1971
1972 return OK;
1973}
1974
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001975status_t AST::generateCppInstrumentationCall(
1976 Formatter &out,
1977 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001978 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001979 status_t err = generateCppAtraceCall(out, event, method);
1980 if (err != OK) {
1981 return err;
1982 }
1983
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001984 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1985 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001986 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001987 std::string event_str = "";
1988 switch (event) {
1989 case SERVER_API_ENTRY:
1990 {
1991 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1992 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001993 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001994 << (arg->type().resultNeedsDeref() ? "" : "&")
1995 << arg->name()
1996 << ");\n";
1997 }
1998 break;
1999 }
2000 case SERVER_API_EXIT:
2001 {
2002 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07002003 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002004 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07002005 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002006 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002007 }
2008 break;
2009 }
2010 case CLIENT_API_ENTRY:
2011 {
2012 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2013 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002014 out << "_hidl_args.push_back((void *)&"
2015 << arg->name()
2016 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002017 }
2018 break;
2019 }
2020 case CLIENT_API_EXIT:
2021 {
2022 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2023 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002024 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002025 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002026 << "_hidl_out_"
2027 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002028 << ");\n";
2029 }
2030 break;
2031 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002032 case PASSTHROUGH_ENTRY:
2033 {
2034 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2035 for (const auto &arg : method->args()) {
2036 out << "_hidl_args.push_back((void *)&"
2037 << arg->name()
2038 << ");\n";
2039 }
2040 break;
2041 }
2042 case PASSTHROUGH_EXIT:
2043 {
2044 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002045 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002046 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002047 << arg->name()
2048 << ");\n";
2049 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002050 break;
2051 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002052 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002053 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002054 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002055 return UNKNOWN_ERROR;
2056 }
2057 }
2058
Steven Moreland031ccf12016-10-31 15:54:38 -07002059 const Interface *iface = mRootScope->getInterface();
2060
Steven Moreland1ab31442016-11-03 18:37:51 -07002061 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002062 out.indent();
2063 out << "callback("
2064 << event_str
2065 << ", \""
2066 << mPackage.package()
2067 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002068 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002069 << "\", \""
2070 << iface->localName()
2071 << "\", \""
2072 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002073 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002074 out.unindent();
2075 out << "}\n";
2076 out.unindent();
2077 out << "}\n\n";
2078
2079 return OK;
2080}
2081
Andreas Huber881227d2016-08-02 14:20:21 -07002082} // namespace android