blob: 1302d8169c73ed96f80ad98287d8629c21d23652 [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();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800362
Yifan Hongc8934042016-11-17 17:10:52 -0800363 out << "virtual bool isRemote() const ";
364 if (!isIBase()) {
365 out << "override ";
366 }
367 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800368
Andreas Huber881227d2016-08-02 14:20:21 -0700369 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700370 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700371
Andreas Huber881227d2016-08-02 14:20:21 -0700372 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800373 const TypedVar *elidedReturn = method->canElideCallback();
374
375 if (elidedReturn == nullptr && returnsValue) {
376 out << "using "
377 << method->name()
378 << "_cb = std::function<void("
379 << Method::GetArgSignature(method->results(),
380 true /* specify namespaces */)
381 << ")>;\n";
382 }
Andreas Huber881227d2016-08-02 14:20:21 -0700383
Andreas Huber3599d922016-08-09 10:42:57 -0700384 method->dumpAnnotations(out);
385
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700386 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700387 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700388 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700389 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700390 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700391 }
392
393 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700394 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700395 << Method::GetArgSignature(method->args(),
396 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700397
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700398 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700399 if (!method->args().empty()) {
400 out << ", ";
401 }
402
Steven Moreland67f67b42016-09-29 08:59:02 -0700403 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700404 }
405
Yifan Hong10fe0b52016-10-19 14:20:17 -0700406 out << ")";
407 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800408 if (!isIBase()) {
409 out << " override";
410 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700411 out << " {\n";
412 out.indent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100413 method->cppImpl(IMPL_HEADER, out);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700414 out.unindent();
415 out << "\n}\n";
416 } else {
417 out << " = 0;\n";
418 }
Andreas Huber881227d2016-08-02 14:20:21 -0700419 }
Steven Moreland40786312016-08-16 10:29:40 -0700420
Yifan Hong3d746092016-12-07 14:26:33 -0800421 out << "// cast static functions\n";
422 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700423
Yifan Hong3d746092016-12-07 14:26:33 -0800424 for (const Interface *superType : iface->typeChain()) {
425 out << "static "
426 << childTypeResult
427 << " castFrom("
428 << superType->getCppArgumentType()
429 << " parent"
430 << ");\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700431 }
432
Steven Morelandd39133b2016-11-11 12:30:08 -0800433 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700434
Yifan Hongc8934042016-11-17 17:10:52 -0800435 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800436 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800437 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800438 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800439 }
Andreas Huber881227d2016-08-02 14:20:21 -0700440 }
441
442 if (isInterface) {
443 out.unindent();
444
Andreas Hubere3f769a2016-10-10 10:54:44 -0700445 out << "};\n\n";
446 }
447
448 err = mRootScope->emitGlobalTypeDeclarations(out);
449
450 if (err != OK) {
451 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700452 }
453
454 out << "\n";
455 enterLeaveNamespace(out, false /* enter */);
456
457 out << "\n#endif // " << guard << "\n";
458
459 return OK;
460}
461
Steven Moreland40786312016-08-16 10:29:40 -0700462status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
463 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800464 bool isInterface = AST::isInterface(&ifaceName);
465 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800466 std::string klassName{};
467
468 if(isInterface) {
469 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800470 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800471 } else {
472 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700473 }
474
Steven Moreland40786312016-08-16 10:29:40 -0700475 std::string path = outputPath;
476 path.append(mCoordinator->convertPackageRootToPath(mPackage));
477 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
478 path.append(klassName + ".h");
479
Yifan Hong244e82d2016-11-11 11:13:57 -0800480 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700481
482 if (file == NULL) {
483 return -errno;
484 }
485
486 Formatter out(file);
487
488 const std::string guard = makeHeaderGuard(klassName);
489
490 out << "#ifndef " << guard << "\n";
491 out << "#define " << guard << "\n\n";
492
Yifan Hong244e82d2016-11-11 11:13:57 -0800493 if (isInterface) {
494 generateCppPackageInclude(out, mPackage, ifaceName);
495 } else {
496 generateCppPackageInclude(out, mPackage, "types");
497 }
Steven Moreland40786312016-08-16 10:29:40 -0700498
Steven Morelandee88eed2016-10-31 17:49:00 -0700499 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700500
501 for (const auto &item : mImportedNames) {
502 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800503 generateCppPackageInclude(out, item, "hwtypes");
504 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800505 generateCppPackageInclude(out, item, item.getInterfaceStubName());
506 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700507 }
Steven Moreland40786312016-08-16 10:29:40 -0700508 }
509
510 out << "\n";
511
Martijn Coenen93915102016-09-01 01:35:52 +0200512 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700513 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100514 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700515
516 out << "\n";
517
518 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700519
Yifan Hong244e82d2016-11-11 11:13:57 -0800520 status_t err = mRootScope->emitGlobalHwDeclarations(out);
521 if (err != OK) {
522 return err;
523 }
Steven Moreland40786312016-08-16 10:29:40 -0700524
525 enterLeaveNamespace(out, false /* enter */);
526
527 out << "\n#endif // " << guard << "\n";
528
529 return OK;
530}
531
Andreas Huber881227d2016-08-02 14:20:21 -0700532status_t AST::emitTypeDeclarations(Formatter &out) const {
533 return mRootScope->emitTypeDeclarations(out);
534}
535
Yifan Hong7a118f52016-12-07 11:21:15 -0800536static void wrapPassthroughArg(Formatter &out,
537 const TypedVar *arg, bool addPrefixToName,
538 std::function<void(void)> handleError) {
539 if (!arg->type().isInterface()) {
540 return;
541 }
542 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
543 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
544 + arg->name();
545 const Interface &iface = static_cast<const Interface &>(arg->type());
546 out << iface.getCppStackType() << " " << wrappedName << ";\n";
547 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
548 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
549 out << wrappedName
550 << " = "
551 << iface.fqName().cppName()
552 << "::castFrom(::android::hardware::wrapPassthrough("
553 << name << "));\n";
554 out.sIf(wrappedName + " == nullptr", [&] {
555 // Fatal error. Happens when the BsFoo class is not found in the binary
556 // or any dynamic libraries.
557 handleError();
558 }).endl();
559 }).sElse([&] {
560 out << wrappedName << " = " << name << ";\n";
561 }).endl().endl();
562}
563
Steven Moreland69e7c702016-09-09 11:16:32 -0700564status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700565 const Method *method) const {
566 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700567
568 out << " {\n";
569 out.indent();
570
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800571 if (method->isHidlReserved()
572 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
573 method->cppImpl(IMPL_PASSTHROUGH, out);
574 out.unindent();
575 out << "}\n\n";
576 return OK;
577 }
578
Steven Moreland69e7c702016-09-09 11:16:32 -0700579 const bool returnsValue = !method->results().empty();
580 const TypedVar *elidedReturn = method->canElideCallback();
581
Steven Moreland67f67b42016-09-29 08:59:02 -0700582 if (returnsValue && elidedReturn == nullptr) {
583 generateCheckNonNull(out, "_hidl_cb");
584 }
585
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700586 generateCppInstrumentationCall(
587 out,
588 InstrumentationEvent::PASSTHROUGH_ENTRY,
589 method);
590
Yifan Hong7a118f52016-12-07 11:21:15 -0800591
592 for (const auto &arg : method->args()) {
593 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
594 out << "return ::android::hardware::Status::fromExceptionCode(\n";
595 out.indent(2, [&] {
596 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800597 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800598 });
599 });
600 }
601
602 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700603 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700604
605 if (method->isOneway()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800606 out << "addOnewayTask([this, &_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700607 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800608 out << ", "
609 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
610 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700611 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700612 out << "] {\n";
613 out.indent();
614 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700615 }
616
617 out << "mImpl->"
618 << method->name()
619 << "(";
620
621 bool first = true;
622 for (const auto &arg : method->args()) {
623 if (!first) {
624 out << ", ";
625 }
626 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800627 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700628 }
629 if (returnsValue && elidedReturn == nullptr) {
630 if (!method->args().empty()) {
631 out << ", ";
632 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800633 out << "[&](";
634 first = true;
635 for (const auto &arg : method->results()) {
636 if (!first) {
637 out << ", ";
638 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700639
Yifan Hong7a118f52016-12-07 11:21:15 -0800640 out << "const auto &_hidl_out_"
641 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800642
643 first = false;
644 }
645
646 out << ") {\n";
647 out.indent();
648 status_t status = generateCppInstrumentationCall(
649 out,
650 InstrumentationEvent::PASSTHROUGH_EXIT,
651 method);
652 if (status != OK) {
653 return status;
654 }
655
Yifan Hong7a118f52016-12-07 11:21:15 -0800656 for (const auto &arg : method->results()) {
657 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
658 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
659 out.indent(2, [&] {
660 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800661 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800662 });
663 out << "return;\n";
664 });
665 }
666
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800667 out << "_hidl_cb(";
668 first = true;
669 for (const auto &arg : method->results()) {
670 if (!first) {
671 out << ", ";
672 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800673 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800674 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
675 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800676 }
677 out << ");\n";
678 out.unindent();
679 out << "});\n\n";
680 } else {
681 out << ");\n\n";
682 if (elidedReturn != nullptr) {
683 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800684 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800685 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000686 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800687 }
688 status_t status = generateCppInstrumentationCall(
689 out,
690 InstrumentationEvent::PASSTHROUGH_EXIT,
691 method);
692 if (status != OK) {
693 return status;
694 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700695 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700696
697 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700698 out.unindent();
699 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700700 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700701
702 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700703
704 out.unindent();
705 out << "}\n";
706
707 return OK;
708}
709
Yifan Hong068c5522016-10-31 14:07:25 -0700710status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700711
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700712 const Interface *iface = mRootScope->getInterface();
713
Yifan Hong10fe0b52016-10-19 14:20:17 -0700714 const Interface *prevIterface = nullptr;
715 for (const auto &tuple : iface->allMethodsFromRoot()) {
716 const Method *method = tuple.method();
717 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700718
Yifan Hong10fe0b52016-10-19 14:20:17 -0700719 if(prevIterface != superInterface) {
720 if (prevIterface != nullptr) {
721 out << "\n";
722 }
723 out << "// Methods from "
724 << superInterface->fullName()
725 << " follow.\n";
726 prevIterface = superInterface;
727 }
Yifan Hong068c5522016-10-31 14:07:25 -0700728 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700729
Yifan Hong10fe0b52016-10-19 14:20:17 -0700730 if (err != OK) {
731 return err;
732 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700733 }
734
Yifan Hong10fe0b52016-10-19 14:20:17 -0700735 out << "\n";
736
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700737 return OK;
738}
739
Andreas Huberb82318c2016-08-02 14:45:54 -0700740status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700741 std::string ifaceName;
742 if (!AST::isInterface(&ifaceName)) {
743 // types.hal does not get a stub header.
744 return OK;
745 }
746
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700747 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800748 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700749
Andreas Huberb82318c2016-08-02 14:45:54 -0700750 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700751 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700752 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700753 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700754 path.append(".h");
755
Andreas Huberd2943e12016-08-05 11:59:31 -0700756 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700757 FILE *file = fopen(path.c_str(), "w");
758
759 if (file == NULL) {
760 return -errno;
761 }
762
763 Formatter out(file);
764
Steven Moreland40786312016-08-16 10:29:40 -0700765 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700766
767 out << "#ifndef " << guard << "\n";
768 out << "#define " << guard << "\n\n";
769
Yifan Hongeefe4f22017-01-04 15:32:42 -0800770 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700771 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700772
773 enterLeaveNamespace(out, true /* enter */);
774 out << "\n";
775
776 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800777 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100778 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800779 out << " : public ::android::hardware::BHwBinder";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100780 out << ", public ::android::hardware::HidlInstrumentor {\n";
781 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800782 out << " : public "
783 << gIBaseFqName.getInterfaceStubFqName().cppName()
784 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100785 }
Andreas Huber881227d2016-08-02 14:20:21 -0700786
787 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800788 out << "explicit "
789 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700790 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100791 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800792 out << "explicit "
793 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100794 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800795 << " const std::string& HidlInstrumentor_package,"
796 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700797 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700798 out << "::android::status_t onTransact(\n";
799 out.indent();
800 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700801 out << "uint32_t _hidl_code,\n";
802 out << "const ::android::hardware::Parcel &_hidl_data,\n";
803 out << "::android::hardware::Parcel *_hidl_reply,\n";
804 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700805 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700806 out.unindent();
807 out.unindent();
808
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100809 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
810 out.unindent();
811 out << "private:\n";
812 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800813
814 status_t err = generateMethods(out, [&](const Method *method, const Interface *iface) {
815 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
816 return OK;
817 }
818 const bool returnsValue = !method->results().empty();
819 const TypedVar *elidedReturn = method->canElideCallback();
820
821 if (elidedReturn == nullptr && returnsValue) {
822 out << "using " << method->name() << "_cb = "
823 << iface->fqName().cppName()
824 << "::" << method->name() << "_cb;\n";
825 }
826 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800827 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800828 return OK;
829 });
830 if (err != OK) {
831 return err;
832 }
833
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100834 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700835 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700836 out << "};\n\n";
837
838 enterLeaveNamespace(out, false /* enter */);
839
840 out << "\n#endif // " << guard << "\n";
841
842 return OK;
843}
844
Andreas Huberb82318c2016-08-02 14:45:54 -0700845status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700846 std::string ifaceName;
847 if (!AST::isInterface(&ifaceName)) {
848 // types.hal does not get a proxy header.
849 return OK;
850 }
851
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700852 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800853 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700854
Andreas Huberb82318c2016-08-02 14:45:54 -0700855 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700856 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700857 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800858 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700859 path.append(".h");
860
Andreas Huberd2943e12016-08-05 11:59:31 -0700861 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700862 FILE *file = fopen(path.c_str(), "w");
863
864 if (file == NULL) {
865 return -errno;
866 }
867
868 Formatter out(file);
869
Yifan Hongeefe4f22017-01-04 15:32:42 -0800870 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700871
872 out << "#ifndef " << guard << "\n";
873 out << "#define " << guard << "\n\n";
874
Martijn Coenen115d4282016-12-19 05:14:04 +0100875 out << "#include <hidl/HidlTransportSupport.h>\n\n";
876
Andreas Huber881227d2016-08-02 14:20:21 -0700877 std::vector<std::string> packageComponents;
878 getPackageAndVersionComponents(
879 &packageComponents, false /* cpp_compatible */);
880
Yifan Hongeefe4f22017-01-04 15:32:42 -0800881 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700882 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700883
884 enterLeaveNamespace(out, true /* enter */);
885 out << "\n";
886
887 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800888 << proxyName
889 << " : public ::android::hardware::BpInterface<"
890 << iface->localName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -0700891 << ">, public ::android::hardware::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700892
893 out.indent();
894
Yifan Hongeefe4f22017-01-04 15:32:42 -0800895 out << "explicit "
896 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700897 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700898 << "\n\n";
899
Yifan Hong10fe0b52016-10-19 14:20:17 -0700900 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700901
Yifan Hong068c5522016-10-31 14:07:25 -0700902 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
903 method->generateCppSignature(out);
904 out << " override;\n";
905 return OK;
906 });
Steven Moreland9c387612016-09-07 09:54:26 -0700907
908 if (err != OK) {
909 return err;
910 }
Andreas Huber881227d2016-08-02 14:20:21 -0700911
912 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100913 out << "private:\n";
914 out.indent();
915 out << "std::mutex _hidl_mMutex;\n"
916 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
917 << " _hidl_mDeathRecipients;\n";
918 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700919 out << "};\n\n";
920
921 enterLeaveNamespace(out, false /* enter */);
922
923 out << "\n#endif // " << guard << "\n";
924
925 return OK;
926}
927
Andreas Huberb82318c2016-08-02 14:45:54 -0700928status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700929
Andreas Huberb82318c2016-08-02 14:45:54 -0700930 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700931 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700932 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700933
934 std::string ifaceName;
935 std::string baseName;
936
Yifan Hongfe95aa22016-10-19 17:26:45 -0700937 const Interface *iface = nullptr;
938 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700939 if (!AST::isInterface(&ifaceName)) {
940 baseName = "types";
941 isInterface = false;
942 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700943 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700944 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700945 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700946 }
947
948 path.append(baseName);
949
950 if (baseName != "types") {
951 path.append("All");
952 }
953
954 path.append(".cpp");
955
Andreas Huberd2943e12016-08-05 11:59:31 -0700956 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700957 FILE *file = fopen(path.c_str(), "w");
958
959 if (file == NULL) {
960 return -errno;
961 }
962
963 Formatter out(file);
964
Steven Moreland623c0042017-01-13 14:42:29 -0800965 out << "#define LOG_TAG \""
966 << mPackage.string() << "::" << baseName
967 << "\"\n\n";
968
Steven Moreland05cd4232016-11-21 16:01:12 -0800969 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100970 out << "#include <cutils/trace.h>\n";
971 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700972 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700973 // This is a no-op for IServiceManager itself.
974 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
975
Steven Morelandbec74ed2017-01-25 17:42:35 -0800976 // TODO(b/34274385) remove this
977 out << "#include <hidl/LegacySupport.h>\n";
978
Yifan Hongeefe4f22017-01-04 15:32:42 -0800979 generateCppPackageInclude(out, mPackage, iface->getProxyName());
980 generateCppPackageInclude(out, mPackage, iface->getStubName());
981 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700982
983 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700984 generateCppPackageInclude(out,
985 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800986 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700987 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800988
989 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700990 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700991 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800992 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700993 }
994
995 out << "\n";
996
997 enterLeaveNamespace(out, true /* enter */);
998 out << "\n";
999
1000 status_t err = generateTypeSource(out, ifaceName);
1001
1002 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001003 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001004
1005 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -08001006 out << "const char* "
1007 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -07001008 << "::descriptor(\""
1009 << iface->fqName().string()
1010 << "\");\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +01001011 out << "__attribute__((constructor))";
1012 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001013 out.indent([&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001014 out << "::android::hardware::gBnConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001015 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001016 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001017 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001018 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001019 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001020 out << "return new "
1021 << iface->getStubName()
1022 << "(reinterpret_cast<"
1023 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001024 << " *>(iIntf));\n";
1025 });
Yifan Hongb04de382017-02-06 15:31:52 -08001026 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001027 });
Yifan Hongb04de382017-02-06 15:31:52 -08001028 out << "::android::hardware::gBsConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001029 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001030 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001031 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001032 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -08001033 << gIBaseFqName.cppName()
1034 << "> {\n";
1035 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001036 out << "return new "
1037 << iface->getPassthroughName()
1038 << "(reinterpret_cast<"
1039 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001040 << " *>(iIntf));\n";
1041 });
Yifan Hongb04de382017-02-06 15:31:52 -08001042 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001043 });
Yifan Hong158655a2016-11-08 12:34:07 -08001044 });
Martijn Coenen8adcb652017-02-03 17:37:36 +01001045 out << "};\n\n";
1046 out << "__attribute__((destructor))";
1047 out << "static void static_destructor() {\n";
1048 out.indent([&] {
1049 out << "::android::hardware::gBnConstructorMap.erase("
1050 << iface->localName()
1051 << "::descriptor);\n";
1052 out << "::android::hardware::gBsConstructorMap.erase("
1053 << iface->localName()
1054 << "::descriptor);\n";
1055 });
1056 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001057
Yifan Hongfe95aa22016-10-19 17:26:45 -07001058 err = generateInterfaceSource(out);
1059 }
1060
1061 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001062 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001063 }
1064
1065 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001066 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001067 }
1068
Steven Moreland40786312016-08-16 10:29:40 -07001069 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001070 err = generatePassthroughSource(out);
1071 }
1072
1073 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001074 const Interface *iface = mRootScope->getInterface();
1075
Yifan Hongc8934042016-11-17 17:10:52 -08001076 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001077 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001078 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001079 std::string package = iface->fqName().package()
1080 + iface->fqName().atVersion();
1081
Yifan Hongeefe4f22017-01-04 15:32:42 -08001082 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001083 }
Steven Moreland40786312016-08-16 10:29:40 -07001084 }
1085
Andreas Huber881227d2016-08-02 14:20:21 -07001086 enterLeaveNamespace(out, false /* enter */);
1087
1088 return err;
1089}
1090
Steven Moreland67f67b42016-09-29 08:59:02 -07001091// static
1092void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001093 out.sIf(nonNull + " == nullptr", [&] {
1094 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1095 out.indent(2, [&] {
1096 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1097 });
1098 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001099}
1100
Andreas Huber881227d2016-08-02 14:20:21 -07001101status_t AST::generateTypeSource(
1102 Formatter &out, const std::string &ifaceName) const {
1103 return mRootScope->emitTypeDefinitions(out, ifaceName);
1104}
1105
Andreas Hubere7ff2282016-08-16 13:50:03 -07001106void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001107 Formatter &out,
1108 const std::vector<TypedVar *> &args,
1109 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001110 if (args.empty()) {
1111 return;
1112 }
1113
1114 for (const auto &arg : args) {
1115 const Type &type = arg->type();
1116
Yifan Hong3b320f82016-11-01 15:15:54 -07001117 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001118 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001119 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001120 << ";\n";
1121 }
1122
1123 out << "\n";
1124}
1125
Andreas Huber881227d2016-08-02 14:20:21 -07001126void AST::emitCppReaderWriter(
1127 Formatter &out,
1128 const std::string &parcelObj,
1129 bool parcelObjIsPointer,
1130 const TypedVar *arg,
1131 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001132 Type::ErrorMode mode,
1133 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001134 const Type &type = arg->type();
1135
Andreas Huber881227d2016-08-02 14:20:21 -07001136 type.emitReaderWriter(
1137 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001138 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001139 parcelObj,
1140 parcelObjIsPointer,
1141 isReader,
1142 mode);
1143}
1144
Yifan Hongbf459bc2016-08-23 16:50:37 -07001145void AST::emitCppResolveReferences(
1146 Formatter &out,
1147 const std::string &parcelObj,
1148 bool parcelObjIsPointer,
1149 const TypedVar *arg,
1150 bool isReader,
1151 Type::ErrorMode mode,
1152 bool addPrefixToName) const {
1153 const Type &type = arg->type();
1154 if(type.needsResolveReferences()) {
1155 type.emitResolveReferences(
1156 out,
1157 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1158 isReader, // nameIsPointer
1159 parcelObj,
1160 parcelObjIsPointer,
1161 isReader,
1162 mode);
1163 }
1164}
1165
Yifan Hong068c5522016-10-31 14:07:25 -07001166status_t AST::generateProxyMethodSource(Formatter &out,
1167 const std::string &klassName,
1168 const Method *method,
1169 const Interface *superInterface) const {
1170
1171 method->generateCppSignature(out,
1172 klassName,
1173 true /* specify namespaces */);
1174
1175 const bool returnsValue = !method->results().empty();
1176 const TypedVar *elidedReturn = method->canElideCallback();
1177
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001178 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001179
1180 out.indent();
1181
Martijn Coenen115d4282016-12-19 05:14:04 +01001182 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1183 method->cppImpl(IMPL_PROXY, out);
1184 out.unindent();
1185 out << "}\n\n";
1186 return OK;
1187 }
1188
Yifan Hong068c5522016-10-31 14:07:25 -07001189 if (returnsValue && elidedReturn == nullptr) {
1190 generateCheckNonNull(out, "_hidl_cb");
1191 }
1192
1193 status_t status = generateCppInstrumentationCall(
1194 out,
1195 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001196 method);
1197 if (status != OK) {
1198 return status;
1199 }
1200
1201 out << "::android::hardware::Parcel _hidl_data;\n";
1202 out << "::android::hardware::Parcel _hidl_reply;\n";
1203 out << "::android::status_t _hidl_err;\n";
1204 out << "::android::hardware::Status _hidl_status;\n\n";
1205
1206 declareCppReaderLocals(
1207 out, method->results(), true /* forResults */);
1208
1209 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001210 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001211 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001212 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1213
Martijn Coenenfff73352017-01-04 16:36:31 +01001214 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001215 // First DFS: write all buffers and resolve pointers for parent
1216 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001217 if (arg->type().isInterface()) {
1218 hasInterfaceArgument = true;
1219 }
Yifan Hong068c5522016-10-31 14:07:25 -07001220 emitCppReaderWriter(
1221 out,
1222 "_hidl_data",
1223 false /* parcelObjIsPointer */,
1224 arg,
1225 false /* reader */,
1226 Type::ErrorMode_Goto,
1227 false /* addPrefixToName */);
1228 }
1229
1230 // Second DFS: resolve references.
1231 for (const auto &arg : method->args()) {
1232 emitCppResolveReferences(
1233 out,
1234 "_hidl_data",
1235 false /* parcelObjIsPointer */,
1236 arg,
1237 false /* reader */,
1238 Type::ErrorMode_Goto,
1239 false /* addPrefixToName */);
1240 }
1241
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001242 if (hasInterfaceArgument) {
1243 // Start binder threadpool to handle incoming transactions
1244 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1245 }
Yifan Hong068c5522016-10-31 14:07:25 -07001246 out << "_hidl_err = remote()->transact("
1247 << method->getSerialId()
1248 << " /* "
1249 << method->name()
1250 << " */, _hidl_data, &_hidl_reply";
1251
1252 if (method->isOneway()) {
1253 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1254 }
1255 out << ");\n";
1256
1257 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1258
1259 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001260 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001261 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1262 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1263
1264
1265 // First DFS: write all buffers and resolve pointers for parent
1266 for (const auto &arg : method->results()) {
1267 emitCppReaderWriter(
1268 out,
1269 "_hidl_reply",
1270 false /* parcelObjIsPointer */,
1271 arg,
1272 true /* reader */,
1273 Type::ErrorMode_Goto,
1274 true /* addPrefixToName */);
1275 }
1276
1277 // Second DFS: resolve references.
1278 for (const auto &arg : method->results()) {
1279 emitCppResolveReferences(
1280 out,
1281 "_hidl_reply",
1282 false /* parcelObjIsPointer */,
1283 arg,
1284 true /* reader */,
1285 Type::ErrorMode_Goto,
1286 true /* addPrefixToName */);
1287 }
1288
1289 if (returnsValue && elidedReturn == nullptr) {
1290 out << "_hidl_cb(";
1291
1292 bool first = true;
1293 for (const auto &arg : method->results()) {
1294 if (!first) {
1295 out << ", ";
1296 }
1297
1298 if (arg->type().resultNeedsDeref()) {
1299 out << "*";
1300 }
1301 out << "_hidl_out_" << arg->name();
1302
1303 first = false;
1304 }
1305
1306 out << ");\n\n";
1307 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001308 }
1309 status = generateCppInstrumentationCall(
1310 out,
1311 InstrumentationEvent::CLIENT_API_EXIT,
1312 method);
1313 if (status != OK) {
1314 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001315 }
1316
1317 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001318 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1319 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001320 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001321 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1322 } else {
1323 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1324 out << "return ::android::hardware::Return<void>();\n\n";
1325 }
1326
1327 out.unindent();
1328 out << "_hidl_error:\n";
1329 out.indent();
1330 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1331 out << "return ::android::hardware::Return<";
1332 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001333 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001334 } else {
1335 out << "void";
1336 }
1337 out << ">(_hidl_status);\n";
1338
1339 out.unindent();
1340 out << "}\n\n";
1341 return OK;
1342}
1343
Andreas Huber881227d2016-08-02 14:20:21 -07001344status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001345 Formatter &out, const FQName &fqName) const {
1346 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001347
1348 out << klassName
1349 << "::"
1350 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001351 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001352
1353 out.indent();
1354 out.indent();
1355
1356 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001357 << "<"
1358 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001359 << ">(_hidl_impl),\n"
Steven Moreland19d5c172016-10-20 19:20:25 -07001360 << " ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001361 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001362 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001363 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001364 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001365
Andreas Huber881227d2016-08-02 14:20:21 -07001366 out.unindent();
1367 out.unindent();
1368 out << "}\n\n";
1369
Yifan Hong068c5522016-10-31 14:07:25 -07001370 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1371 return generateProxyMethodSource(out, klassName, method, superInterface);
1372 });
Andreas Huber881227d2016-08-02 14:20:21 -07001373
Yifan Hong068c5522016-10-31 14:07:25 -07001374 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001375}
1376
1377status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001378 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001379 const Interface *iface) const {
1380 const std::string interfaceName = iface->localName();
1381 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001382
Steven Moreland40786312016-08-16 10:29:40 -07001383 out << klassName
1384 << "::"
1385 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001386 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001387
1388 out.indent();
1389 out.indent();
1390
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001391 if (iface->isIBase()) {
1392 out << ": ::android::hardware::HidlInstrumentor(\"";
1393 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001394 out << ": "
1395 << gIBaseFqName.getInterfaceStubFqName().cppName()
1396 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001397 }
1398
1399 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001400 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001401 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001402 << "\") { \n";
1403 out.indent();
1404 out << "_hidl_mImpl = _hidl_impl;\n";
1405 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001406
1407 out.unindent();
1408 out.unindent();
1409 out << "}\n\n";
1410
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001411 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001412 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001413 // class properly.
1414 out << klassName
1415 << "::"
1416 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001417 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1418 << " const std::string &HidlInstrumentor_package,"
1419 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001420
1421 out.indent();
1422 out.indent();
1423
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001424 out << ": ::android::hardware::HidlInstrumentor("
1425 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001426 out.indent();
1427 out << "_hidl_mImpl = _hidl_impl;\n";
1428 out.unindent();
1429
1430 out.unindent();
1431 out.unindent();
1432 out << "}\n\n";
1433 }
1434
Yifan Hongbcffce22017-02-01 15:52:06 -08001435 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1436 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1437 return OK;
1438 }
1439 method->generateCppSignature(out, iface->getStubName());
1440 out << " ";
1441 out.block([&] {
1442 method->cppImpl(IMPL_STUB_IMPL, out);
1443 }).endl();
1444 return OK;
1445 });
Steven Moreland60818632017-02-04 00:33:42 -08001446 if (err != OK) {
1447 return err;
1448 }
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001449
Andreas Huber881227d2016-08-02 14:20:21 -07001450 out << "::android::status_t " << klassName << "::onTransact(\n";
1451
1452 out.indent();
1453 out.indent();
1454
Iliyan Malchev549e2592016-08-10 08:59:12 -07001455 out << "uint32_t _hidl_code,\n"
1456 << "const ::android::hardware::Parcel &_hidl_data,\n"
1457 << "::android::hardware::Parcel *_hidl_reply,\n"
1458 << "uint32_t _hidl_flags,\n"
1459 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001460
1461 out.unindent();
1462
Iliyan Malchev549e2592016-08-10 08:59:12 -07001463 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001464 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001465 out.indent();
1466
Yifan Hong10fe0b52016-10-19 14:20:17 -07001467 for (const auto &tuple : iface->allMethodsFromRoot()) {
1468 const Method *method = tuple.method();
1469 const Interface *superInterface = tuple.interface();
1470 out << "case "
1471 << method->getSerialId()
1472 << " /* "
1473 << method->name()
1474 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001475
Yifan Hong10fe0b52016-10-19 14:20:17 -07001476 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001477
Yifan Hong10fe0b52016-10-19 14:20:17 -07001478 status_t err =
1479 generateStubSourceForMethod(out, superInterface, method);
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001480
Yifan Hong10fe0b52016-10-19 14:20:17 -07001481 if (err != OK) {
1482 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001483 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001484
1485 out.unindent();
1486 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001487 }
1488
1489 out << "default:\n{\n";
1490 out.indent();
1491
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001492 out << "return onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001493
1494 out.indent();
1495 out.indent();
1496
Iliyan Malchev549e2592016-08-10 08:59:12 -07001497 out << "_hidl_code, _hidl_data, _hidl_reply, "
1498 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001499
1500 out.unindent();
1501 out.unindent();
1502
1503 out.unindent();
1504 out << "}\n";
1505
1506 out.unindent();
1507 out << "}\n\n";
1508
Yifan Honga018ed52016-12-13 16:35:08 -08001509 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1510 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1511 out.indent(2, [&] {
1512 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1513 out << "_hidl_reply);\n";
1514 });
1515 });
Andreas Huber881227d2016-08-02 14:20:21 -07001516
Iliyan Malchev549e2592016-08-10 08:59:12 -07001517 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001518
1519 out.unindent();
1520 out << "}\n\n";
1521
1522 return OK;
1523}
1524
1525status_t AST::generateStubSourceForMethod(
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001526 Formatter &out, const Interface *iface, const Method *method) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001527 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1528 method->cppImpl(IMPL_STUB, out);
1529 out << "break;\n";
1530 return OK;
1531 }
1532
Yifan Hongeefe4f22017-01-04 15:32:42 -08001533 out << "if (!_hidl_data.enforceInterface("
1534 << iface->fullName()
1535 << "::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001536
Andreas Huber881227d2016-08-02 14:20:21 -07001537 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001538 out << "_hidl_err = ::android::BAD_TYPE;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001539 out << "break;\n";
1540 out.unindent();
1541 out << "}\n\n";
1542
Andreas Huber5e44a292016-09-27 14:52:39 -07001543 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001544
Yifan Hongbf459bc2016-08-23 16:50:37 -07001545 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001546 for (const auto &arg : method->args()) {
1547 emitCppReaderWriter(
1548 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001549 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001550 false /* parcelObjIsPointer */,
1551 arg,
1552 true /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001553 Type::ErrorMode_Break,
1554 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001555 }
1556
Yifan Hongbf459bc2016-08-23 16:50:37 -07001557 // Second DFS: resolve references
1558 for (const auto &arg : method->args()) {
1559 emitCppResolveReferences(
1560 out,
1561 "_hidl_data",
1562 false /* parcelObjIsPointer */,
1563 arg,
1564 true /* reader */,
1565 Type::ErrorMode_Break,
1566 false /* addPrefixToName */);
1567 }
1568
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001569 status_t status = generateCppInstrumentationCall(
1570 out,
1571 InstrumentationEvent::SERVER_API_ENTRY,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001572 method);
1573 if (status != OK) {
1574 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001575 }
1576
Andreas Huber881227d2016-08-02 14:20:21 -07001577 const bool returnsValue = !method->results().empty();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001578 const TypedVar *elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -08001579 const std::string callee =
1580 (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL))
1581 ? "this" : "_hidl_mImpl";
Andreas Huber881227d2016-08-02 14:20:21 -07001582
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001583 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001584 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001585 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001586 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001587 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001588 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001589 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001590
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001591 bool first = true;
1592 for (const auto &arg : method->args()) {
Andreas Huber881227d2016-08-02 14:20:21 -07001593 if (!first) {
1594 out << ", ";
1595 }
1596
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001597 if (arg->type().resultNeedsDeref()) {
1598 out << "*";
1599 }
1600
1601 out << arg->name();
Andreas Huber881227d2016-08-02 14:20:21 -07001602
1603 first = false;
1604 }
1605
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001606 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001607 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1608 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001609
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001610 elidedReturn->type().emitReaderWriter(
1611 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001612 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001613 "_hidl_reply",
1614 true, /* parcelObjIsPointer */
1615 false, /* isReader */
1616 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001617
Yifan Hongbf459bc2016-08-23 16:50:37 -07001618 emitCppResolveReferences(
1619 out,
1620 "_hidl_reply",
1621 true /* parcelObjIsPointer */,
1622 elidedReturn,
1623 false /* reader */,
1624 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001625 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001626
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001627 status_t status = generateCppInstrumentationCall(
1628 out,
1629 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001630 method);
1631 if (status != OK) {
1632 return status;
1633 }
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001634
Iliyan Malchev549e2592016-08-10 08:59:12 -07001635 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001636 } else {
1637 if (returnsValue) {
1638 out << "bool _hidl_callbackCalled = false;\n\n";
1639 }
Andreas Huber881227d2016-08-02 14:20:21 -07001640
Yifan Hongcd2ae452017-01-31 14:33:40 -08001641 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001642
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001643 bool first = true;
1644 for (const auto &arg : method->args()) {
1645 if (!first) {
1646 out << ", ";
1647 }
Andreas Huber881227d2016-08-02 14:20:21 -07001648
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001649 if (arg->type().resultNeedsDeref()) {
1650 out << "*";
1651 }
1652
1653 out << arg->name();
1654
1655 first = false;
1656 }
1657
1658 if (returnsValue) {
1659 if (!first) {
1660 out << ", ";
1661 }
1662
1663 out << "[&](";
1664
1665 first = true;
1666 for (const auto &arg : method->results()) {
1667 if (!first) {
1668 out << ", ";
1669 }
1670
Yifan Honga47eef32016-12-12 10:38:54 -08001671 out << "const auto &_hidl_out_" << arg->name();
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001672
1673 first = false;
1674 }
1675
1676 out << ") {\n";
1677 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001678 out << "if (_hidl_callbackCalled) {\n";
1679 out.indent();
1680 out << "LOG_ALWAYS_FATAL(\""
1681 << method->name()
1682 << ": _hidl_cb called a second time, but must be called once.\");\n";
1683 out.unindent();
1684 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001685 out << "_hidl_callbackCalled = true;\n\n";
1686
Yifan Hong859e53f2016-11-14 19:08:24 -08001687 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1688 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001689
Yifan Hongbf459bc2016-08-23 16:50:37 -07001690 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001691 for (const auto &arg : method->results()) {
1692 emitCppReaderWriter(
1693 out,
1694 "_hidl_reply",
1695 true /* parcelObjIsPointer */,
1696 arg,
1697 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001698 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001699 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001700 }
1701
Yifan Hongbf459bc2016-08-23 16:50:37 -07001702 // Second DFS: resolve references
1703 for (const auto &arg : method->results()) {
1704 emitCppResolveReferences(
1705 out,
1706 "_hidl_reply",
1707 true /* parcelObjIsPointer */,
1708 arg,
1709 false /* reader */,
1710 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001711 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001712 }
1713
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001714 status_t status = generateCppInstrumentationCall(
1715 out,
1716 InstrumentationEvent::SERVER_API_EXIT,
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001717 method);
1718 if (status != OK) {
1719 return status;
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001720 }
1721
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001722 out << "_hidl_cb(*_hidl_reply);\n";
1723
1724 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001725 out << "});\n\n";
1726 } else {
1727 out << ");\n\n";
1728 status_t status = generateCppInstrumentationCall(
1729 out,
1730 InstrumentationEvent::SERVER_API_EXIT,
1731 method);
1732 if (status != OK) {
1733 return status;
1734 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001735 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001736
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001737 if (returnsValue) {
1738 out << "if (!_hidl_callbackCalled) {\n";
1739 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001740 out << "LOG_ALWAYS_FATAL(\""
1741 << method->name()
1742 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001743 out.unindent();
1744 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001745 } else {
1746 out << "::android::hardware::writeToParcel("
1747 << "::android::hardware::Status::ok(), "
1748 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001749 }
Andreas Huber881227d2016-08-02 14:20:21 -07001750 }
1751
1752 out << "break;\n";
1753
1754 return OK;
1755}
1756
Steven Moreland69e7c702016-09-09 11:16:32 -07001757status_t AST::generatePassthroughHeader(const std::string &outputPath) const {
1758 std::string ifaceName;
1759 if (!AST::isInterface(&ifaceName)) {
1760 // types.hal does not get a stub header.
1761 return OK;
1762 }
1763
1764 const Interface *iface = mRootScope->getInterface();
1765
Yifan Hongeefe4f22017-01-04 15:32:42 -08001766 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001767
1768 bool supportOneway = iface->hasOnewayMethods();
1769
1770 std::string path = outputPath;
1771 path.append(mCoordinator->convertPackageRootToPath(mPackage));
1772 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
1773 path.append(klassName);
1774 path.append(".h");
1775
1776 CHECK(Coordinator::MakeParentHierarchy(path));
1777 FILE *file = fopen(path.c_str(), "w");
1778
1779 if (file == NULL) {
1780 return -errno;
1781 }
1782
1783 Formatter out(file);
1784
1785 const std::string guard = makeHeaderGuard(klassName);
1786
1787 out << "#ifndef " << guard << "\n";
1788 out << "#define " << guard << "\n\n";
1789
1790 std::vector<std::string> packageComponents;
1791 getPackageAndVersionComponents(
1792 &packageComponents, false /* cpp_compatible */);
1793
Yifan Hongb0949432016-12-15 15:32:24 -08001794 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001795 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001796
1797 generateCppPackageInclude(out, mPackage, ifaceName);
1798 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001799
Yifan Hong7a118f52016-12-07 11:21:15 -08001800 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001801 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001802 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001803 }
1804
1805 enterLeaveNamespace(out, true /* enter */);
1806 out << "\n";
1807
1808 out << "struct "
1809 << klassName
1810 << " : " << ifaceName
Steven Moreland19d5c172016-10-20 19:20:25 -07001811 << ", ::android::hardware::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001812
1813 out.indent();
1814 out << "explicit "
1815 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001816 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001817 << ifaceName
1818 << "> impl);\n";
1819
Yifan Hong068c5522016-10-31 14:07:25 -07001820 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1821 return generatePassthroughMethod(out, method);
1822 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001823
1824 if (err != OK) {
1825 return err;
1826 }
1827
1828 out.unindent();
1829 out << "private:\n";
1830 out.indent();
Steven Morelandc46e9842016-11-02 13:21:26 -07001831 out << "const ::android::sp<" << ifaceName << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001832
1833 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001834 out << "::android::hardware::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001835
1836 out << "\n";
1837
1838 out << "::android::hardware::Return<void> addOnewayTask("
1839 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001840 }
1841
1842 out.unindent();
1843
1844 out << "};\n\n";
1845
1846 enterLeaveNamespace(out, false /* enter */);
1847
1848 out << "\n#endif // " << guard << "\n";
1849
1850 return OK;
1851}
1852
Yifan Hongfe95aa22016-10-19 17:26:45 -07001853status_t AST::generateInterfaceSource(Formatter &out) const {
1854 const Interface *iface = mRootScope->getInterface();
1855
Yifan Hong2d7126b2016-10-20 15:12:57 -07001856 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001857 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001858
Yifan Hong3d746092016-12-07 14:26:33 -08001859 for (const Interface *superType : iface->typeChain()) {
1860 out << "// static \n"
1861 << childTypeResult
Yifan Hongeefe4f22017-01-04 15:32:42 -08001862 << " "
1863 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001864 << "::castFrom("
1865 << superType->getCppArgumentType()
1866 << " parent) {\n";
1867 out.indent();
1868 if (iface == superType) {
1869 out << "return parent;\n";
1870 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -07001871 out << "return ::android::hardware::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001872 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001873 << superType->fqName().cppName() << ", "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001874 << iface->getProxyName() << ", "
Yifan Hong51a65092017-01-04 15:41:44 -08001875 << superType->getProxyFqName().cppName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001876 << ">(\n";
1877 out.indent();
1878 out.indent();
1879 out << "parent, \""
1880 << iface->fqName().string()
1881 << "\");\n";
1882 out.unindent();
1883 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001884 }
Yifan Hong3d746092016-12-07 14:26:33 -08001885 out.unindent();
1886 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001887 }
1888
1889 return OK;
1890}
1891
Steven Moreland69e7c702016-09-09 11:16:32 -07001892status_t AST::generatePassthroughSource(Formatter &out) const {
1893 const Interface *iface = mRootScope->getInterface();
1894
Yifan Hongeefe4f22017-01-04 15:32:42 -08001895 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001896
1897 out << klassName
1898 << "::"
1899 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001900 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001901 << iface->fullName()
Steven Moreland19d5c172016-10-20 19:20:25 -07001902 << "> impl) : ::android::hardware::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001903 << mPackage.string()
1904 << "\", \""
1905 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001906 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001907 if (iface->hasOnewayMethods()) {
1908 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001909 out.indent([&] {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001910 out << "mOnewayQueue.setLimit(3000 /* similar limit to binderized */);\n";
1911 });
1912 }
1913 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001914
1915 if (iface->hasOnewayMethods()) {
1916 out << "::android::hardware::Return<void> "
1917 << klassName
1918 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1919 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001920 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001921 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001922 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1923 out.indent();
1924 out.indent();
1925 out << "::android::hardware::Status::EX_TRANSACTION_FAILED);\n";
1926 out.unindent();
1927 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001928 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001929 out << "}\n";
1930
Steven Morelandd366c262016-10-11 15:29:10 -07001931 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001932
1933 out.unindent();
1934 out << "}\n\n";
1935
1936
1937 }
1938
1939 return OK;
1940}
1941
Martijn Coenen7b295242016-11-04 16:52:56 +01001942status_t AST::generateCppAtraceCall(Formatter &out,
1943 InstrumentationEvent event,
1944 const Method *method) const {
1945 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001946 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001947 switch (event) {
1948 case SERVER_API_ENTRY:
1949 {
1950 out << "atrace_begin(ATRACE_TAG_HAL, \""
1951 << baseString + "::server\");\n";
1952 break;
1953 }
1954 case CLIENT_API_ENTRY:
1955 {
1956 out << "atrace_begin(ATRACE_TAG_HAL, \""
1957 << baseString + "::client\");\n";
1958 break;
1959 }
1960 case PASSTHROUGH_ENTRY:
1961 {
1962 out << "atrace_begin(ATRACE_TAG_HAL, \""
1963 << baseString + "::passthrough\");\n";
1964 break;
1965 }
1966 case SERVER_API_EXIT:
1967 case CLIENT_API_EXIT:
1968 case PASSTHROUGH_EXIT:
1969 {
1970 out << "atrace_end(ATRACE_TAG_HAL);\n";
1971 break;
1972 }
1973 default:
1974 {
1975 LOG(ERROR) << "Unsupported instrumentation event: " << event;
1976 return UNKNOWN_ERROR;
1977 }
1978 }
1979
1980 return OK;
1981}
1982
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001983status_t AST::generateCppInstrumentationCall(
1984 Formatter &out,
1985 InstrumentationEvent event,
Steven Moreland031ccf12016-10-31 15:54:38 -07001986 const Method *method) const {
Martijn Coenen7b295242016-11-04 16:52:56 +01001987 status_t err = generateCppAtraceCall(out, event, method);
1988 if (err != OK) {
1989 return err;
1990 }
1991
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001992 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1993 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001994 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001995 std::string event_str = "";
1996 switch (event) {
1997 case SERVER_API_ENTRY:
1998 {
1999 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
2000 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002001 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002002 << (arg->type().resultNeedsDeref() ? "" : "&")
2003 << arg->name()
2004 << ");\n";
2005 }
2006 break;
2007 }
2008 case SERVER_API_EXIT:
2009 {
2010 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07002011 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002012 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07002013 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002014 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002015 }
2016 break;
2017 }
2018 case CLIENT_API_ENTRY:
2019 {
2020 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
2021 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002022 out << "_hidl_args.push_back((void *)&"
2023 << arg->name()
2024 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002025 }
2026 break;
2027 }
2028 case CLIENT_API_EXIT:
2029 {
2030 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2031 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002032 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002033 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002034 << "_hidl_out_"
2035 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002036 << ");\n";
2037 }
2038 break;
2039 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002040 case PASSTHROUGH_ENTRY:
2041 {
2042 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2043 for (const auto &arg : method->args()) {
2044 out << "_hidl_args.push_back((void *)&"
2045 << arg->name()
2046 << ");\n";
2047 }
2048 break;
2049 }
2050 case PASSTHROUGH_EXIT:
2051 {
2052 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002053 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002054 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002055 << arg->name()
2056 << ");\n";
2057 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002058 break;
2059 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002060 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002061 {
Steven Moreland031ccf12016-10-31 15:54:38 -07002062 LOG(ERROR) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002063 return UNKNOWN_ERROR;
2064 }
2065 }
2066
Steven Moreland031ccf12016-10-31 15:54:38 -07002067 const Interface *iface = mRootScope->getInterface();
2068
Steven Moreland1ab31442016-11-03 18:37:51 -07002069 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002070 out.indent();
2071 out << "callback("
2072 << event_str
2073 << ", \""
2074 << mPackage.package()
2075 << "\", \""
Yifan Hong90ea87f2016-11-01 14:25:47 -07002076 << mPackage.version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002077 << "\", \""
2078 << iface->localName()
2079 << "\", \""
2080 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002081 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002082 out.unindent();
2083 out << "}\n";
2084 out.unindent();
2085 out << "}\n\n";
2086
2087 return OK;
2088}
2089
Andreas Huber881227d2016-08-02 14:20:21 -07002090} // namespace android