blob: a088960f402041643c2315a91d89d672998eeb9f [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 "transport == ::android::vintf::Transport::EMPTY)", [&] {
169 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800170 out.indent(2, [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000171 out << "= ::android::hardware::defaultServiceManager();\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800172 });
Steven Morelandf10af872017-01-25 16:01:56 +0000173 out.sIf("sm != nullptr", [&] {
Steven Morelandbec74ed2017-01-25 17:42:35 -0800174 // TODO(b/34274385) remove sysprop check
Steven Moreland15835172017-01-30 16:21:42 -0800175 out.sIf("transport == ::android::vintf::Transport::HWBINDER ||"
176 "(transport == ::android::vintf::Transport::TOGGLED &&"
177 " ::android::hardware::details::blockingHalBinderizationEnabled())", [&]() {
Steven Moreland6d7b91c2017-01-24 18:58:07 -0800178 out << "::android::hardware::details::waitForHwService("
179 << interfaceName << "::descriptor" << ", serviceName);\n";
180 }).endl();
Steven Morelandf10af872017-01-25 16:01:56 +0000181 out << "::android::hardware::Return<::android::sp<" << gIBaseFqName.cppName() << ">> ret = \n";
182 out.indent(2, [&] {
183 out << "sm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
184 });
185 out.sIf("ret.isOk()", [&] {
186 out << "iface = " << interfaceName << "::castFrom(ret);\n";
187 out.sIf("iface != nullptr", [&] {
188 out << "return iface;\n";
189 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800190 }).endl();
191 }).endl();
192 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800193
Steven Morelandf10af872017-01-25 16:01:56 +0000194 out.sIf("getStub || "
195 "transport == ::android::vintf::Transport::PASSTHROUGH || "
Steven Moreland15835172017-01-30 16:21:42 -0800196 "(transport == ::android::vintf::Transport::TOGGLED &&"
Steven Morelandbec74ed2017-01-25 17:42:35 -0800197 " !::android::hardware::details::blockingHalBinderizationEnabled()) ||"
Steven Morelandf10af872017-01-25 16:01:56 +0000198 "transport == ::android::vintf::Transport::EMPTY", [&] {
199 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> pm\n";
Steven Morelande3fa5da2017-01-25 07:07:53 +0000200 out.indent(2, [&] {
Steven Morelandf10af872017-01-25 16:01:56 +0000201 out << "= ::android::hardware::getPassthroughServiceManager();\n";
Steven Morelande3fa5da2017-01-25 07:07:53 +0000202 });
Steven Morelandf10af872017-01-25 16:01:56 +0000203
204 out.sIf("pm != nullptr", [&] () {
205 out << "::android::hardware::Return<::android::sp<" << gIBaseFqName.cppName() << ">> ret = \n";
206 out.indent(2, [&] {
207 out << "pm->get(" << interfaceName << "::descriptor" << ", serviceName);\n";
Steven Moreland2c2dea82017-01-18 17:24:17 -0800208 });
Steven Morelandf10af872017-01-25 16:01:56 +0000209 out.sIf("ret.isOk()", [&] {
210 out << "::android::sp<" << gIBaseFqName.cppName()
211 << "> baseInterface = ret;\n";
212 out.sIf("baseInterface != nullptr", [&]() {
213 out << "iface = new " << fqName.getInterfacePassthroughName()
214 << "(" << interfaceName << "::castFrom(baseInterface));\n";
215 });
216 }).endl();
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800217 }).endl();
218 }).endl();
Steven Moreland2c2dea82017-01-18 17:24:17 -0800219
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800220 out << "return iface;\n";
221 }).endl().endl();
222
Yifan Hongeefe4f22017-01-04 15:32:42 -0800223 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800224 << "const std::string &serviceName) ";
225 out.block([&] {
226 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
227 out.indent(2, [&] {
228 out << "= ::android::hardware::defaultServiceManager();\n";
229 });
230 out.sIf("sm == nullptr", [&] {
231 out << "return ::android::INVALID_OPERATION;\n";
232 }).endl();
233 out << "bool success = false;\n"
234 << "::android::hardware::Return<void> ret =\n";
235 out.indent(2, [&] {
236 out << "this->interfaceChain("
237 << "[&success, &sm, &serviceName, this](const auto &chain) ";
238 out.block([&] {
239 out << "::android::hardware::Return<bool> addRet = "
240 << "sm->add(chain, serviceName.c_str(), this);\n";
241 out << "success = addRet.isOk() && addRet;\n";
242 });
243 out << ");\n";
Steven Morelandcd00b9b2016-12-29 10:34:03 -0800244 out << "success = success && ret.isOk();\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800245 });
246 out << "return success ? ::android::OK : ::android::UNKNOWN_ERROR;\n";
247 }).endl().endl();
248
Yifan Hongeefe4f22017-01-04 15:32:42 -0800249 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800250 out.indent(2, [&] {
251 out << "const std::string &serviceName,\n"
252 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
253 << "&notification) ";
254 });
255 out.block([&] {
256 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
257 out.indent(2, [&] {
258 out << "= ::android::hardware::defaultServiceManager();\n";
259 });
260 out.sIf("sm == nullptr", [&] {
261 out << "return false;\n";
262 }).endl();
263 out << "::android::hardware::Return<bool> success =\n";
264 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800265 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800266 out.indent(2, [&] {
267 out << "serviceName, notification);\n";
268 });
269 });
270 out << "return success.isOk() && success;\n";
271 }).endl().endl();
272}
273
Andreas Huberb82318c2016-08-02 14:45:54 -0700274status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700275
Andreas Huberb82318c2016-08-02 14:45:54 -0700276 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700277 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700278 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700279
280 std::string ifaceName;
281 bool isInterface = true;
282 if (!AST::isInterface(&ifaceName)) {
283 ifaceName = "types";
284 isInterface = false;
285 }
286 path.append(ifaceName);
287 path.append(".h");
288
Andreas Huberd2943e12016-08-05 11:59:31 -0700289 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700290 FILE *file = fopen(path.c_str(), "w");
291
292 if (file == NULL) {
293 return -errno;
294 }
295
296 Formatter out(file);
297
298 const std::string guard = makeHeaderGuard(ifaceName);
299
300 out << "#ifndef " << guard << "\n";
301 out << "#define " << guard << "\n\n";
302
Andreas Huber737080b2016-08-02 15:38:04 -0700303 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700304 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700305 }
306
307 if (!mImportedNames.empty()) {
308 out << "\n";
309 }
310
Steven Moreland0693f312016-11-09 15:06:14 -0800311 if (isInterface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800312 if (isIBase()) {
313 out << "// skipped #include IServiceNotification.h\n\n";
314 } else {
315 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
316 }
Steven Moreland0693f312016-11-09 15:06:14 -0800317 }
318
Yifan Hongc8934042016-11-17 17:10:52 -0800319 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700320 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700321
322 if (isInterface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200323 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700324 }
325
Martijn Coenenaf712c02016-11-16 15:26:27 +0100326 out << "#include <utils/NativeHandle.h>\n";
327 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700328
329 enterLeaveNamespace(out, true /* enter */);
330 out << "\n";
331
332 if (isInterface) {
333 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700334 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700335
336 const Interface *iface = mRootScope->getInterface();
337 const Interface *superType = iface->superType();
338
Steven Moreland40786312016-08-16 10:29:40 -0700339 if (superType == NULL) {
Yifan Hongc8934042016-11-17 17:10:52 -0800340 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700341 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000342 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700343 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700344 }
345
346 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700347
348 out.indent();
349
Andreas Huber881227d2016-08-02 14:20:21 -0700350 }
351
352 status_t err = emitTypeDeclarations(out);
353
354 if (err != OK) {
355 return err;
356 }
357
358 if (isInterface) {
359 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800360
Yifan Hongc8934042016-11-17 17:10:52 -0800361 out << "virtual bool isRemote() const ";
362 if (!isIBase()) {
363 out << "override ";
364 }
365 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800366
Andreas Huber881227d2016-08-02 14:20:21 -0700367 for (const auto &method : iface->methods()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700368 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700369
Andreas Huber881227d2016-08-02 14:20:21 -0700370 const bool returnsValue = !method->results().empty();
Steven Morelandd732ea12016-11-08 17:12:06 -0800371 const TypedVar *elidedReturn = method->canElideCallback();
372
373 if (elidedReturn == nullptr && returnsValue) {
374 out << "using "
375 << method->name()
376 << "_cb = std::function<void("
377 << Method::GetArgSignature(method->results(),
378 true /* specify namespaces */)
379 << ")>;\n";
380 }
Andreas Huber881227d2016-08-02 14:20:21 -0700381
Andreas Huber3599d922016-08-09 10:42:57 -0700382 method->dumpAnnotations(out);
383
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700384 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700385 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700386 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700387 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700388 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700389 }
390
391 out << method->name()
Andreas Huber881227d2016-08-02 14:20:21 -0700392 << "("
Steven Moreland979e0992016-09-07 09:18:08 -0700393 << Method::GetArgSignature(method->args(),
394 true /* specify namespaces */);
Andreas Huber881227d2016-08-02 14:20:21 -0700395
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700396 if (returnsValue && elidedReturn == nullptr) {
Andreas Huber881227d2016-08-02 14:20:21 -0700397 if (!method->args().empty()) {
398 out << ", ";
399 }
400
Steven Moreland67f67b42016-09-29 08:59:02 -0700401 out << method->name() << "_cb _hidl_cb";
Andreas Huber881227d2016-08-02 14:20:21 -0700402 }
403
Yifan Hong10fe0b52016-10-19 14:20:17 -0700404 out << ")";
405 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800406 if (!isIBase()) {
407 out << " override";
408 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700409 out << " {\n";
410 out.indent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100411 method->cppImpl(IMPL_HEADER, out);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700412 out.unindent();
413 out << "\n}\n";
414 } else {
415 out << " = 0;\n";
416 }
Andreas Huber881227d2016-08-02 14:20:21 -0700417 }
Steven Moreland40786312016-08-16 10:29:40 -0700418
Yifan Hong3d746092016-12-07 14:26:33 -0800419 out << "// cast static functions\n";
420 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700421
Yifan Hong3d746092016-12-07 14:26:33 -0800422 for (const Interface *superType : iface->typeChain()) {
423 out << "static "
424 << childTypeResult
425 << " castFrom("
426 << superType->getCppArgumentType()
427 << " parent"
428 << ");\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700429 }
430
Steven Morelandd39133b2016-11-11 12:30:08 -0800431 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700432
Yifan Hongc8934042016-11-17 17:10:52 -0800433 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800434 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800435 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800436 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800437 }
Andreas Huber881227d2016-08-02 14:20:21 -0700438 }
439
440 if (isInterface) {
441 out.unindent();
442
Andreas Hubere3f769a2016-10-10 10:54:44 -0700443 out << "};\n\n";
444 }
445
446 err = mRootScope->emitGlobalTypeDeclarations(out);
447
448 if (err != OK) {
449 return err;
Andreas Huber881227d2016-08-02 14:20:21 -0700450 }
451
452 out << "\n";
453 enterLeaveNamespace(out, false /* enter */);
454
455 out << "\n#endif // " << guard << "\n";
456
457 return OK;
458}
459
Steven Moreland40786312016-08-16 10:29:40 -0700460status_t AST::generateHwBinderHeader(const std::string &outputPath) const {
461 std::string ifaceName;
Yifan Hong244e82d2016-11-11 11:13:57 -0800462 bool isInterface = AST::isInterface(&ifaceName);
463 const Interface *iface = nullptr;
Yifan Hong244e82d2016-11-11 11:13:57 -0800464 std::string klassName{};
465
466 if(isInterface) {
467 iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800468 klassName = iface->getHwName();
Yifan Hong244e82d2016-11-11 11:13:57 -0800469 } else {
470 klassName = "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700471 }
472
Steven Moreland40786312016-08-16 10:29:40 -0700473 std::string path = outputPath;
474 path.append(mCoordinator->convertPackageRootToPath(mPackage));
475 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
476 path.append(klassName + ".h");
477
Yifan Hong244e82d2016-11-11 11:13:57 -0800478 FILE *file = fopen(path.c_str(), "w");
Steven Moreland40786312016-08-16 10:29:40 -0700479
480 if (file == NULL) {
481 return -errno;
482 }
483
484 Formatter out(file);
485
486 const std::string guard = makeHeaderGuard(klassName);
487
488 out << "#ifndef " << guard << "\n";
489 out << "#define " << guard << "\n\n";
490
Yifan Hong244e82d2016-11-11 11:13:57 -0800491 if (isInterface) {
492 generateCppPackageInclude(out, mPackage, ifaceName);
493 } else {
494 generateCppPackageInclude(out, mPackage, "types");
495 }
Steven Moreland40786312016-08-16 10:29:40 -0700496
Steven Morelandee88eed2016-10-31 17:49:00 -0700497 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700498
499 for (const auto &item : mImportedNames) {
500 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800501 generateCppPackageInclude(out, item, "hwtypes");
502 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800503 generateCppPackageInclude(out, item, item.getInterfaceStubName());
504 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700505 }
Steven Moreland40786312016-08-16 10:29:40 -0700506 }
507
508 out << "\n";
509
Martijn Coenen93915102016-09-01 01:35:52 +0200510 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700511 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100512 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700513
514 out << "\n";
515
516 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700517
Yifan Hong244e82d2016-11-11 11:13:57 -0800518 status_t err = mRootScope->emitGlobalHwDeclarations(out);
519 if (err != OK) {
520 return err;
521 }
Steven Moreland40786312016-08-16 10:29:40 -0700522
523 enterLeaveNamespace(out, false /* enter */);
524
525 out << "\n#endif // " << guard << "\n";
526
527 return OK;
528}
529
Andreas Huber881227d2016-08-02 14:20:21 -0700530status_t AST::emitTypeDeclarations(Formatter &out) const {
531 return mRootScope->emitTypeDeclarations(out);
532}
533
Yifan Hong7a118f52016-12-07 11:21:15 -0800534static void wrapPassthroughArg(Formatter &out,
535 const TypedVar *arg, bool addPrefixToName,
536 std::function<void(void)> handleError) {
537 if (!arg->type().isInterface()) {
538 return;
539 }
540 std::string name = (addPrefixToName ? "_hidl_out_" : "") + arg->name();
541 std::string wrappedName = (addPrefixToName ? "_hidl_out_wrapped_" : "_hidl_wrapped_")
542 + arg->name();
543 const Interface &iface = static_cast<const Interface &>(arg->type());
544 out << iface.getCppStackType() << " " << wrappedName << ";\n";
545 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
546 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
547 out << wrappedName
548 << " = "
549 << iface.fqName().cppName()
550 << "::castFrom(::android::hardware::wrapPassthrough("
551 << name << "));\n";
552 out.sIf(wrappedName + " == nullptr", [&] {
553 // Fatal error. Happens when the BsFoo class is not found in the binary
554 // or any dynamic libraries.
555 handleError();
556 }).endl();
557 }).sElse([&] {
558 out << wrappedName << " = " << name << ";\n";
559 }).endl().endl();
560}
561
Steven Moreland69e7c702016-09-09 11:16:32 -0700562status_t AST::generatePassthroughMethod(Formatter &out,
Yifan Hong068c5522016-10-31 14:07:25 -0700563 const Method *method) const {
564 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700565
566 out << " {\n";
567 out.indent();
568
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800569 if (method->isHidlReserved()
570 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
571 method->cppImpl(IMPL_PASSTHROUGH, out);
572 out.unindent();
573 out << "}\n\n";
574 return OK;
575 }
576
Steven Moreland69e7c702016-09-09 11:16:32 -0700577 const bool returnsValue = !method->results().empty();
578 const TypedVar *elidedReturn = method->canElideCallback();
579
Steven Moreland67f67b42016-09-29 08:59:02 -0700580 if (returnsValue && elidedReturn == nullptr) {
581 generateCheckNonNull(out, "_hidl_cb");
582 }
583
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700584 generateCppInstrumentationCall(
585 out,
586 InstrumentationEvent::PASSTHROUGH_ENTRY,
587 method);
588
Yifan Hong7a118f52016-12-07 11:21:15 -0800589
590 for (const auto &arg : method->args()) {
591 wrapPassthroughArg(out, arg, false /* addPrefixToName */, [&] {
592 out << "return ::android::hardware::Status::fromExceptionCode(\n";
593 out.indent(2, [&] {
594 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800595 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800596 });
597 });
598 }
599
600 out << "auto _hidl_error = ::android::hardware::Void();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700601 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700602
603 if (method->isOneway()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800604 out << "addOnewayTask([this, &_hidl_error";
Steven Moreland69e7c702016-09-09 11:16:32 -0700605 for (const auto &arg : method->args()) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800606 out << ", "
607 << (arg->type().isInterface() ? "_hidl_wrapped_" : "")
608 << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700609 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700610 out << "] {\n";
611 out.indent();
612 out << "this->";
Steven Moreland69e7c702016-09-09 11:16:32 -0700613 }
614
615 out << "mImpl->"
616 << method->name()
617 << "(";
618
619 bool first = true;
620 for (const auto &arg : method->args()) {
621 if (!first) {
622 out << ", ";
623 }
624 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800625 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Steven Moreland69e7c702016-09-09 11:16:32 -0700626 }
627 if (returnsValue && elidedReturn == nullptr) {
628 if (!method->args().empty()) {
629 out << ", ";
630 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800631 out << "[&](";
632 first = true;
633 for (const auto &arg : method->results()) {
634 if (!first) {
635 out << ", ";
636 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700637
Yifan Hong7a118f52016-12-07 11:21:15 -0800638 out << "const auto &_hidl_out_"
639 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800640
641 first = false;
642 }
643
644 out << ") {\n";
645 out.indent();
646 status_t status = generateCppInstrumentationCall(
647 out,
648 InstrumentationEvent::PASSTHROUGH_EXIT,
649 method);
650 if (status != OK) {
651 return status;
652 }
653
Yifan Hong7a118f52016-12-07 11:21:15 -0800654 for (const auto &arg : method->results()) {
655 wrapPassthroughArg(out, arg, true /* addPrefixToName */, [&] {
656 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
657 out.indent(2, [&] {
658 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800659 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800660 });
661 out << "return;\n";
662 });
663 }
664
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800665 out << "_hidl_cb(";
666 first = true;
667 for (const auto &arg : method->results()) {
668 if (!first) {
669 out << ", ";
670 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800671 first = false;
Yifan Hong7a118f52016-12-07 11:21:15 -0800672 out << (arg->type().isInterface() ? "_hidl_out_wrapped_" : "_hidl_out_")
673 << arg->name();
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800674 }
675 out << ");\n";
676 out.unindent();
677 out << "});\n\n";
678 } else {
679 out << ");\n\n";
680 if (elidedReturn != nullptr) {
681 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -0800682 << " _hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800683 << elidedReturn->name()
Steven Moreland2ae5bca2016-12-01 05:56:49 +0000684 << " = _hidl_return;\n";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800685 }
686 status_t status = generateCppInstrumentationCall(
687 out,
688 InstrumentationEvent::PASSTHROUGH_EXIT,
689 method);
690 if (status != OK) {
691 return status;
692 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700693 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700694
695 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700696 out.unindent();
697 out << "});\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700698 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700699
700 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700701
702 out.unindent();
703 out << "}\n";
704
705 return OK;
706}
707
Yifan Hong068c5522016-10-31 14:07:25 -0700708status_t AST::generateMethods(Formatter &out, MethodGenerator gen) const {
Steven Morelanda7a421a2016-09-07 08:35:18 -0700709
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700710 const Interface *iface = mRootScope->getInterface();
711
Yifan Hong10fe0b52016-10-19 14:20:17 -0700712 const Interface *prevIterface = nullptr;
713 for (const auto &tuple : iface->allMethodsFromRoot()) {
714 const Method *method = tuple.method();
715 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700716
Yifan Hong10fe0b52016-10-19 14:20:17 -0700717 if(prevIterface != superInterface) {
718 if (prevIterface != nullptr) {
719 out << "\n";
720 }
721 out << "// Methods from "
722 << superInterface->fullName()
723 << " follow.\n";
724 prevIterface = superInterface;
725 }
Yifan Hong068c5522016-10-31 14:07:25 -0700726 status_t err = gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700727
Yifan Hong10fe0b52016-10-19 14:20:17 -0700728 if (err != OK) {
729 return err;
730 }
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700731 }
732
Yifan Hong10fe0b52016-10-19 14:20:17 -0700733 out << "\n";
734
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700735 return OK;
736}
737
Andreas Huberb82318c2016-08-02 14:45:54 -0700738status_t AST::generateStubHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700739 std::string ifaceName;
740 if (!AST::isInterface(&ifaceName)) {
741 // types.hal does not get a stub header.
742 return OK;
743 }
744
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700745 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800746 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -0700747
Andreas Huberb82318c2016-08-02 14:45:54 -0700748 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700749 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700750 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Steven Moreland40786312016-08-16 10:29:40 -0700751 path.append(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700752 path.append(".h");
753
Andreas Huberd2943e12016-08-05 11:59:31 -0700754 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700755 FILE *file = fopen(path.c_str(), "w");
756
757 if (file == NULL) {
758 return -errno;
759 }
760
761 Formatter out(file);
762
Steven Moreland40786312016-08-16 10:29:40 -0700763 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700764
765 out << "#ifndef " << guard << "\n";
766 out << "#define " << guard << "\n\n";
767
Yifan Hongeefe4f22017-01-04 15:32:42 -0800768 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700769 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700770
771 enterLeaveNamespace(out, true /* enter */);
772 out << "\n";
773
774 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800775 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100776 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800777 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000778 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100779 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800780 out << " : public "
781 << gIBaseFqName.getInterfaceStubFqName().cppName()
782 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100783 }
Andreas Huber881227d2016-08-02 14:20:21 -0700784
785 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800786 out << "explicit "
787 << klassName
Steven Moreland40786312016-08-16 10:29:40 -0700788 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100789 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800790 out << "explicit "
791 << klassName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100792 << "(const ::android::sp<" << ifaceName << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800793 << " const std::string& HidlInstrumentor_package,"
794 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700795 << "\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700796 out << "::android::status_t onTransact(\n";
797 out.indent();
798 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700799 out << "uint32_t _hidl_code,\n";
800 out << "const ::android::hardware::Parcel &_hidl_data,\n";
801 out << "::android::hardware::Parcel *_hidl_reply,\n";
802 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700803 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700804 out.unindent();
805 out.unindent();
806
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100807 out << "::android::sp<" << ifaceName << "> getImpl() { return _hidl_mImpl; };\n";
808 out.unindent();
809 out << "private:\n";
810 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800811
812 status_t err = generateMethods(out, [&](const Method *method, const Interface *iface) {
813 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
814 return OK;
815 }
816 const bool returnsValue = !method->results().empty();
817 const TypedVar *elidedReturn = method->canElideCallback();
818
819 if (elidedReturn == nullptr && returnsValue) {
820 out << "using " << method->name() << "_cb = "
821 << iface->fqName().cppName()
822 << "::" << method->name() << "_cb;\n";
823 }
824 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800825 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800826 return OK;
827 });
828 if (err != OK) {
829 return err;
830 }
831
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100832 out << "::android::sp<" << ifaceName << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700833 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700834 out << "};\n\n";
835
836 enterLeaveNamespace(out, false /* enter */);
837
838 out << "\n#endif // " << guard << "\n";
839
840 return OK;
841}
842
Andreas Huberb82318c2016-08-02 14:45:54 -0700843status_t AST::generateProxyHeader(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700844 std::string ifaceName;
845 if (!AST::isInterface(&ifaceName)) {
846 // types.hal does not get a proxy header.
847 return OK;
848 }
849
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700850 const Interface *iface = mRootScope->getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800851 const std::string proxyName = iface->getProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -0700852
Andreas Huberb82318c2016-08-02 14:45:54 -0700853 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700854 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700855 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Yifan Hongeefe4f22017-01-04 15:32:42 -0800856 path.append(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700857 path.append(".h");
858
Andreas Huberd2943e12016-08-05 11:59:31 -0700859 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700860 FILE *file = fopen(path.c_str(), "w");
861
862 if (file == NULL) {
863 return -errno;
864 }
865
866 Formatter out(file);
867
Yifan Hongeefe4f22017-01-04 15:32:42 -0800868 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700869
870 out << "#ifndef " << guard << "\n";
871 out << "#define " << guard << "\n\n";
872
Martijn Coenen115d4282016-12-19 05:14:04 +0100873 out << "#include <hidl/HidlTransportSupport.h>\n\n";
874
Andreas Huber881227d2016-08-02 14:20:21 -0700875 std::vector<std::string> packageComponents;
876 getPackageAndVersionComponents(
877 &packageComponents, false /* cpp_compatible */);
878
Yifan Hongeefe4f22017-01-04 15:32:42 -0800879 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700880 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700881
882 enterLeaveNamespace(out, true /* enter */);
883 out << "\n";
884
885 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800886 << proxyName
887 << " : public ::android::hardware::BpInterface<"
888 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000889 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700890
891 out.indent();
892
Yifan Hongeefe4f22017-01-04 15:32:42 -0800893 out << "explicit "
894 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700895 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700896 << "\n\n";
897
Yifan Hong10fe0b52016-10-19 14:20:17 -0700898 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700899
Yifan Hong068c5522016-10-31 14:07:25 -0700900 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
901 method->generateCppSignature(out);
902 out << " override;\n";
903 return OK;
904 });
Steven Moreland9c387612016-09-07 09:54:26 -0700905
906 if (err != OK) {
907 return err;
908 }
Andreas Huber881227d2016-08-02 14:20:21 -0700909
910 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100911 out << "private:\n";
912 out.indent();
913 out << "std::mutex _hidl_mMutex;\n"
914 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
915 << " _hidl_mDeathRecipients;\n";
916 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700917 out << "};\n\n";
918
919 enterLeaveNamespace(out, false /* enter */);
920
921 out << "\n#endif // " << guard << "\n";
922
923 return OK;
924}
925
Andreas Huberb82318c2016-08-02 14:45:54 -0700926status_t AST::generateAllSource(const std::string &outputPath) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700927
Andreas Huberb82318c2016-08-02 14:45:54 -0700928 std::string path = outputPath;
Andreas Huberd2943e12016-08-05 11:59:31 -0700929 path.append(mCoordinator->convertPackageRootToPath(mPackage));
Andreas Huberdca261f2016-08-04 13:47:51 -0700930 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
Andreas Huber881227d2016-08-02 14:20:21 -0700931
932 std::string ifaceName;
933 std::string baseName;
934
Yifan Hongfe95aa22016-10-19 17:26:45 -0700935 const Interface *iface = nullptr;
936 bool isInterface;
Andreas Huber881227d2016-08-02 14:20:21 -0700937 if (!AST::isInterface(&ifaceName)) {
938 baseName = "types";
939 isInterface = false;
940 } else {
Yifan Hongfe95aa22016-10-19 17:26:45 -0700941 iface = mRootScope->getInterface();
Jayant Chowdhary3f32c1f2016-09-15 16:53:56 -0700942 baseName = iface->getBaseName();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700943 isInterface = true;
Andreas Huber881227d2016-08-02 14:20:21 -0700944 }
945
946 path.append(baseName);
947
948 if (baseName != "types") {
949 path.append("All");
950 }
951
952 path.append(".cpp");
953
Andreas Huberd2943e12016-08-05 11:59:31 -0700954 CHECK(Coordinator::MakeParentHierarchy(path));
Andreas Huber881227d2016-08-02 14:20:21 -0700955 FILE *file = fopen(path.c_str(), "w");
956
957 if (file == NULL) {
958 return -errno;
959 }
960
961 Formatter out(file);
962
Steven Moreland623c0042017-01-13 14:42:29 -0800963 out << "#define LOG_TAG \""
964 << mPackage.string() << "::" << baseName
965 << "\"\n\n";
966
Steven Moreland05cd4232016-11-21 16:01:12 -0800967 out << "#include <android/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100968 out << "#include <cutils/trace.h>\n";
969 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700970 if (isInterface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700971 // This is a no-op for IServiceManager itself.
972 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
973
Steven Morelandbec74ed2017-01-25 17:42:35 -0800974 // TODO(b/34274385) remove this
975 out << "#include <hidl/LegacySupport.h>\n";
976
Yifan Hongeefe4f22017-01-04 15:32:42 -0800977 generateCppPackageInclude(out, mPackage, iface->getProxyName());
978 generateCppPackageInclude(out, mPackage, iface->getStubName());
979 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700980
981 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700982 generateCppPackageInclude(out,
983 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800984 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700985 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800986
987 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700988 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700989 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800990 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700991 }
992
993 out << "\n";
994
995 enterLeaveNamespace(out, true /* enter */);
996 out << "\n";
997
998 status_t err = generateTypeSource(out, ifaceName);
999
1000 if (err == OK && isInterface) {
Yifan Hong10fe0b52016-10-19 14:20:17 -07001001 const Interface *iface = mRootScope->getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -07001002
1003 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -08001004 out << "const char* "
1005 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -07001006 << "::descriptor(\""
1007 << iface->fqName().string()
1008 << "\");\n\n";
Martijn Coenen8adcb652017-02-03 17:37:36 +01001009 out << "__attribute__((constructor))";
1010 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001011 out.indent([&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001012 out << "::android::hardware::gBnConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001013 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001014 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001015 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001016 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001017 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001018 out << "return new "
1019 << iface->getStubName()
1020 << "(reinterpret_cast<"
1021 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -08001022 << " *>(iIntf));\n";
1023 });
Yifan Hongb04de382017-02-06 15:31:52 -08001024 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001025 });
Yifan Hongb04de382017-02-06 15:31:52 -08001026 out << "::android::hardware::gBsConstructorMap.set("
Yifan Hongeefe4f22017-01-04 15:32:42 -08001027 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -08001028 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001029 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -08001030 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -08001031 << gIBaseFqName.cppName()
1032 << "> {\n";
1033 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001034 out << "return new "
1035 << iface->getPassthroughName()
1036 << "(reinterpret_cast<"
1037 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -08001038 << " *>(iIntf));\n";
1039 });
Yifan Hongb04de382017-02-06 15:31:52 -08001040 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -08001041 });
Yifan Hong158655a2016-11-08 12:34:07 -08001042 });
Martijn Coenen8adcb652017-02-03 17:37:36 +01001043 out << "};\n\n";
1044 out << "__attribute__((destructor))";
1045 out << "static void static_destructor() {\n";
1046 out.indent([&] {
1047 out << "::android::hardware::gBnConstructorMap.erase("
1048 << iface->localName()
1049 << "::descriptor);\n";
1050 out << "::android::hardware::gBsConstructorMap.erase("
1051 << iface->localName()
1052 << "::descriptor);\n";
1053 });
1054 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -08001055
Yifan Hongfe95aa22016-10-19 17:26:45 -07001056 err = generateInterfaceSource(out);
1057 }
1058
1059 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001060 err = generateProxySource(out, iface->fqName());
Andreas Huber881227d2016-08-02 14:20:21 -07001061 }
1062
1063 if (err == OK && isInterface) {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001064 err = generateStubSource(out, iface);
Andreas Huber881227d2016-08-02 14:20:21 -07001065 }
1066
Steven Moreland40786312016-08-16 10:29:40 -07001067 if (err == OK && isInterface) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001068 err = generatePassthroughSource(out);
1069 }
1070
1071 if (err == OK && isInterface) {
Steven Moreland9c387612016-09-07 09:54:26 -07001072 const Interface *iface = mRootScope->getInterface();
1073
Yifan Hongc8934042016-11-17 17:10:52 -08001074 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001075 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -08001076 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -08001077 std::string package = iface->fqName().package()
1078 + iface->fqName().atVersion();
1079
Yifan Hongeefe4f22017-01-04 15:32:42 -08001080 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -08001081 }
Steven Moreland40786312016-08-16 10:29:40 -07001082 }
1083
Andreas Huber881227d2016-08-02 14:20:21 -07001084 enterLeaveNamespace(out, false /* enter */);
1085
1086 return err;
1087}
1088
Steven Moreland67f67b42016-09-29 08:59:02 -07001089// static
1090void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -08001091 out.sIf(nonNull + " == nullptr", [&] {
1092 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1093 out.indent(2, [&] {
1094 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT);\n";
1095 });
1096 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -07001097}
1098
Andreas Huber881227d2016-08-02 14:20:21 -07001099status_t AST::generateTypeSource(
1100 Formatter &out, const std::string &ifaceName) const {
1101 return mRootScope->emitTypeDefinitions(out, ifaceName);
1102}
1103
Andreas Hubere7ff2282016-08-16 13:50:03 -07001104void AST::declareCppReaderLocals(
Andreas Huber5e44a292016-09-27 14:52:39 -07001105 Formatter &out,
1106 const std::vector<TypedVar *> &args,
1107 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -07001108 if (args.empty()) {
1109 return;
1110 }
1111
1112 for (const auto &arg : args) {
1113 const Type &type = arg->type();
1114
Yifan Hong3b320f82016-11-01 15:15:54 -07001115 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001116 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -07001117 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -07001118 << ";\n";
1119 }
1120
1121 out << "\n";
1122}
1123
Andreas Huber881227d2016-08-02 14:20:21 -07001124void AST::emitCppReaderWriter(
1125 Formatter &out,
1126 const std::string &parcelObj,
1127 bool parcelObjIsPointer,
1128 const TypedVar *arg,
1129 bool isReader,
Andreas Huber5e44a292016-09-27 14:52:39 -07001130 Type::ErrorMode mode,
1131 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -07001132 const Type &type = arg->type();
1133
Andreas Huber881227d2016-08-02 14:20:21 -07001134 type.emitReaderWriter(
1135 out,
Andreas Huber5e44a292016-09-27 14:52:39 -07001136 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -07001137 parcelObj,
1138 parcelObjIsPointer,
1139 isReader,
1140 mode);
1141}
1142
Yifan Hongbf459bc2016-08-23 16:50:37 -07001143void AST::emitCppResolveReferences(
1144 Formatter &out,
1145 const std::string &parcelObj,
1146 bool parcelObjIsPointer,
1147 const TypedVar *arg,
1148 bool isReader,
1149 Type::ErrorMode mode,
1150 bool addPrefixToName) const {
1151 const Type &type = arg->type();
1152 if(type.needsResolveReferences()) {
1153 type.emitResolveReferences(
1154 out,
1155 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1156 isReader, // nameIsPointer
1157 parcelObj,
1158 parcelObjIsPointer,
1159 isReader,
1160 mode);
1161 }
1162}
1163
Yifan Hong068c5522016-10-31 14:07:25 -07001164status_t AST::generateProxyMethodSource(Formatter &out,
1165 const std::string &klassName,
1166 const Method *method,
1167 const Interface *superInterface) const {
1168
1169 method->generateCppSignature(out,
1170 klassName,
1171 true /* specify namespaces */);
1172
1173 const bool returnsValue = !method->results().empty();
1174 const TypedVar *elidedReturn = method->canElideCallback();
1175
Steven Moreland41c6d2e2016-11-07 12:26:54 -08001176 out << " {\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001177
1178 out.indent();
1179
Martijn Coenen115d4282016-12-19 05:14:04 +01001180 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
1181 method->cppImpl(IMPL_PROXY, out);
1182 out.unindent();
1183 out << "}\n\n";
1184 return OK;
1185 }
1186
Yifan Hong068c5522016-10-31 14:07:25 -07001187 if (returnsValue && elidedReturn == nullptr) {
1188 generateCheckNonNull(out, "_hidl_cb");
1189 }
1190
1191 status_t status = generateCppInstrumentationCall(
1192 out,
1193 InstrumentationEvent::CLIENT_API_ENTRY,
Yifan Hong068c5522016-10-31 14:07:25 -07001194 method);
1195 if (status != OK) {
1196 return status;
1197 }
1198
1199 out << "::android::hardware::Parcel _hidl_data;\n";
1200 out << "::android::hardware::Parcel _hidl_reply;\n";
1201 out << "::android::status_t _hidl_err;\n";
1202 out << "::android::hardware::Status _hidl_status;\n\n";
1203
1204 declareCppReaderLocals(
1205 out, method->results(), true /* forResults */);
1206
1207 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001208 out << superInterface->fqName().cppName();
Yifan Hong068c5522016-10-31 14:07:25 -07001209 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001210 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1211
Martijn Coenenfff73352017-01-04 16:36:31 +01001212 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001213 // First DFS: write all buffers and resolve pointers for parent
1214 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001215 if (arg->type().isInterface()) {
1216 hasInterfaceArgument = true;
1217 }
Yifan Hong068c5522016-10-31 14:07:25 -07001218 emitCppReaderWriter(
1219 out,
1220 "_hidl_data",
1221 false /* parcelObjIsPointer */,
1222 arg,
1223 false /* reader */,
1224 Type::ErrorMode_Goto,
1225 false /* addPrefixToName */);
1226 }
1227
1228 // Second DFS: resolve references.
1229 for (const auto &arg : method->args()) {
1230 emitCppResolveReferences(
1231 out,
1232 "_hidl_data",
1233 false /* parcelObjIsPointer */,
1234 arg,
1235 false /* reader */,
1236 Type::ErrorMode_Goto,
1237 false /* addPrefixToName */);
1238 }
1239
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001240 if (hasInterfaceArgument) {
1241 // Start binder threadpool to handle incoming transactions
1242 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1243 }
Yifan Hong068c5522016-10-31 14:07:25 -07001244 out << "_hidl_err = remote()->transact("
1245 << method->getSerialId()
1246 << " /* "
1247 << method->name()
1248 << " */, _hidl_data, &_hidl_reply";
1249
1250 if (method->isOneway()) {
1251 out << ", ::android::hardware::IBinder::FLAG_ONEWAY";
1252 }
1253 out << ");\n";
1254
1255 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1256
1257 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001258 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001259 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1260 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1261
1262
1263 // First DFS: write all buffers and resolve pointers for parent
1264 for (const auto &arg : method->results()) {
1265 emitCppReaderWriter(
1266 out,
1267 "_hidl_reply",
1268 false /* parcelObjIsPointer */,
1269 arg,
1270 true /* reader */,
1271 Type::ErrorMode_Goto,
1272 true /* addPrefixToName */);
1273 }
1274
1275 // Second DFS: resolve references.
1276 for (const auto &arg : method->results()) {
1277 emitCppResolveReferences(
1278 out,
1279 "_hidl_reply",
1280 false /* parcelObjIsPointer */,
1281 arg,
1282 true /* reader */,
1283 Type::ErrorMode_Goto,
1284 true /* addPrefixToName */);
1285 }
1286
1287 if (returnsValue && elidedReturn == nullptr) {
1288 out << "_hidl_cb(";
1289
1290 bool first = true;
1291 for (const auto &arg : method->results()) {
1292 if (!first) {
1293 out << ", ";
1294 }
1295
1296 if (arg->type().resultNeedsDeref()) {
1297 out << "*";
1298 }
1299 out << "_hidl_out_" << arg->name();
1300
1301 first = false;
1302 }
1303
1304 out << ");\n\n";
1305 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001306 }
1307 status = generateCppInstrumentationCall(
1308 out,
1309 InstrumentationEvent::CLIENT_API_EXIT,
1310 method);
1311 if (status != OK) {
1312 return status;
Yifan Hong068c5522016-10-31 14:07:25 -07001313 }
1314
1315 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001316 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1317 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001318 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001319 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1320 } else {
1321 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1322 out << "return ::android::hardware::Return<void>();\n\n";
1323 }
1324
1325 out.unindent();
1326 out << "_hidl_error:\n";
1327 out.indent();
1328 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1329 out << "return ::android::hardware::Return<";
1330 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001331 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001332 } else {
1333 out << "void";
1334 }
1335 out << ">(_hidl_status);\n";
1336
1337 out.unindent();
1338 out << "}\n\n";
1339 return OK;
1340}
1341
Andreas Huber881227d2016-08-02 14:20:21 -07001342status_t AST::generateProxySource(
Yifan Hongeefe4f22017-01-04 15:32:42 -08001343 Formatter &out, const FQName &fqName) const {
1344 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001345
1346 out << klassName
1347 << "::"
1348 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001349 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001350
1351 out.indent();
1352 out.indent();
1353
1354 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001355 << "<"
1356 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001357 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001358 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001359 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001360 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001361 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001362 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001363
Andreas Huber881227d2016-08-02 14:20:21 -07001364 out.unindent();
1365 out.unindent();
1366 out << "}\n\n";
1367
Yifan Hong068c5522016-10-31 14:07:25 -07001368 status_t err = generateMethods(out, [&](const Method *method, const Interface *superInterface) {
1369 return generateProxyMethodSource(out, klassName, method, superInterface);
1370 });
Andreas Huber881227d2016-08-02 14:20:21 -07001371
Yifan Hong068c5522016-10-31 14:07:25 -07001372 return err;
Andreas Huber881227d2016-08-02 14:20:21 -07001373}
1374
1375status_t AST::generateStubSource(
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001376 Formatter &out,
Yifan Hongeefe4f22017-01-04 15:32:42 -08001377 const Interface *iface) const {
1378 const std::string interfaceName = iface->localName();
1379 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001380
Steven Moreland40786312016-08-16 10:29:40 -07001381 out << klassName
1382 << "::"
1383 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001384 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001385
1386 out.indent();
1387 out.indent();
1388
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001389 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001390 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001391 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001392 out << ": "
1393 << gIBaseFqName.getInterfaceStubFqName().cppName()
1394 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001395 }
1396
1397 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001398 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001399 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001400 << "\") { \n";
1401 out.indent();
1402 out << "_hidl_mImpl = _hidl_impl;\n";
1403 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001404
1405 out.unindent();
1406 out.unindent();
1407 out << "}\n\n";
1408
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001409 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001410 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001411 // class properly.
1412 out << klassName
1413 << "::"
1414 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001415 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1416 << " const std::string &HidlInstrumentor_package,"
1417 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001418
1419 out.indent();
1420 out.indent();
1421
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001422 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001423 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001424 out.indent();
1425 out << "_hidl_mImpl = _hidl_impl;\n";
1426 out.unindent();
1427
1428 out.unindent();
1429 out.unindent();
1430 out << "}\n\n";
1431 }
1432
Yifan Hongbcffce22017-02-01 15:52:06 -08001433 status_t err = generateMethods(out, [&](const Method *method, const Interface *) {
1434 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
1435 return OK;
1436 }
1437 method->generateCppSignature(out, iface->getStubName());
1438 out << " ";
1439 out.block([&] {
1440 method->cppImpl(IMPL_STUB_IMPL, out);
1441 }).endl();
1442 return OK;
1443 });
Steven Moreland60818632017-02-04 00:33:42 -08001444 if (err != OK) {
1445 return err;
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
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001809 << ", ::android::hardware::details::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()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001900 << "> impl) : ::android::hardware::details::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