blob: 6dcd3cac8ccada115edec55e4f90cbe4b22917d6 [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 }
Andreas Huber881227d2016-08-02 14:20:21 -0700441 }
442
443 if (isInterface) {
444 out.unindent();
445
Andreas Hubere3f769a2016-10-10 10:54:44 -0700446 out << "};\n\n";
447 }
448
449 err = mRootScope->emitGlobalTypeDeclarations(out);
450
451 if (err != OK) {
452 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700453 }
454
455 out << "\n";
456 enterLeaveNamespace(out, false /* enter */);
457
458 out << "\n#endif // " << guard << "\n";
459
460 return OK;
461}
462
Steven Moreland40786312016-08-16 10:29:40 -0700463status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
464 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800465 bool isInterface = AST::isInterface(&ifaceName);
466 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800467 std::string klassName{};
468
469 if(isInterface) {
470 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800471 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800472 } else {
473 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700474 }
475
Steven Moreland40786312016-08-16 10:29:40 -0700476 std::string path = outputPath;
477 path.append(mCoordinator->convertPackageRootToPath(mPackage));
478 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
479 path.append(klassName + ".h");
480
Yifan Hong244e82d2016-11-11 11:13:57 -0800481 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700482
483 if (file == NULL) {
484 return -errno;
485 }
486
487 Formatter out(file);
488
489 const std::string guard = makeHeaderGuard(klassName);
490
491 out << "#ifndef " << guard << "\n";
492 out << "#define " << guard << "\n\n";
493
Yifan Hong244e82d2016-11-11 11:13:57 -0800494 if (isInterface) {
495 generateCppPackageInclude(out, mPackage, ifaceName);
496 } else {
497 generateCppPackageInclude(out, mPackage, "types");
498 }
Steven Moreland40786312016-08-16 10:29:40 -0700499
Steven Morelandee88eed2016-10-31 17:49:00 -0700500 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700501
502 for (const auto &item : mImportedNames) {
503 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800504 generateCppPackageInclude(out, item, "hwtypes");
505 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800506 generateCppPackageInclude(out, item, item.getInterfaceStubName());
507 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700508 }
Steven Moreland40786312016-08-16 10:29:40 -0700509 }
510
511 out << "\n";
512
Martijn Coenen93915102016-09-01 01:35:52 +0200513 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700514 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100515 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700516
517 out << "\n";
518
519 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700520
Yifan Hong244e82d2016-11-11 11:13:57 -0800521 status_t err = mRootScope->emitGlobalHwDeclarations(out);
522 if (err != OK) {
523 return err;
524 }
Steven Moreland40786312016-08-16 10:29:40 -0700525
526 enterLeaveNamespace(out, false /* enter */);
527
528 out << "\n#endif // " << guard << "\n";
529
530 return OK;
531}
532
Andreas Huber881227d2016-08-02 14:20:21 -0700533status_t AST::emitTypeDeclarations(Formatter &out) const {
534 return mRootScope->emitTypeDeclarations(out);
535}
536
Yifan Hong7a118f52016-12-07 11:21:15 -0800537static void wrapPassthroughArg(Formatter &out,
538 const TypedVar *arg, bool addPrefixToName,
539 std::function<void(void)> handleError) {
540 if (!arg->type().isInterface()) {
541 return;
542 }
543 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
544 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
545 + arg->name();
546 const Interface &iface = static_cast<const Interface &>(arg->type());
547 out << iface.getCppStackType() << " " << wrappedName << ";\n";
548 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
549 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
550 out << wrappedName
551 << " = "
552 << iface.fqName().cppName()
553 << "::castFrom(::android::hardware::wrapPassthrough("
554 << name << "));\n";
555 out.sIf(wrappedName + " == nullptr", [&] {
556 // Fatal error. Happens when the BsFoo class is not found in the binary
557 // or any dynamic libraries.
558 handleError();
559 }).endl();
560 }).sElse([&] {
561 out << wrappedName << " = " << name << ";\n";
562 }).endl().endl();
563}
564
Steven Moreland69e7c702016-09-09 11:16:32 -0700565status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700566 const Method *method) const {
567 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700568
569 out << " {\n";
570 out.indent();
571
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800572 if (method->isHidlReserved()
573 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
574 method->cppImpl(IMPL_PASSTHROUGH, out);
575 out.unindent();
576 out << "}\n\n";
577 return OK;
578 }
579
Steven Moreland69e7c702016-09-09 11:16:32 -0700580 const bool returnsValue = !method->results().empty();
581 const TypedVar *elidedReturn = method->canElideCallback();
582
Steven Moreland67f67b42016-09-29 08:59:02 -0700583 if (returnsValue && elidedReturn == nullptr) {
584 generateCheckNonNull(out, "_hidl_cb");
585 }
586
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700587 generateCppInstrumentationCall(
588 out,
589 InstrumentationEvent::PASSTHROUGH_ENTRY,
590 method);
591
Yifan Hong7a118f52016-12-07 11:21:15 -0800592
593 for (const auto &arg : method->args()) {
594 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
595 out << "return ::android::hardware::Status::fromExceptionCode(\n";
596 out.indent(2, [&] {
597 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800598 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800599 });
600 });
601 }
602
603 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700604 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700605
606 if (method->isOneway()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800607 out << "addOnewayTask([this, &_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700608 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800609 out << ", "
610 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
611 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700612 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700613 out << "] {\n";
614 out.indent();
615 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700616 }
617
618 out << "mImpl->"
619 << method->name()
620 << "(";
621
622 bool first = true;
623 for (const auto &arg : method->args()) {
624 if (!first) {
625 out << ", ";
626 }
627 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800628 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700629 }
630 if (returnsValue && elidedReturn == nullptr) {
631 if (!method->args().empty()) {
632 out << ", ";
633 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800634 out << "[&](";
635 first = true;
636 for (const auto &arg : method->results()) {
637 if (!first) {
638 out << ", ";
639 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700640
Yifan Hong7a118f52016-12-07 11:21:15 -0800641 out << "const auto &_hidl_out_"
642 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800643
644 first = false;
645 }
646
647 out << ") {\n";
648 out.indent();
649 status_t status = generateCppInstrumentationCall(
650 out,
651 InstrumentationEvent::PASSTHROUGH_EXIT,
652 method);
653 if (status != OK) {
654 return status;
655 }
656
Yifan Hong7a118f52016-12-07 11:21:15 -0800657 for (const auto &arg : method->results()) {
658 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
659 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
660 out.indent(2, [&] {
661 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800662 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800663 });
664 out << "return;\n";
665 });
666 }
667
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800668 out << "_hidl_cb(";
669 first = true;
670 for (const auto &arg : method->results()) {
671 if (!first) {
672 out << ", ";
673 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800674 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800675 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
676 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800677 }
678 out << ");\n";
679 out.unindent();
680 out << "});\n\n";
681 } else {
682 out << ");\n\n";
683 if (elidedReturn != nullptr) {
684 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800685 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800686 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000687 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800688 }
689 status_t status = generateCppInstrumentationCall(
690 out,
691 InstrumentationEvent::PASSTHROUGH_EXIT,
692 method);
693 if (status != OK) {
694 return status;
695 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700696 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700697
698 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700699 out.unindent();
700 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700701 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700702
703 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700704
705 out.unindent();
706 out << "}\n";
707
708 return OK;
709}
710
Yifan Hong068c5522016-10-31 14:07:25 -0700711status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700712
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700713 const Interface *iface = mRootScope->getInterface();
714
Yifan Hong10fe0b52016-10-19 14:20:17 -0700715 const Interface *prevIterface = nullptr;
716 for (const auto &tuple : iface->allMethodsFromRoot()) {
717 const Method *method = tuple.method();
718 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700719
Yifan Hong10fe0b52016-10-19 14:20:17 -0700720 if(prevIterface != superInterface) {
721 if (prevIterface != nullptr) {
722 out << "\n";
723 }
724 out << "// Methods from "
725 << superInterface->fullName()
726 << " follow.\n";
727 prevIterface = superInterface;
728 }
Yifan Hong068c5522016-10-31 14:07:25 -0700729 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700730
Yifan Hong10fe0b52016-10-19 14:20:17 -0700731 if (err != OK) {
732 return err;
733 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700734 }
735
Yifan Hong10fe0b52016-10-19 14:20:17 -0700736 out << "\n";
737
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700738 return OK;
739}
740
Andreas Huberb82318c2016-08-02 14:45:54 -0700741status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700742 std::string ifaceName;
743 if (!AST::isInterface(&ifaceName)) {
744 // types.hal does not get a stub header.
745 return OK;
746 }
747
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700748 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800749 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700750
Andreas Huberb82318c2016-08-02 14:45:54 -0700751 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700752 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700753 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700754 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700755 path.append(".h");
756
Andreas Huberd2943e12016-08-05 11:59:31 -0700757 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700758 FILE *file = fopen(path.c_str(), "w");
759
760 if (file == NULL) {
761 return -errno;
762 }
763
764 Formatter out(file);
765
Steven Moreland40786312016-08-16 10:29:40 -0700766 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700767
768 out << "#ifndef " << guard << "\n";
769 out << "#define " << guard << "\n\n";
770
Yifan Hongeefe4f22017-01-04 15:32:42 -0800771 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700772 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700773
774 enterLeaveNamespace(out, true /* enter */);
775 out << "\n";
776
777 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800778 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100779 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800780 out << " : public ::android::hardware::BHwBinder";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100781 out << ", public ::android::hardware::HidlInstrumentor {\n";
782 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800783 out << " : public "
784 << gIBaseFqName.getInterfaceStubFqName().cppName()
785 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100786 }
Andreas Huber881227d2016-08-02 14:20:21 -0700787
788 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800789 out << "explicit "
790 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700791 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100792 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800793 out << "explicit "
794 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100795 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800796 << " const std::string& HidlInstrumentor_package,"
797 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700798 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700799 out << "::android::status_t onTransact(\n";
800 out.indent();
801 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700802 out << "uint32_t _hidl_code,\n";
803 out << "const ::android::hardware::Parcel &_hidl_data,\n";
804 out << "::android::hardware::Parcel *_hidl_reply,\n";
805 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700806 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700807 out.unindent();
808 out.unindent();
809
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100810 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
811 out.unindent();
812 out << "private:\n";
813 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800814
815 status_t err = generateMethods(out, [&](const Method *method, const Interface *iface) {
816 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
817 return OK;
818 }
819 const bool returnsValue = !method->results().empty();
820 const TypedVar *elidedReturn = method->canElideCallback();
821
822 if (elidedReturn == nullptr && returnsValue) {
823 out << "using " << method->name() << "_cb = "
824 << iface->fqName().cppName()
825 << "::" << method->name() << "_cb;\n";
826 }
827 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800828 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800829 return OK;
830 });
831 if (err != OK) {
832 return err;
833 }
834
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100835 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700836 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700837 out << "};\n\n";
838
839 enterLeaveNamespace(out, false /* enter */);
840
841 out << "\n#endif // " << guard << "\n";
842
843 return OK;
844}
845
Andreas Huberb82318c2016-08-02 14:45:54 -0700846status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700847 std::string ifaceName;
848 if (!AST::isInterface(&ifaceName)) {
849 // types.hal does not get a proxy header.
850 return OK;
851 }
852
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700853 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800854 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700855
Andreas Huberb82318c2016-08-02 14:45:54 -0700856 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700857 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700858 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800859 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700860 path.append(".h");
861
Andreas Huberd2943e12016-08-05 11:59:31 -0700862 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700863 FILE *file = fopen(path.c_str(), "w");
864
865 if (file == NULL) {
866 return -errno;
867 }
868
869 Formatter out(file);
870
Yifan Hongeefe4f22017-01-04 15:32:42 -0800871 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700872
873 out << "#ifndef " << guard << "\n";
874 out << "#define " << guard << "\n\n";
875
Martijn Coenen115d4282016-12-19 05:14:04 +0100876 out << "#include <hidl/HidlTransportSupport.h>\n\n";
877
Andreas Huber881227d2016-08-02 14:20:21 -0700878 std::vector<std::string> packageComponents;
879 getPackageAndVersionComponents(
880 &packageComponents, false /* cpp_compatible */);
881
Yifan Hongeefe4f22017-01-04 15:32:42 -0800882 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700883 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700884
885 enterLeaveNamespace(out, true /* enter */);
886 out << "\n";
887
888 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800889 << proxyName
890 << " : public ::android::hardware::BpInterface<"
891 << iface->localName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700892 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700893
894 out.indent();
895
Yifan Hongeefe4f22017-01-04 15:32:42 -0800896 out << "explicit "
897 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700898 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700899 << "\n\n";
900
Yifan Hong10fe0b52016-10-19 14:20:17 -0700901 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700902
Yifan Hong068c5522016-10-31 14:07:25 -0700903 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
904 method->generateCppSignature(out);
905 out << " override;\n";
906 return OK;
907 });
Steven Moreland9c387612016-09-07 09:54:26 -0700908
909 if (err != OK) {
910 return err;
911 }
Andreas Huber881227d2016-08-02 14:20:21 -0700912
913 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100914 out << "private:\n";
915 out.indent();
916 out << "std::mutex _hidl_mMutex;\n"
917 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
918 << " _hidl_mDeathRecipients;\n";
919 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700920 out << "};\n\n";
921
922 enterLeaveNamespace(out, false /* enter */);
923
924 out << "\n#endif // " << guard << "\n";
925
926 return OK;
927}
928
Andreas Huberb82318c2016-08-02 14:45:54 -0700929status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700930
Andreas Huberb82318c2016-08-02 14:45:54 -0700931 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700932 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700933 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700934
935 std::string ifaceName;
936 std::string baseName;
937
Yifan Hongfe95aa22016-10-19 17:26:45 -0700938 const Interface *iface = nullptr;
939 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700940 if (!AST::isInterface(&ifaceName)) {
941 baseName = "types";
942 isInterface = false;
943 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700944 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700945 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700946 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700947 }
948
949 path.append(baseName);
950
951 if (baseName != "types") {
952 path.append("All");
953 }
954
955 path.append(".cpp");
956
Andreas Huberd2943e12016-08-05 11:59:31 -0700957 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700958 FILE *file = fopen(path.c_str(), "w");
959
960 if (file == NULL) {
961 return -errno;
962 }
963
964 Formatter out(file);
965
Steven Moreland623c0042017-01-13 14:42:29 -0800966 out << "#define LOG_TAG \""
967 << mPackage.string() << "::" << baseName
968 << "\"\n\n";
969
Steven Moreland05cd4232016-11-21 16:01:12 -0800970 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100971 out << "#include <cutils/trace.h>\n";
972 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700973 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700974 // This is a no-op for IServiceManager itself.
975 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
976
Steven Morelandbec74ed2017-01-25 17:42:35 -0800977 // TODO(b/34274385) remove this
978 out << "#include <hidl/LegacySupport.h>\n";
979
Yifan Hongeefe4f22017-01-04 15:32:42 -0800980 generateCppPackageInclude(out, mPackage, iface->getProxyName());
981 generateCppPackageInclude(out, mPackage, iface->getStubName());
982 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700983
984 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700985 generateCppPackageInclude(out,
986 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800987 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700988 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800989
990 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700991 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700992 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800993 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700994 }
995
996 out << "\n";
997
998 enterLeaveNamespace(out, true /* enter */);
999 out << "\n";
1000
1001 status_t err = generateTypeSource(out, ifaceName);
1002
1003 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001004 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001005
1006 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -08001007 out << "const char* "
1008 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -07001009 << "::descriptor(\""
1010 << iface->fqName().string()
1011 << "\");\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +01001012 out << "__attribute__((constructor))";
1013 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001014 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001015 out << "::android::hardware::gBnConstructorMap["
1016 << iface->localName()
Steven Morelandd39133b2016-11-11 12:30:08 -08001017 << "::descriptor]\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001018 out.indent(2, [&] {
Yifan Hong158655a2016-11-08 12:34:07 -08001019 out << "= [](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001020 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001021 out << "return new "
1022 << iface->getStubName()
1023 << "(reinterpret_cast<"
1024 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001025 << " *>(iIntf));\n";
1026 });
1027 out << "};\n";
1028 });
Yifan Hongeefe4f22017-01-04 15:32:42 -08001029 out << "::android::hardware::gBsConstructorMap["
1030 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001031 << "::descriptor]\n";
1032 out.indent(2, [&] {
1033 out << "= [](void *iIntf) -> ::android::sp<"
1034 << gIBaseFqName.cppName()
1035 << "> {\n";
1036 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001037 out << "return new "
1038 << iface->getPassthroughName()
1039 << "(reinterpret_cast<"
1040 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001041 << " *>(iIntf));\n";
1042 });
1043 out << "};\n";
1044 });
Yifan Hong158655a2016-11-08 12:34:07 -08001045 });
Martijn Coenen8adcb652017-02-03 17:37:36 +01001046 out << "};\n\n";
1047 out << "__attribute__((destructor))";
1048 out << "static void static_destructor() {\n";
1049 out.indent([&] {
1050 out << "::android::hardware::gBnConstructorMap.erase("
1051 << iface->localName()
1052 << "::descriptor);\n";
1053 out << "::android::hardware::gBsConstructorMap.erase("
1054 << iface->localName()
1055 << "::descriptor);\n";
1056 });
1057 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001058
Yifan Hongfe95aa22016-10-19 17:26:45 -07001059 err = generateInterfaceSource(out);
1060 }
1061
1062 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001063 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001064 }
1065
1066 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001067 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001068 }
1069
Steven Moreland40786312016-08-16 10:29:40 -07001070 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001071 err = generatePassthroughSource(out);
1072 }
1073
1074 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001075 const Interface *iface = mRootScope->getInterface();
1076
Yifan Hongc8934042016-11-17 17:10:52 -08001077 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001078 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001079 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001080 std::string package = iface->fqName().package()
1081 + iface->fqName().atVersion();
1082
Yifan Hongeefe4f22017-01-04 15:32:42 -08001083 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001084 }
Steven Moreland40786312016-08-16 10:29:40 -07001085 }
1086
Andreas Huber881227d2016-08-02 14:20:21 -07001087 enterLeaveNamespace(out, false /* enter */);
1088
1089 return err;
1090}
1091
Steven Moreland67f67b42016-09-29 08:59:02 -07001092// static
1093void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001094 out.sIf(nonNull + " == nullptr", [&] {
1095 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1096 out.indent(2, [&] {
1097 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1098 });
1099 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001100}
1101
Andreas Huber881227d2016-08-02 14:20:21 -07001102status_t AST::generateTypeSource(
1103 Formatter &out, const std::string &ifaceName) const {
1104 return mRootScope->emitTypeDefinitions(out, ifaceName);
1105}
1106
Andreas Hubere7ff2282016-08-16 13:50:03 -07001107void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001108 Formatter &out,
1109 const std::vector<TypedVar *> &args,
1110 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001111 if (args.empty()) {
1112 return;
1113 }
1114
1115 for (const auto &arg : args) {
1116 const Type &type = arg->type();
1117
Yifan Hong3b320f82016-11-01 15:15:54 -07001118 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001119 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001120 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001121 << ";\n";
1122 }
1123
1124 out << "\n";
1125}
1126
Andreas Huber881227d2016-08-02 14:20:21 -07001127void AST::emitCppReaderWriter(
1128 Formatter &out,
1129 const std::string &parcelObj,
1130 bool parcelObjIsPointer,
1131 const TypedVar *arg,
1132 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001133 Type::ErrorMode mode,
1134 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001135 const Type &type = arg->type();
1136
Andreas Huber881227d2016-08-02 14:20:21 -07001137 type.emitReaderWriter(
1138 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001139 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001140 parcelObj,
1141 parcelObjIsPointer,
1142 isReader,
1143 mode);
1144}
1145
Yifan Hongbf459bc2016-08-23 16:50:37 -07001146void AST::emitCppResolveReferences(
1147 Formatter &out,
1148 const std::string &parcelObj,
1149 bool parcelObjIsPointer,
1150 const TypedVar *arg,
1151 bool isReader,
1152 Type::ErrorMode mode,
1153 bool addPrefixToName) const {
1154 const Type &type = arg->type();
1155 if(type.needsResolveReferences()) {
1156 type.emitResolveReferences(
1157 out,
1158 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1159 isReader, // nameIsPointer
1160 parcelObj,
1161 parcelObjIsPointer,
1162 isReader,
1163 mode);
1164 }
1165}
1166
Yifan Hong068c5522016-10-31 14:07:25 -07001167status_t AST::generateProxyMethodSource(Formatter &out,
1168 const std::string &klassName,
1169 const Method *method,
1170 const Interface *superInterface) const {
1171
1172 method->generateCppSignature(out,
1173 klassName,
1174 true /* specify namespaces */);
1175
1176 const bool returnsValue = !method->results().empty();
1177 const TypedVar *elidedReturn = method->canElideCallback();
1178
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001179 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001180
1181 out.indent();
1182
Martijn Coenen115d4282016-12-19 05:14:04 +01001183 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1184 method->cppImpl(IMPL_PROXY, out);
1185 out.unindent();
1186 out << "}\n\n";
1187 return OK;
1188 }
1189
Yifan Hong068c5522016-10-31 14:07:25 -07001190 if (returnsValue && elidedReturn == nullptr) {
1191 generateCheckNonNull(out, "_hidl_cb");
1192 }
1193
1194 status_t status = generateCppInstrumentationCall(
1195 out,
1196 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001197 method);
1198 if (status != OK) {
1199 return status;
1200 }
1201
1202 out << "::android::hardware::Parcel _hidl_data;\n";
1203 out << "::android::hardware::Parcel _hidl_reply;\n";
1204 out << "::android::status_t _hidl_err;\n";
1205 out << "::android::hardware::Status _hidl_status;\n\n";
1206
1207 declareCppReaderLocals(
1208 out, method->results(), true /* forResults */);
1209
1210 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001211 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001212 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001213 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1214
Martijn Coenenfff73352017-01-04 16:36:31 +01001215 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001216 // First DFS: write all buffers and resolve pointers for parent
1217 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001218 if (arg->type().isInterface()) {
1219 hasInterfaceArgument = true;
1220 }
Yifan Hong068c5522016-10-31 14:07:25 -07001221 emitCppReaderWriter(
1222 out,
1223 "_hidl_data",
1224 false /* parcelObjIsPointer */,
1225 arg,
1226 false /* reader */,
1227 Type::ErrorMode_Goto,
1228 false /* addPrefixToName */);
1229 }
1230
1231 // Second DFS: resolve references.
1232 for (const auto &arg : method->args()) {
1233 emitCppResolveReferences(
1234 out,
1235 "_hidl_data",
1236 false /* parcelObjIsPointer */,
1237 arg,
1238 false /* reader */,
1239 Type::ErrorMode_Goto,
1240 false /* addPrefixToName */);
1241 }
1242
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001243 if (hasInterfaceArgument) {
1244 // Start binder threadpool to handle incoming transactions
1245 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1246 }
Yifan Hong068c5522016-10-31 14:07:25 -07001247 out << "_hidl_err = remote()->transact("
1248 << method->getSerialId()
1249 << " /* "
1250 << method->name()
1251 << " */, _hidl_data, &_hidl_reply";
1252
1253 if (method->isOneway()) {
1254 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1255 }
1256 out << ");\n";
1257
1258 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1259
1260 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001261 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001262 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1263 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1264
1265
1266 // First DFS: write all buffers and resolve pointers for parent
1267 for (const auto &arg : method->results()) {
1268 emitCppReaderWriter(
1269 out,
1270 "_hidl_reply",
1271 false /* parcelObjIsPointer */,
1272 arg,
1273 true /* reader */,
1274 Type::ErrorMode_Goto,
1275 true /* addPrefixToName */);
1276 }
1277
1278 // Second DFS: resolve references.
1279 for (const auto &arg : method->results()) {
1280 emitCppResolveReferences(
1281 out,
1282 "_hidl_reply",
1283 false /* parcelObjIsPointer */,
1284 arg,
1285 true /* reader */,
1286 Type::ErrorMode_Goto,
1287 true /* addPrefixToName */);
1288 }
1289
1290 if (returnsValue && elidedReturn == nullptr) {
1291 out << "_hidl_cb(";
1292
1293 bool first = true;
1294 for (const auto &arg : method->results()) {
1295 if (!first) {
1296 out << ", ";
1297 }
1298
1299 if (arg->type().resultNeedsDeref()) {
1300 out << "*";
1301 }
1302 out << "_hidl_out_" << arg->name();
1303
1304 first = false;
1305 }
1306
1307 out << ");\n\n";
1308 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001309 }
1310 status = generateCppInstrumentationCall(
1311 out,
1312 InstrumentationEvent::CLIENT_API_EXIT,
1313 method);
1314 if (status != OK) {
1315 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001316 }
1317
1318 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001319 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1320 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001321 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001322 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1323 } else {
1324 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1325 out << "return ::android::hardware::Return<void>();\n\n";
1326 }
1327
1328 out.unindent();
1329 out << "_hidl_error:\n";
1330 out.indent();
1331 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1332 out << "return ::android::hardware::Return<";
1333 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001334 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001335 } else {
1336 out << "void";
1337 }
1338 out << ">(_hidl_status);\n";
1339
1340 out.unindent();
1341 out << "}\n\n";
1342 return OK;
1343}
1344
Andreas Huber881227d2016-08-02 14:20:21 -07001345status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001346 Formatter &out, const FQName &fqName) const {
1347 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001348
1349 out << klassName
1350 << "::"
1351 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001352 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001353
1354 out.indent();
1355 out.indent();
1356
1357 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001358 << "<"
1359 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001360 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001361 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001362 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001363 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001364 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001365 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001366
Andreas Huber881227d2016-08-02 14:20:21 -07001367 out.unindent();
1368 out.unindent();
1369 out << "}\n\n";
1370
Yifan Hong068c5522016-10-31 14:07:25 -07001371 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1372 return generateProxyMethodSource(out, klassName, method, superInterface);
1373 });
Andreas Huber881227d2016-08-02 14:20:21 -07001374
Yifan Hong068c5522016-10-31 14:07:25 -07001375 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001376}
1377
1378status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001379 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001380 const Interface *iface) const {
1381 const std::string interfaceName = iface->localName();
1382 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001383
Steven Moreland40786312016-08-16 10:29:40 -07001384 out << klassName
1385 << "::"
1386 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001387 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001388
1389 out.indent();
1390 out.indent();
1391
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001392 if (iface->isIBase()) {
1393 out << ": ::android::hardware::HidlInstrumentor(\"";
1394 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001395 out << ": "
1396 << gIBaseFqName.getInterfaceStubFqName().cppName()
1397 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001398 }
1399
1400 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001401 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001402 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001403 << "\") { \n";
1404 out.indent();
1405 out << "_hidl_mImpl = _hidl_impl;\n";
1406 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001407
1408 out.unindent();
1409 out.unindent();
1410 out << "}\n\n";
1411
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001412 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001413 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001414 // class properly.
1415 out << klassName
1416 << "::"
1417 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001418 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1419 << " const std::string &HidlInstrumentor_package,"
1420 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001421
1422 out.indent();
1423 out.indent();
1424
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001425 out << ": ::android::hardware::HidlInstrumentor("
1426 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001427 out.indent();
1428 out << "_hidl_mImpl = _hidl_impl;\n";
1429 out.unindent();
1430
1431 out.unindent();
1432 out.unindent();
1433 out << "}\n\n";
1434 }
1435
Yifan Hongbcffce22017-02-01 15:52:06 -08001436 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1437 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1438 return OK;
1439 }
1440 method->generateCppSignature(out, iface->getStubName());
1441 out << " ";
1442 out.block([&] {
1443 method->cppImpl(IMPL_STUB_IMPL, out);
1444 }).endl();
1445 return OK;
1446 });
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001447
Andreas Huber881227d2016-08-02 14:20:21 -07001448 out << "::android::status_t " << klassName << "::onTransact(\n";
1449
1450 out.indent();
1451 out.indent();
1452
Iliyan Malchev549e2592016-08-10 08:59:12 -07001453 out << "uint32_t _hidl_code,\n"
1454 << "const ::android::hardware::Parcel &_hidl_data,\n"
1455 << "::android::hardware::Parcel *_hidl_reply,\n"
1456 << "uint32_t _hidl_flags,\n"
1457 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001458
1459 out.unindent();
1460
Iliyan Malchev549e2592016-08-10 08:59:12 -07001461 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001462 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001463 out.indent();
1464
Yifan Hong10fe0b52016-10-19 14:20:17 -07001465 for (const auto &tuple : iface->allMethodsFromRoot()) {
1466 const Method *method = tuple.method();
1467 const Interface *superInterface = tuple.interface();
1468 out << "case "
1469 << method->getSerialId()
1470 << " /* "
1471 << method->name()
1472 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001473
Yifan Hong10fe0b52016-10-19 14:20:17 -07001474 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001475
Yifan Hong10fe0b52016-10-19 14:20:17 -07001476 status_t err =
1477 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001478
Yifan Hong10fe0b52016-10-19 14:20:17 -07001479 if (err != OK) {
1480 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001481 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001482
1483 out.unindent();
1484 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001485 }
1486
1487 out << "default:\n{\n";
1488 out.indent();
1489
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001490 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001491
1492 out.indent();
1493 out.indent();
1494
Iliyan Malchev549e2592016-08-10 08:59:12 -07001495 out << "_hidl_code, _hidl_data, _hidl_reply, "
1496 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001497
1498 out.unindent();
1499 out.unindent();
1500
1501 out.unindent();
1502 out << "}\n";
1503
1504 out.unindent();
1505 out << "}\n\n";
1506
Yifan Honga018ed52016-12-13 16:35:08 -08001507 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1508 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1509 out.indent(2, [&] {
1510 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1511 out << "_hidl_reply);\n";
1512 });
1513 });
Andreas Huber881227d2016-08-02 14:20:21 -07001514
Iliyan Malchev549e2592016-08-10 08:59:12 -07001515 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001516
1517 out.unindent();
1518 out << "}\n\n";
1519
1520 return OK;
1521}
1522
1523status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001524 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001525 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1526 method->cppImpl(IMPL_STUB, out);
1527 out << "break;\n";
1528 return OK;
1529 }
1530
Yifan Hongeefe4f22017-01-04 15:32:42 -08001531 out << "if (!_hidl_data.enforceInterface("
1532 << iface->fullName()
1533 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001534
Andreas Huber881227d2016-08-02 14:20:21 -07001535 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001536 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001537 out << "break;\n";
1538 out.unindent();
1539 out << "}\n\n";
1540
Andreas Huber5e44a292016-09-27 14:52:39 -07001541 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001542
Yifan Hongbf459bc2016-08-23 16:50:37 -07001543 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001544 for (const auto &arg : method->args()) {
1545 emitCppReaderWriter(
1546 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001547 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001548 false /* parcelObjIsPointer */,
1549 arg,
1550 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001551 Type::ErrorMode_Break,
1552 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001553 }
1554
Yifan Hongbf459bc2016-08-23 16:50:37 -07001555 // Second DFS: resolve references
1556 for (const auto &arg : method->args()) {
1557 emitCppResolveReferences(
1558 out,
1559 "_hidl_data",
1560 false /* parcelObjIsPointer */,
1561 arg,
1562 true /* reader */,
1563 Type::ErrorMode_Break,
1564 false /* addPrefixToName */);
1565 }
1566
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001567 status_t status = generateCppInstrumentationCall(
1568 out,
1569 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001570 method);
1571 if (status != OK) {
1572 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001573 }
1574
Andreas Huber881227d2016-08-02 14:20:21 -07001575 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001576 const TypedVar *elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -08001577 const std::string callee =
1578 (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL))
1579 ? "this" : "_hidl_mImpl";
Andreas Huber881227d2016-08-02 14:20:21 -07001580
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001581 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001582 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001583 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001584 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001585 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001586 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001587 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001588
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001589 bool first = true;
1590 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001591 if (!first) {
1592 out << ", ";
1593 }
1594
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001595 if (arg->type().resultNeedsDeref()) {
1596 out << "*";
1597 }
1598
1599 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001600
1601 first = false;
1602 }
1603
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001604 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001605 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1606 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001607
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001608 elidedReturn->type().emitReaderWriter(
1609 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001610 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001611 "_hidl_reply",
1612 true, /* parcelObjIsPointer */
1613 false, /* isReader */
1614 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001615
Yifan Hongbf459bc2016-08-23 16:50:37 -07001616 emitCppResolveReferences(
1617 out,
1618 "_hidl_reply",
1619 true /* parcelObjIsPointer */,
1620 elidedReturn,
1621 false /* reader */,
1622 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001623 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001624
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001625 status_t status = generateCppInstrumentationCall(
1626 out,
1627 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001628 method);
1629 if (status != OK) {
1630 return status;
1631 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001632
Iliyan Malchev549e2592016-08-10 08:59:12 -07001633 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001634 } else {
1635 if (returnsValue) {
1636 out << "bool _hidl_callbackCalled = false;\n\n";
1637 }
Andreas Huber881227d2016-08-02 14:20:21 -07001638
Yifan Hongcd2ae452017-01-31 14:33:40 -08001639 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001640
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001641 bool first = true;
1642 for (const auto &arg : method->args()) {
1643 if (!first) {
1644 out << ", ";
1645 }
Andreas Huber881227d2016-08-02 14:20:21 -07001646
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001647 if (arg->type().resultNeedsDeref()) {
1648 out << "*";
1649 }
1650
1651 out << arg->name();
1652
1653 first = false;
1654 }
1655
1656 if (returnsValue) {
1657 if (!first) {
1658 out << ", ";
1659 }
1660
1661 out << "[&](";
1662
1663 first = true;
1664 for (const auto &arg : method->results()) {
1665 if (!first) {
1666 out << ", ";
1667 }
1668
Yifan Honga47eef32016-12-12 10:38:54 -08001669 out << "const auto &_hidl_out_" << arg->name();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001670
1671 first = false;
1672 }
1673
1674 out << ") {\n";
1675 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001676 out << "if (_hidl_callbackCalled) {\n";
1677 out.indent();
1678 out << "LOG_ALWAYS_FATAL(\""
1679 << method->name()
1680 << ": _hidl_cb called a second time, but must be called once.\");\n";
1681 out.unindent();
1682 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001683 out << "_hidl_callbackCalled = true;\n\n";
1684
Yifan Hong859e53f2016-11-14 19:08:24 -08001685 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1686 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001687
Yifan Hongbf459bc2016-08-23 16:50:37 -07001688 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001689 for (const auto &arg : method->results()) {
1690 emitCppReaderWriter(
1691 out,
1692 "_hidl_reply",
1693 true /* parcelObjIsPointer */,
1694 arg,
1695 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001696 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001697 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001698 }
1699
Yifan Hongbf459bc2016-08-23 16:50:37 -07001700 // Second DFS: resolve references
1701 for (const auto &arg : method->results()) {
1702 emitCppResolveReferences(
1703 out,
1704 "_hidl_reply",
1705 true /* parcelObjIsPointer */,
1706 arg,
1707 false /* reader */,
1708 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001709 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001710 }
1711
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001712 status_t status = generateCppInstrumentationCall(
1713 out,
1714 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001715 method);
1716 if (status != OK) {
1717 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001718 }
1719
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001720 out << "_hidl_cb(*_hidl_reply);\n";
1721
1722 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001723 out << "});\n\n";
1724 } else {
1725 out << ");\n\n";
1726 status_t status = generateCppInstrumentationCall(
1727 out,
1728 InstrumentationEvent::SERVER_API_EXIT,
1729 method);
1730 if (status != OK) {
1731 return status;
1732 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001733 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001734
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001735 if (returnsValue) {
1736 out << "if (!_hidl_callbackCalled) {\n";
1737 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001738 out << "LOG_ALWAYS_FATAL(\""
1739 << method->name()
1740 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001741 out.unindent();
1742 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001743 } else {
1744 out << "::android::hardware::writeToParcel("
1745 << "::android::hardware::Status::ok(), "
1746 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001747 }
Andreas Huber881227d2016-08-02 14:20:21 -07001748 }
1749
1750 out << "break;\n";
1751
1752 return OK;
1753}
1754
Steven Moreland69e7c702016-09-09 11:16:32 -07001755status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1756 std::string ifaceName;
1757 if (!AST::isInterface(&ifaceName)) {
1758 // types.hal does not get a stub header.
1759 return OK;
1760 }
1761
1762 const Interface *iface = mRootScope->getInterface();
1763
Yifan Hongeefe4f22017-01-04 15:32:42 -08001764 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001765
1766 bool supportOneway = iface->hasOnewayMethods();
1767
1768 std::string path = outputPath;
1769 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1770 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1771 path.append(klassName);
1772 path.append(".h");
1773
1774 CHECK(Coordinator::MakeParentHierarchy(path));
1775 FILE *file = fopen(path.c_str(), "w");
1776
1777 if (file == NULL) {
1778 return -errno;
1779 }
1780
1781 Formatter out(file);
1782
1783 const std::string guard = makeHeaderGuard(klassName);
1784
1785 out << "#ifndef " << guard << "\n";
1786 out << "#define " << guard << "\n\n";
1787
1788 std::vector<std::string> packageComponents;
1789 getPackageAndVersionComponents(
1790 &packageComponents, false /* cpp_compatible */);
1791
Yifan Hongb0949432016-12-15 15:32:24 -08001792 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001793 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001794
1795 generateCppPackageInclude(out, mPackage, ifaceName);
1796 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001797
Yifan Hong7a118f52016-12-07 11:21:15 -08001798 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001799 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001800 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001801 }
1802
1803 enterLeaveNamespace(out, true /* enter */);
1804 out << "\n";
1805
1806 out << "struct "
1807 << klassName
1808 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001809 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001810
1811 out.indent();
1812 out << "explicit "
1813 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001814 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001815 << ifaceName
1816 << "> impl);\n";
1817
Yifan Hong068c5522016-10-31 14:07:25 -07001818 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1819 return generatePassthroughMethod(out, method);
1820 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001821
1822 if (err != OK) {
1823 return err;
1824 }
1825
1826 out.unindent();
1827 out << "private:\n";
1828 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001829 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001830
1831 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001832 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001833
1834 out << "\n";
1835
1836 out << "::android::hardware::Return<void> addOnewayTask("
1837 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001838 }
1839
1840 out.unindent();
1841
1842 out << "};\n\n";
1843
1844 enterLeaveNamespace(out, false /* enter */);
1845
1846 out << "\n#endif // " << guard << "\n";
1847
1848 return OK;
1849}
1850
Yifan Hongfe95aa22016-10-19 17:26:45 -07001851status_t AST::generateInterfaceSource(Formatter &out) const {
1852 const Interface *iface = mRootScope->getInterface();
1853
Yifan Hong2d7126b2016-10-20 15:12:57 -07001854 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001855 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001856
Yifan Hong3d746092016-12-07 14:26:33 -08001857 for (const Interface *superType : iface->typeChain()) {
1858 out << "// static \n"
1859 << childTypeResult
Yifan Hongeefe4f22017-01-04 15:32:42 -08001860 << " "
1861 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001862 << "::castFrom("
1863 << superType->getCppArgumentType()
1864 << " parent) {\n";
1865 out.indent();
1866 if (iface == superType) {
1867 out << "return parent;\n";
1868 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001869 out << "return ::android::hardware::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001870 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001871 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001872 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001873 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001874 << ">(\n";
1875 out.indent();
1876 out.indent();
1877 out << "parent, \""
1878 << iface->fqName().string()
1879 << "\");\n";
1880 out.unindent();
1881 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001882 }
Yifan Hong3d746092016-12-07 14:26:33 -08001883 out.unindent();
1884 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001885 }
1886
1887 return OK;
1888}
1889
Steven Moreland69e7c702016-09-09 11:16:32 -07001890status_t AST::generatePassthroughSource(Formatter &out) const {
1891 const Interface *iface = mRootScope->getInterface();
1892
Yifan Hongeefe4f22017-01-04 15:32:42 -08001893 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001894
1895 out << klassName
1896 << "::"
1897 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001898 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001899 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001900 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001901 << mPackage.string()
1902 << "\", \""
1903 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001904 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001905 if (iface->hasOnewayMethods()) {
1906 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001907 out.indent([&] {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001908 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1909 });
1910 }
1911 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001912
1913 if (iface->hasOnewayMethods()) {
1914 out << "::android::hardware::Return<void> "
1915 << klassName
1916 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1917 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001918 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001919 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001920 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1921 out.indent();
1922 out.indent();
1923 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1924 out.unindent();
1925 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001926 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001927 out << "}\n";
1928
Steven Morelandd366c262016-10-11 15:29:10 -07001929 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001930
1931 out.unindent();
1932 out << "}\n\n";
1933
1934
1935 }
1936
1937 return OK;
1938}
1939
Martijn Coenen7b295242016-11-04 16:52:56 +01001940status_t AST::generateCppAtraceCall(Formatter &out,
1941 InstrumentationEvent event,
1942 const Method *method) const {
1943 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001944 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001945 switch (event) {
1946 case SERVER_API_ENTRY:
1947 {
1948 out << "atrace_begin(ATRACE_TAG_HAL, \""
1949 << baseString + "::server\");\n";
1950 break;
1951 }
1952 case CLIENT_API_ENTRY:
1953 {
1954 out << "atrace_begin(ATRACE_TAG_HAL, \""
1955 << baseString + "::client\");\n";
1956 break;
1957 }
1958 case PASSTHROUGH_ENTRY:
1959 {
1960 out << "atrace_begin(ATRACE_TAG_HAL, \""
1961 << baseString + "::passthrough\");\n";
1962 break;
1963 }
1964 case SERVER_API_EXIT:
1965 case CLIENT_API_EXIT:
1966 case PASSTHROUGH_EXIT:
1967 {
1968 out << "atrace_end(ATRACE_TAG_HAL);\n";
1969 break;
1970 }
1971 default:
1972 {
1973 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1974 return UNKNOWN_ERROR;
1975 }
1976 }
1977
1978 return OK;
1979}
1980
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001981status_t AST::generateCppInstrumentationCall(
1982 Formatter &out,
1983 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001984 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001985 status_t err = generateCppAtraceCall(out, event, method);
1986 if (err != OK) {
1987 return err;
1988 }
1989
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001990 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1991 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001992 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001993 std::string event_str = "";
1994 switch (event) {
1995 case SERVER_API_ENTRY:
1996 {
1997 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1998 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001999 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002000 << (arg->type().resultNeedsDeref() ? "" : "&")
2001 << arg->name()
2002 << ");\n";
2003 }
2004 break;
2005 }
2006 case SERVER_API_EXIT:
2007 {
2008 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07002009 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002010 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07002011 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002012 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002013 }
2014 break;
2015 }
2016 case CLIENT_API_ENTRY:
2017 {
2018 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2019 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002020 out << "_hidl_args.push_back((void *)&"
2021 << arg->name()
2022 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002023 }
2024 break;
2025 }
2026 case CLIENT_API_EXIT:
2027 {
2028 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2029 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002030 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002031 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002032 << "_hidl_out_"
2033 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002034 << ");\n";
2035 }
2036 break;
2037 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002038 case PASSTHROUGH_ENTRY:
2039 {
2040 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2041 for (const auto &arg : method->args()) {
2042 out << "_hidl_args.push_back((void *)&"
2043 << arg->name()
2044 << ");\n";
2045 }
2046 break;
2047 }
2048 case PASSTHROUGH_EXIT:
2049 {
2050 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002051 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002052 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002053 << arg->name()
2054 << ");\n";
2055 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002056 break;
2057 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002058 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002059 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002060 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002061 return UNKNOWN_ERROR;
2062 }
2063 }
2064
Steven Moreland031ccf12016-10-31 15:54:38 -07002065 const Interface *iface = mRootScope->getInterface();
2066
Steven Moreland1ab31442016-11-03 18:37:51 -07002067 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002068 out.indent();
2069 out << "callback("
2070 << event_str
2071 << ", \""
2072 << mPackage.package()
2073 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002074 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002075 << "\", \""
2076 << iface->localName()
2077 << "\", \""
2078 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002079 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002080 out.unindent();
2081 out << "}\n";
2082 out.unindent();
2083 out << "}\n\n";
2084
2085 return OK;
2086}
2087
Andreas Huber881227d2016-08-02 14:20:21 -07002088} // namespace android