blob: 98e3d27a36b4f37b21518a90f2af400127f80ac6 [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 Huber6755e9d2017-04-06 11:09:07 -070021#include "HidlTypeAssertion.h"
Timur Iskhakov7fa79f62017-08-09 11:04:54 -070022#include "Interface.h"
Andreas Huber881227d2016-08-02 14:20:21 -070023#include "Method.h"
Timur Iskhakov7fa79f62017-08-09 11:04:54 -070024#include "Reference.h"
Iliyan Malchev40d474a2016-08-16 06:20:17 -070025#include "ScalarType.h"
Andreas Huber881227d2016-08-02 14:20:21 -070026#include "Scope.h"
27
Andreas Huberdca261f2016-08-04 13:47:51 -070028#include <algorithm>
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070029#include <hidl-util/Formatter.h>
Steven Moreland5708edf2016-11-04 15:33:31 +000030#include <hidl-util/StringHelper.h>
Andreas Huber881227d2016-08-02 14:20:21 -070031#include <android-base/logging.h>
Andreas Huberdca261f2016-08-04 13:47:51 -070032#include <string>
Andreas Huber881227d2016-08-02 14:20:21 -070033#include <vector>
34
35namespace android {
36
Andreas Huber737080b2016-08-02 15:38:04 -070037void AST::getPackageComponents(
38 std::vector<std::string> *components) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070039 mPackage.getPackageComponents(components);
Andreas Huber737080b2016-08-02 15:38:04 -070040}
41
42void AST::getPackageAndVersionComponents(
43 std::vector<std::string> *components, bool cpp_compatible) const {
Andreas Huber0e00de42016-08-03 09:56:02 -070044 mPackage.getPackageAndVersionComponents(components, cpp_compatible);
Andreas Huber737080b2016-08-02 15:38:04 -070045}
46
Steven Moreland5708edf2016-11-04 15:33:31 +000047std::string AST::makeHeaderGuard(const std::string &baseName,
48 bool indicateGenerated) const {
49 std::string guard;
Andreas Huber881227d2016-08-02 14:20:21 -070050
Steven Moreland5708edf2016-11-04 15:33:31 +000051 if (indicateGenerated) {
52 guard += "HIDL_GENERATED_";
53 }
54
55 guard += StringHelper::Uppercase(mPackage.tokenName());
Andreas Huber881227d2016-08-02 14:20:21 -070056 guard += "_";
Steven Moreland5708edf2016-11-04 15:33:31 +000057 guard += StringHelper::Uppercase(baseName);
58 guard += "_H";
Andreas Huber881227d2016-08-02 14:20:21 -070059
60 return guard;
61}
62
Steven Morelandee88eed2016-10-31 17:49:00 -070063void AST::generateCppPackageInclude(
64 Formatter &out,
65 const FQName &package,
66 const std::string &klass) {
67
68 out << "#include <";
69
70 std::vector<std::string> components;
71 package.getPackageAndVersionComponents(&components, false /* cpp_compatible */);
72
73 for (const auto &component : components) {
74 out << component << "/";
75 }
76
77 out << klass
78 << ".h>\n";
79}
80
Andreas Huber881227d2016-08-02 14:20:21 -070081void AST::enterLeaveNamespace(Formatter &out, bool enter) const {
82 std::vector<std::string> packageComponents;
83 getPackageAndVersionComponents(
84 &packageComponents, true /* cpp_compatible */);
85
86 if (enter) {
87 for (const auto &component : packageComponents) {
88 out << "namespace " << component << " {\n";
89 }
Andreas Huber0e00de42016-08-03 09:56:02 -070090
Andreas Huber2831d512016-08-15 09:33:47 -070091 out.setNamespace(mPackage.cppNamespace() + "::");
Andreas Huber881227d2016-08-02 14:20:21 -070092 } else {
Andreas Huber0e00de42016-08-03 09:56:02 -070093 out.setNamespace(std::string());
94
Andreas Huber881227d2016-08-02 14:20:21 -070095 for (auto it = packageComponents.rbegin();
96 it != packageComponents.rend();
97 ++it) {
98 out << "} // namespace " << *it << "\n";
99 }
100 }
101}
102
Steven Moreland038903b2017-03-30 12:11:24 -0700103static void declareGetService(Formatter &out, const std::string &interfaceName, bool isTry) {
104 const std::string functionName = isTry ? "tryGetService" : "getService";
105
106 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800107 << "const std::string &serviceName=\"default\", bool getStub=false);\n";
Steven Moreland038903b2017-03-30 12:11:24 -0700108 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800109 << "const char serviceName[], bool getStub=false)"
110 << " { std::string str(serviceName ? serviceName : \"\");"
Steven Moreland038903b2017-03-30 12:11:24 -0700111 << " return " << functionName << "(str, getStub); }\n";
112 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800113 << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
114 // without c_str the std::string constructor is ambiguous
115 << " { std::string str(serviceName.c_str());"
Steven Moreland038903b2017-03-30 12:11:24 -0700116 << " return " << functionName << "(str, getStub); }\n";
117 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
118 << "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
119}
120
121static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
122 declareGetService(out, interfaceName, true /* isTry */);
123 declareGetService(out, interfaceName, false /* isTry */);
124
Steven Moreland90831502017-03-27 12:08:40 -0700125 out << "__attribute__ ((warn_unused_result))"
126 << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800127 out << "static bool registerForNotifications(\n";
128 out.indent(2, [&] {
129 out << "const std::string &serviceName,\n"
130 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
131 << "&notification);\n";
132 });
133
134}
135
Steven Moreland038903b2017-03-30 12:11:24 -0700136static void implementGetService(Formatter &out,
137 const FQName &fqName,
138 bool isTry) {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800139
140 const std::string interfaceName = fqName.getInterfaceName();
Steven Moreland038903b2017-03-30 12:11:24 -0700141 const std::string functionName = isTry ? "tryGetService" : "getService";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800142
Steven Moreland23cc5fa2018-05-09 10:48:48 -0700143 out << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
Yifan Hong31f07ff2017-03-21 18:56:35 +0000144 << "const std::string &serviceName, const bool getStub) ";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800145 out.block([&] {
Steven Moreland78f95f92017-10-06 17:07:40 -0700146 out << "return ::android::hardware::details::getServiceInternal<"
147 << fqName.getInterfaceProxyName()
148 << ">(serviceName, "
149 << (!isTry ? "true" : "false") // retry
150 << ", getStub);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800151 }).endl().endl();
Steven Moreland038903b2017-03-30 12:11:24 -0700152}
153
154static void implementServiceManagerInteractions(Formatter &out,
155 const FQName &fqName, const std::string &package) {
156
157 const std::string interfaceName = fqName.getInterfaceName();
158
159 implementGetService(out, fqName, true /* isTry */);
160 implementGetService(out, fqName, false /* isTry */);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800161
Yifan Hongeefe4f22017-01-04 15:32:42 -0800162 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800163 << "const std::string &serviceName) ";
164 out.block([&] {
Steven Moreland5f84b382018-10-11 12:10:35 -0700165 out << "return ::android::hardware::details::registerAsServiceInternal(this, serviceName);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800166 }).endl().endl();
167
Yifan Hongeefe4f22017-01-04 15:32:42 -0800168 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800169 out.indent(2, [&] {
170 out << "const std::string &serviceName,\n"
171 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
172 << "&notification) ";
173 });
174 out.block([&] {
175 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
176 out.indent(2, [&] {
177 out << "= ::android::hardware::defaultServiceManager();\n";
178 });
179 out.sIf("sm == nullptr", [&] {
180 out << "return false;\n";
181 }).endl();
182 out << "::android::hardware::Return<bool> success =\n";
183 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800184 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800185 out.indent(2, [&] {
186 out << "serviceName, notification);\n";
187 });
188 });
189 out << "return success.isOk() && success;\n";
190 }).endl().endl();
191}
192
Steven Moreland368e4602018-02-16 14:21:49 -0800193void AST::generateInterfaceHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700194 const Interface *iface = getInterface();
195 std::string ifaceName = iface ? iface->localName() : "types";
Andreas Huber881227d2016-08-02 14:20:21 -0700196 const std::string guard = makeHeaderGuard(ifaceName);
197
198 out << "#ifndef " << guard << "\n";
199 out << "#define " << guard << "\n\n";
200
Andreas Huber737080b2016-08-02 15:38:04 -0700201 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700202 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700203 }
204
205 if (!mImportedNames.empty()) {
206 out << "\n";
207 }
208
Steven Moreland19f11b52017-05-12 18:22:21 -0700209 if (iface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800210 if (isIBase()) {
211 out << "// skipped #include IServiceNotification.h\n\n";
212 } else {
213 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
214 }
Steven Moreland0693f312016-11-09 15:06:14 -0800215 }
216
Yifan Hongc8934042016-11-17 17:10:52 -0800217 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700218 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700219
Steven Moreland19f11b52017-05-12 18:22:21 -0700220 if (iface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200221 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700222 }
223
Martijn Coenenaf712c02016-11-16 15:26:27 +0100224 out << "#include <utils/NativeHandle.h>\n";
225 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700226
227 enterLeaveNamespace(out, true /* enter */);
228 out << "\n";
229
Steven Moreland19f11b52017-05-12 18:22:21 -0700230 if (iface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700231 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700232 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700233
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700234 const Interface *superType = iface->superType();
235
Yi Kong56758da2018-07-24 16:21:37 -0700236 if (superType == nullptr) {
Yifan Hongc8934042016-11-17 17:10:52 -0800237 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700238 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000239 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700240 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700241 }
242
243 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700244
245 out.indent();
246
Steven Moreland1a52e822017-07-27 13:56:29 -0700247 generateCppTag(out, "android::hardware::details::i_tag");
Andreas Huber881227d2016-08-02 14:20:21 -0700248 }
249
Steven Moreland368e4602018-02-16 14:21:49 -0800250 emitTypeDeclarations(out);
Andreas Huber881227d2016-08-02 14:20:21 -0700251
Steven Moreland19f11b52017-05-12 18:22:21 -0700252 if (iface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800253 out << "virtual bool isRemote() const ";
254 if (!isIBase()) {
255 out << "override ";
256 }
257 out << "{ return false; }\n\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800258
Steven Morelandf7f2a9a2017-07-21 18:05:38 -0700259 for (const auto& tuple : iface->allMethodsFromRoot()) {
260 const Method* method = tuple.method();
261
Andreas Huber881227d2016-08-02 14:20:21 -0700262 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700263
Andreas Huber881227d2016-08-02 14:20:21 -0700264 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700265 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Morelandd732ea12016-11-08 17:12:06 -0800266
267 if (elidedReturn == nullptr && returnsValue) {
268 out << "using "
269 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700270 << "_cb = std::function<void(";
271 method->emitCppResultSignature(out, true /* specify namespaces */);
272 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800273 }
Andreas Huber881227d2016-08-02 14:20:21 -0700274
Andreas Huber3599d922016-08-09 10:42:57 -0700275 method->dumpAnnotations(out);
276
Steven Moreland49bad8d2018-05-17 15:45:26 -0700277 method->emitDocComment(out);
278
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700279 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700280 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700281 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700282 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700283 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700284 }
285
286 out << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700287 << "(";
288 method->emitCppArgSignature(out, true /* specify namespaces */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700289 out << ")";
290 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800291 if (!isIBase()) {
292 out << " override";
293 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700294 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700295 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700296 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700297 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700298 }
Steven Moreland40786312016-08-16 10:29:40 -0700299
Yifan Hong3d746092016-12-07 14:26:33 -0800300 out << "// cast static functions\n";
301 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700302
Yifan Hong3d746092016-12-07 14:26:33 -0800303 for (const Interface *superType : iface->typeChain()) {
Yifan Hong200209c2017-03-29 03:39:09 -0700304 out << "static ::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -0800305 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -0700306 << "> castFrom("
Yifan Hong3d746092016-12-07 14:26:33 -0800307 << superType->getCppArgumentType()
308 << " parent"
Yifan Hong200209c2017-03-29 03:39:09 -0700309 << ", bool emitError = false);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700310 }
311
Steven Morelandd39133b2016-11-11 12:30:08 -0800312 out << "\nstatic const char* descriptor;\n\n";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700313
Yifan Hongc8934042016-11-17 17:10:52 -0800314 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800315 out << "// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800316 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800317 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800318 }
Andreas Huber881227d2016-08-02 14:20:21 -0700319 }
320
Steven Moreland19f11b52017-05-12 18:22:21 -0700321 if (iface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700322 out.unindent();
323
Andreas Hubere3f769a2016-10-10 10:54:44 -0700324 out << "};\n\n";
325 }
326
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700327 out << "//\n";
328 out << "// type declarations for package\n";
329 out << "//\n\n";
Steven Moreland368e4602018-02-16 14:21:49 -0800330 mRootScope.emitPackageTypeDeclarations(out);
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700331 out << "//\n";
332 out << "// type header definitions for package\n";
333 out << "//\n\n";
334 mRootScope.emitPackageTypeHeaderDefinitions(out);
Andreas Huber881227d2016-08-02 14:20:21 -0700335
336 out << "\n";
337 enterLeaveNamespace(out, false /* enter */);
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700338 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700339
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700340 out << "//\n";
341 out << "// global type declarations for package\n";
342 out << "//\n\n";
Steven Moreland8e61c5a2017-11-17 15:55:28 -0800343 mRootScope.emitGlobalTypeDeclarations(out);
344
Andreas Huber881227d2016-08-02 14:20:21 -0700345 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700346}
347
Steven Moreland368e4602018-02-16 14:21:49 -0800348void AST::generateHwBinderHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700349 const Interface *iface = getInterface();
350 std::string klassName = iface ? iface->getHwName() : "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700351
Steven Moreland40786312016-08-16 10:29:40 -0700352 const std::string guard = makeHeaderGuard(klassName);
353
354 out << "#ifndef " << guard << "\n";
355 out << "#define " << guard << "\n\n";
356
Steven Moreland19f11b52017-05-12 18:22:21 -0700357 generateCppPackageInclude(out, mPackage, iface ? iface->localName() : "types");
Steven Moreland40786312016-08-16 10:29:40 -0700358
Steven Morelandee88eed2016-10-31 17:49:00 -0700359 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700360
361 for (const auto &item : mImportedNames) {
362 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800363 generateCppPackageInclude(out, item, "hwtypes");
364 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800365 generateCppPackageInclude(out, item, item.getInterfaceStubName());
366 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700367 }
Steven Moreland40786312016-08-16 10:29:40 -0700368 }
369
370 out << "\n";
371
Martijn Coenen93915102016-09-01 01:35:52 +0200372 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700373 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100374 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700375
376 out << "\n";
377
378 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700379
Steven Moreland368e4602018-02-16 14:21:49 -0800380 mRootScope.emitPackageHwDeclarations(out);
Steven Moreland40786312016-08-16 10:29:40 -0700381
382 enterLeaveNamespace(out, false /* enter */);
383
384 out << "\n#endif // " << guard << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700385}
386
Steven Moreland368e4602018-02-16 14:21:49 -0800387void AST::emitTypeDeclarations(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700388 return mRootScope.emitTypeDeclarations(out);
Andreas Huber881227d2016-08-02 14:20:21 -0700389}
390
Steven Moreland58a20c72018-10-09 12:30:51 -0700391static std::string wrapPassthroughArg(Formatter& out, const NamedReference<Type>* arg,
392 std::string name, std::function<void(void)> handleError) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800393 if (!arg->type().isInterface()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700394 return name;
Yifan Hong7a118f52016-12-07 11:21:15 -0800395 }
Steven Moreland58a20c72018-10-09 12:30:51 -0700396 std::string wrappedName = "_hidl_wrapped_" + name;
Yifan Hong7a118f52016-12-07 11:21:15 -0800397 const Interface &iface = static_cast<const Interface &>(arg->type());
398 out << iface.getCppStackType() << " " << wrappedName << ";\n";
399 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
400 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
401 out << wrappedName
402 << " = "
Steven Morelandbff4bd22017-10-02 14:46:06 -0700403 << "::android::hardware::details::wrapPassthrough("
404 << name
405 << ");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800406 out.sIf(wrappedName + " == nullptr", [&] {
407 // Fatal error. Happens when the BsFoo class is not found in the binary
408 // or any dynamic libraries.
409 handleError();
410 }).endl();
411 }).sElse([&] {
412 out << wrappedName << " = " << name << ";\n";
413 }).endl().endl();
Steven Moreland58a20c72018-10-09 12:30:51 -0700414
415 return wrappedName;
Yifan Hong7a118f52016-12-07 11:21:15 -0800416}
417
Steven Moreland616cf4d2018-10-02 13:52:18 -0700418void AST::generatePassthroughMethod(Formatter& out, const Method* method, const Interface* superInterface) const {
Yifan Hong068c5522016-10-31 14:07:25 -0700419 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700420
Steven Moreland58a20c72018-10-09 12:30:51 -0700421 out << " override {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700422 out.indent();
423
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800424 if (method->isHidlReserved()
425 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
426 method->cppImpl(IMPL_PASSTHROUGH, out);
427 out.unindent();
428 out << "}\n\n";
Steven Moreland368e4602018-02-16 14:21:49 -0800429 return;
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800430 }
431
Steven Moreland69e7c702016-09-09 11:16:32 -0700432 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700433 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland69e7c702016-09-09 11:16:32 -0700434
Steven Moreland67f67b42016-09-29 08:59:02 -0700435 if (returnsValue && elidedReturn == nullptr) {
436 generateCheckNonNull(out, "_hidl_cb");
437 }
438
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700439 generateCppInstrumentationCall(
440 out,
441 InstrumentationEvent::PASSTHROUGH_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700442 method,
443 superInterface);
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700444
Steven Moreland58a20c72018-10-09 12:30:51 -0700445 std::vector<std::string> wrappedArgNames;
Yifan Hong7a118f52016-12-07 11:21:15 -0800446 for (const auto &arg : method->args()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700447 std::string name = wrapPassthroughArg(out, arg, arg->name(), [&] {
Yifan Hong7a118f52016-12-07 11:21:15 -0800448 out << "return ::android::hardware::Status::fromExceptionCode(\n";
449 out.indent(2, [&] {
450 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800451 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800452 });
453 });
Steven Moreland58a20c72018-10-09 12:30:51 -0700454
455 wrappedArgNames.push_back(name);
Yifan Hong7a118f52016-12-07 11:21:15 -0800456 }
457
Steven Moreland58a20c72018-10-09 12:30:51 -0700458 out << "::android::hardware::Status _hidl_error = ::android::hardware::Status::ok();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700459 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700460
461 if (method->isOneway()) {
Steven Moreland836cb312017-06-05 17:25:55 -0700462 out << "addOnewayTask([mImpl = this->mImpl\n"
463 << "#ifdef __ANDROID_DEBUGGABLE__\n"
464 ", mEnableInstrumentation = this->mEnableInstrumentation, "
465 "mInstrumentationCallbacks = this->mInstrumentationCallbacks\n"
466 << "#endif // __ANDROID_DEBUGGABLE__\n";
Steven Moreland58a20c72018-10-09 12:30:51 -0700467 for (const std::string& arg : wrappedArgNames) {
468 out << ", " << arg;
Steven Moreland69e7c702016-09-09 11:16:32 -0700469 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700470 out << "] {\n";
471 out.indent();
Steven Moreland69e7c702016-09-09 11:16:32 -0700472 }
473
474 out << "mImpl->"
475 << method->name()
476 << "(";
477
Yifan Hong932464e2017-03-30 15:40:22 -0700478 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800479 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700480 });
Steven Moreland58a20c72018-10-09 12:30:51 -0700481
482 std::function<void(void)> kHandlePassthroughError = [&] {
483 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
484 out.indent(2, [&] {
485 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
486 << "\"Cannot wrap passthrough interface.\");\n";
487 });
488 };
489
Steven Moreland69e7c702016-09-09 11:16:32 -0700490 if (returnsValue && elidedReturn == nullptr) {
Steven Moreland340c8822017-05-02 14:41:49 -0700491 // never true if oneway since oneway methods don't return values
492
Steven Moreland69e7c702016-09-09 11:16:32 -0700493 if (!method->args().empty()) {
494 out << ", ";
495 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800496 out << "[&](";
Yifan Hong932464e2017-03-30 15:40:22 -0700497 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800498 out << "const auto &_hidl_out_"
499 << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700500 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800501
502 out << ") {\n";
503 out.indent();
Steven Moreland92a08a72017-07-31 14:57:37 -0700504 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800505 out,
506 InstrumentationEvent::PASSTHROUGH_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700507 method,
508 superInterface);
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800509
Steven Moreland58a20c72018-10-09 12:30:51 -0700510 std::vector<std::string> wrappedOutNames;
Yifan Hong7a118f52016-12-07 11:21:15 -0800511 for (const auto &arg : method->results()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700512 wrappedOutNames.push_back(
513 wrapPassthroughArg(out, arg, "_hidl_out_" + arg->name(), kHandlePassthroughError));
Yifan Hong7a118f52016-12-07 11:21:15 -0800514 }
515
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800516 out << "_hidl_cb(";
Steven Moreland58a20c72018-10-09 12:30:51 -0700517 out.join(wrappedOutNames.begin(), wrappedOutNames.end(), ", ",
518 [&](const std::string& arg) { out << arg; });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800519 out << ");\n";
520 out.unindent();
521 out << "});\n\n";
522 } else {
523 out << ");\n\n";
Steven Moreland30b76e92017-06-02 18:52:24 -0700524
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800525 if (elidedReturn != nullptr) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700526 const std::string outName = "_hidl_out_" + elidedReturn->name();
527
528 out << elidedReturn->type().getCppResultType() << " " << outName
529 << " = _hidl_return;\n";
530 out << "(void) " << outName << ";\n";
531
532 const std::string wrappedName =
533 wrapPassthroughArg(out, elidedReturn, outName, kHandlePassthroughError);
534
535 if (outName != wrappedName) {
536 // update the original value since it is used by generateCppInstrumentationCall
537 out << outName << " = " << wrappedName << ";\n\n";
538
539 // update the value to be returned
540 out << "_hidl_return = " << outName << "\n;";
541 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800542 }
Steven Moreland92a08a72017-07-31 14:57:37 -0700543 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800544 out,
545 InstrumentationEvent::PASSTHROUGH_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700546 method,
547 superInterface);
Steven Moreland69e7c702016-09-09 11:16:32 -0700548 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700549
550 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700551 out.unindent();
552 out << "});\n";
Steven Moreland58a20c72018-10-09 12:30:51 -0700553 } else {
554 out << "if (!_hidl_error.isOk()) return _hidl_error;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700555 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700556
557 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700558
559 out.unindent();
560 out << "}\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700561}
562
Steven Moreland368e4602018-02-16 14:21:49 -0800563void AST::generateMethods(Formatter& out, const MethodGenerator& gen, bool includeParent) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700564 const Interface* iface = mRootScope.getInterface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700565
Yifan Hong10fe0b52016-10-19 14:20:17 -0700566 const Interface *prevIterface = nullptr;
567 for (const auto &tuple : iface->allMethodsFromRoot()) {
568 const Method *method = tuple.method();
569 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700570
Steven Morelandf16c5c02017-07-31 16:50:06 -0700571 if (!includeParent && superInterface != iface) {
572 continue;
573 }
574
Yifan Hong10fe0b52016-10-19 14:20:17 -0700575 if(prevIterface != superInterface) {
576 if (prevIterface != nullptr) {
577 out << "\n";
578 }
579 out << "// Methods from "
580 << superInterface->fullName()
581 << " follow.\n";
582 prevIterface = superInterface;
583 }
Steven Moreland368e4602018-02-16 14:21:49 -0800584 gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700585 }
586
Yifan Hong10fe0b52016-10-19 14:20:17 -0700587 out << "\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700588}
589
Steven Moreland0b843772017-06-23 16:33:38 -0700590void AST::generateTemplatizationLink(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700591 out << "typedef " << mRootScope.getInterface()->localName() << " Pure;\n\n";
Steven Moreland0b843772017-06-23 16:33:38 -0700592}
593
Steven Moreland1a52e822017-07-27 13:56:29 -0700594void AST::generateCppTag(Formatter& out, const std::string& tag) const {
595 out << "typedef " << tag << " _hidl_tag;\n\n";
596}
597
Steven Moreland368e4602018-02-16 14:21:49 -0800598void AST::generateStubHeader(Formatter& out) const {
Steven Moreland5abcf012018-02-08 18:50:18 -0800599 CHECK(AST::isInterface());
Andreas Huber881227d2016-08-02 14:20:21 -0700600
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700601 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800602 const std::string klassName = iface->getStubName();
Steven Moreland40786312016-08-16 10:29:40 -0700603 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700604
605 out << "#ifndef " << guard << "\n";
606 out << "#define " << guard << "\n\n";
607
Yifan Hongeefe4f22017-01-04 15:32:42 -0800608 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Moreland1a52e822017-07-27 13:56:29 -0700609
Steven Morelandee88eed2016-10-31 17:49:00 -0700610 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700611
612 enterLeaveNamespace(out, true /* enter */);
613 out << "\n";
614
615 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800616 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100617 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800618 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000619 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100620 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800621 out << " : public "
622 << gIBaseFqName.getInterfaceStubFqName().cppName()
623 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100624 }
Andreas Huber881227d2016-08-02 14:20:21 -0700625
626 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800627 out << "explicit "
628 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -0700629 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100630 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800631 out << "explicit "
632 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -0700633 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800634 << " const std::string& HidlInstrumentor_package,"
635 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700636 << "\n\n";
Steven Moreland57a89362017-07-21 19:29:54 +0000637 out << "virtual ~" << klassName << "();\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700638 out << "::android::status_t onTransact(\n";
639 out.indent();
640 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700641 out << "uint32_t _hidl_code,\n";
642 out << "const ::android::hardware::Parcel &_hidl_data,\n";
643 out << "::android::hardware::Parcel *_hidl_reply,\n";
644 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700645 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700646 out.unindent();
647 out.unindent();
648
Steven Moreland0b843772017-06-23 16:33:38 -0700649 out.endl();
650 generateTemplatizationLink(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700651 generateCppTag(out, "android::hardware::details::bnhw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700652
Steven Morelandcbcf9f72017-11-20 10:04:15 -0800653 out << "::android::sp<" << iface->localName() << "> getImpl() { return _hidl_mImpl; }\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700654
Steven Moreland368e4602018-02-16 14:21:49 -0800655 generateMethods(out,
656 [&](const Method* method, const Interface*) {
657 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
658 return;
659 }
Steven Morelandf16c5c02017-07-31 16:50:06 -0700660
Steven Moreland368e4602018-02-16 14:21:49 -0800661 out << "static ::android::status_t _hidl_" << method->name() << "(\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700662
Steven Moreland368e4602018-02-16 14:21:49 -0800663 out.indent(2,
664 [&] {
665 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
666 << "const ::android::hardware::Parcel &_hidl_data,\n"
667 << "::android::hardware::Parcel *_hidl_reply,\n"
668 << "TransactCallback _hidl_cb);\n";
669 })
670 .endl()
671 .endl();
672 },
673 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -0700674
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100675 out.unindent();
676 out << "private:\n";
677 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800678
Steven Moreland368e4602018-02-16 14:21:49 -0800679 generateMethods(out, [&](const Method* method, const Interface* iface) {
Yifan Hongcd2ae452017-01-31 14:33:40 -0800680 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
Steven Moreland368e4602018-02-16 14:21:49 -0800681 return;
Yifan Hongcd2ae452017-01-31 14:33:40 -0800682 }
683 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700684 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800685
686 if (elidedReturn == nullptr && returnsValue) {
687 out << "using " << method->name() << "_cb = "
688 << iface->fqName().cppName()
689 << "::" << method->name() << "_cb;\n";
690 }
691 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800692 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800693 });
Yifan Hongcd2ae452017-01-31 14:33:40 -0800694
Steven Moreland19f11b52017-05-12 18:22:21 -0700695 out << "::android::sp<" << iface->localName() << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700696 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700697 out << "};\n\n";
698
699 enterLeaveNamespace(out, false /* enter */);
700
701 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700702}
703
Steven Moreland368e4602018-02-16 14:21:49 -0800704void AST::generateProxyHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700705 if (!AST::isInterface()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700706 // types.hal does not get a proxy header.
Steven Moreland368e4602018-02-16 14:21:49 -0800707 return;
Andreas Huber881227d2016-08-02 14:20:21 -0700708 }
709
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700710 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800711 const std::string proxyName = iface->getProxyName();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800712 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700713
714 out << "#ifndef " << guard << "\n";
715 out << "#define " << guard << "\n\n";
716
Martijn Coenen115d4282016-12-19 05:14:04 +0100717 out << "#include <hidl/HidlTransportSupport.h>\n\n";
718
Andreas Huber881227d2016-08-02 14:20:21 -0700719 std::vector<std::string> packageComponents;
720 getPackageAndVersionComponents(
721 &packageComponents, false /* cpp_compatible */);
722
Yifan Hongeefe4f22017-01-04 15:32:42 -0800723 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700724 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700725
726 enterLeaveNamespace(out, true /* enter */);
727 out << "\n";
728
729 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800730 << proxyName
731 << " : public ::android::hardware::BpInterface<"
732 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000733 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700734
735 out.indent();
736
Yifan Hongeefe4f22017-01-04 15:32:42 -0800737 out << "explicit "
738 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700739 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700740 << "\n\n";
741
Steven Moreland0b843772017-06-23 16:33:38 -0700742 generateTemplatizationLink(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700743 generateCppTag(out, "android::hardware::details::bphw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700744
Yifan Hong10fe0b52016-10-19 14:20:17 -0700745 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700746
Steven Moreland368e4602018-02-16 14:21:49 -0800747 generateMethods(
748 out,
749 [&](const Method* method, const Interface*) {
750 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
751 return;
752 }
Steven Morelandf16c5c02017-07-31 16:50:06 -0700753
Steven Moreland368e4602018-02-16 14:21:49 -0800754 out << "static ";
755 method->generateCppReturnType(out);
756 out << " _hidl_" << method->name() << "("
757 << "::android::hardware::IInterface* _hidl_this, "
758 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700759
Steven Moreland368e4602018-02-16 14:21:49 -0800760 if (!method->hasEmptyCppArgSignature()) {
761 out << ", ";
762 }
763 method->emitCppArgSignature(out);
764 out << ");\n";
765 },
766 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -0700767
Steven Moreland368e4602018-02-16 14:21:49 -0800768 generateMethods(out, [&](const Method* method, const Interface*) {
Yifan Hong068c5522016-10-31 14:07:25 -0700769 method->generateCppSignature(out);
770 out << " override;\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700771 });
Steven Moreland9c387612016-09-07 09:54:26 -0700772
Andreas Huber881227d2016-08-02 14:20:21 -0700773 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100774 out << "private:\n";
775 out.indent();
776 out << "std::mutex _hidl_mMutex;\n"
777 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
778 << " _hidl_mDeathRecipients;\n";
779 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700780 out << "};\n\n";
781
782 enterLeaveNamespace(out, false /* enter */);
783
784 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700785}
786
Steven Moreland368e4602018-02-16 14:21:49 -0800787void AST::generateCppSource(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700788 std::string baseName = getBaseName();
789 const Interface *iface = getInterface();
Andreas Huber881227d2016-08-02 14:20:21 -0700790
Steven Morelanda885d252017-09-25 18:44:43 -0700791 const std::string klassName = baseName + (baseName == "types" ? "" : "All");
Andreas Huber881227d2016-08-02 14:20:21 -0700792
Steven Moreland623c0042017-01-13 14:42:29 -0800793 out << "#define LOG_TAG \""
794 << mPackage.string() << "::" << baseName
795 << "\"\n\n";
796
Steven Moreland5add34d2018-11-08 16:31:30 -0800797 out << "#include <log/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100798 out << "#include <cutils/trace.h>\n";
799 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Steven Moreland26896a92018-07-31 15:31:01 -0700800 out << "#include <hidl/Static.h>\n";
801 out << "#include <hwbinder/ProcessState.h>\n";
Steven Moreland4607ef52018-05-09 10:52:47 -0700802 out << "#include <utils/Trace.h>\n";
Steven Moreland19f11b52017-05-12 18:22:21 -0700803 if (iface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700804 // This is a no-op for IServiceManager itself.
805 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
806
Yifan Hongeefe4f22017-01-04 15:32:42 -0800807 generateCppPackageInclude(out, mPackage, iface->getProxyName());
808 generateCppPackageInclude(out, mPackage, iface->getStubName());
809 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700810
811 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700812 generateCppPackageInclude(out,
813 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800814 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700815 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800816
817 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700818 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700819 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800820 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700821 }
822
823 out << "\n";
824
825 enterLeaveNamespace(out, true /* enter */);
826 out << "\n";
827
Steven Moreland368e4602018-02-16 14:21:49 -0800828 generateTypeSource(out, iface ? iface->localName() : "");
Andreas Huber881227d2016-08-02 14:20:21 -0700829
Steven Moreland368e4602018-02-16 14:21:49 -0800830 if (iface) {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700831 const Interface* iface = mRootScope.getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700832
833 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -0800834 out << "const char* "
835 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -0700836 << "::descriptor(\""
837 << iface->fqName().string()
838 << "\");\n\n";
Yifan Hong91977fd2017-11-09 16:07:37 -0800839 out << "__attribute__((constructor)) ";
Martijn Coenen8adcb652017-02-03 17:37:36 +0100840 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800841 out.indent([&] {
Yifan Hong91977fd2017-11-09 16:07:37 -0800842 out << "::android::hardware::details::getBnConstructorMap().set("
Yifan Hongeefe4f22017-01-04 15:32:42 -0800843 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -0800844 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800845 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -0800846 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800847 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800848 out << "return new "
849 << iface->getStubName()
Yifan Hong341112d2017-04-20 18:12:05 -0700850 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -0800851 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -0800852 << " *>(iIntf));\n";
853 });
Yifan Hongb04de382017-02-06 15:31:52 -0800854 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800855 });
Yifan Hong91977fd2017-11-09 16:07:37 -0800856 out << "::android::hardware::details::getBsConstructorMap().set("
Yifan Hongeefe4f22017-01-04 15:32:42 -0800857 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -0800858 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800859 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -0800860 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -0800861 << gIBaseFqName.cppName()
862 << "> {\n";
863 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800864 out << "return new "
865 << iface->getPassthroughName()
Yifan Hong341112d2017-04-20 18:12:05 -0700866 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -0800867 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -0800868 << " *>(iIntf));\n";
869 });
Yifan Hongb04de382017-02-06 15:31:52 -0800870 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800871 });
Yifan Hong158655a2016-11-08 12:34:07 -0800872 });
Martijn Coenen8adcb652017-02-03 17:37:36 +0100873 out << "};\n\n";
874 out << "__attribute__((destructor))";
875 out << "static void static_destructor() {\n";
876 out.indent([&] {
Yifan Hong91977fd2017-11-09 16:07:37 -0800877 out << "::android::hardware::details::getBnConstructorMap().erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +0100878 << iface->localName()
879 << "::descriptor);\n";
Yifan Hong91977fd2017-11-09 16:07:37 -0800880 out << "::android::hardware::details::getBsConstructorMap().erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +0100881 << iface->localName()
882 << "::descriptor);\n";
883 });
884 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800885
Steven Moreland368e4602018-02-16 14:21:49 -0800886 generateInterfaceSource(out);
887 generateProxySource(out, iface->fqName());
888 generateStubSource(out, iface);
889 generatePassthroughSource(out);
Steven Moreland9c387612016-09-07 09:54:26 -0700890
Yifan Hongc8934042016-11-17 17:10:52 -0800891 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800892 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800893 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800894 std::string package = iface->fqName().package()
895 + iface->fqName().atVersion();
896
Yifan Hongeefe4f22017-01-04 15:32:42 -0800897 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -0800898 }
Steven Moreland40786312016-08-16 10:29:40 -0700899 }
900
Andreas Huber6755e9d2017-04-06 11:09:07 -0700901 HidlTypeAssertion::EmitAll(out);
902 out << "\n";
903
Andreas Huber881227d2016-08-02 14:20:21 -0700904 enterLeaveNamespace(out, false /* enter */);
Andreas Huber881227d2016-08-02 14:20:21 -0700905}
906
Steven Moreland67f67b42016-09-29 08:59:02 -0700907void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -0800908 out.sIf(nonNull + " == nullptr", [&] {
909 out << "return ::android::hardware::Status::fromExceptionCode(\n";
910 out.indent(2, [&] {
Steven Moreland610002f2017-06-16 13:02:49 -0700911 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT,\n"
912 << "\"Null synchronous callback passed.\");\n";
Yifan Honga018ed52016-12-13 16:35:08 -0800913 });
914 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -0700915}
916
Steven Moreland368e4602018-02-16 14:21:49 -0800917void AST::generateTypeSource(Formatter& out, const std::string& ifaceName) const {
918 mRootScope.emitTypeDefinitions(out, ifaceName);
Andreas Huber881227d2016-08-02 14:20:21 -0700919}
920
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700921void AST::declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& args,
922 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700923 if (args.empty()) {
924 return;
925 }
926
927 for (const auto &arg : args) {
928 const Type &type = arg->type();
929
Yifan Hong3b320f82016-11-01 15:15:54 -0700930 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700931 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700932 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700933 << ";\n";
934 }
935
936 out << "\n";
937}
938
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700939void AST::emitCppReaderWriter(Formatter& out, const std::string& parcelObj, bool parcelObjIsPointer,
940 const NamedReference<Type>* arg, bool isReader, Type::ErrorMode mode,
941 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700942 const Type &type = arg->type();
943
Andreas Huber881227d2016-08-02 14:20:21 -0700944 type.emitReaderWriter(
945 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700946 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700947 parcelObj,
948 parcelObjIsPointer,
949 isReader,
950 mode);
951}
952
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700953void AST::emitCppResolveReferences(Formatter& out, const std::string& parcelObj,
954 bool parcelObjIsPointer, const NamedReference<Type>* arg,
955 bool isReader, Type::ErrorMode mode,
956 bool addPrefixToName) const {
Yifan Hongbf459bc2016-08-23 16:50:37 -0700957 const Type &type = arg->type();
958 if(type.needsResolveReferences()) {
959 type.emitResolveReferences(
960 out,
961 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
962 isReader, // nameIsPointer
963 parcelObj,
964 parcelObjIsPointer,
965 isReader,
966 mode);
967 }
968}
969
Steven Moreland368e4602018-02-16 14:21:49 -0800970void AST::generateProxyMethodSource(Formatter& out, const std::string& klassName,
971 const Method* method, const Interface* superInterface) const {
Yifan Hong068c5522016-10-31 14:07:25 -0700972 method->generateCppSignature(out,
973 klassName,
974 true /* specify namespaces */);
975
Martijn Coenen115d4282016-12-19 05:14:04 +0100976 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
Steven Morelandf16c5c02017-07-31 16:50:06 -0700977 out.block([&] {
978 method->cppImpl(IMPL_PROXY, out);
979 }).endl().endl();
Steven Moreland368e4602018-02-16 14:21:49 -0800980 return;
Martijn Coenen115d4282016-12-19 05:14:04 +0100981 }
982
Steven Morelandf16c5c02017-07-31 16:50:06 -0700983 out.block([&] {
984 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700985 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Morelandf16c5c02017-07-31 16:50:06 -0700986
987 method->generateCppReturnType(out);
988
989 out << " _hidl_out = "
990 << superInterface->fqName().cppNamespace()
991 << "::"
992 << superInterface->getProxyName()
993 << "::_hidl_"
994 << method->name()
995 << "(this, this";
996
997 if (!method->hasEmptyCppArgSignature()) {
998 out << ", ";
999 }
1000
1001 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
1002 out << arg->name();
1003 });
1004
1005 if (returnsValue && elidedReturn == nullptr) {
1006 if (!method->args().empty()) {
1007 out << ", ";
1008 }
1009 out << "_hidl_cb";
1010 }
1011
1012 out << ");\n\n";
1013
1014 out << "return _hidl_out;\n";
1015 }).endl().endl();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001016}
1017
Steven Moreland368e4602018-02-16 14:21:49 -08001018void AST::generateStaticProxyMethodSource(Formatter& out, const std::string& klassName,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001019 const Method* method, const Interface* superInterface) const {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001020 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001021 return;
Steven Morelandf16c5c02017-07-31 16:50:06 -07001022 }
1023
1024 method->generateCppReturnType(out);
1025
1026 out << klassName
1027 << "::_hidl_"
1028 << method->name()
1029 << "("
1030 << "::android::hardware::IInterface *_hidl_this, "
1031 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
1032
1033 if (!method->hasEmptyCppArgSignature()) {
1034 out << ", ";
1035 }
1036
1037 method->emitCppArgSignature(out);
1038 out << ") {\n";
1039
1040 out.indent();
1041
1042 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1043 out << "bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();\n";
1044 out << "const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();\n";
1045 out << "#else\n";
1046 out << "(void) _hidl_this_instrumentor;\n";
1047 out << "#endif // __ANDROID_DEBUGGABLE__\n";
1048
1049 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001050 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Yifan Hong068c5522016-10-31 14:07:25 -07001051 if (returnsValue && elidedReturn == nullptr) {
1052 generateCheckNonNull(out, "_hidl_cb");
1053 }
1054
Steven Moreland92a08a72017-07-31 14:57:37 -07001055 generateCppInstrumentationCall(
Yifan Hong068c5522016-10-31 14:07:25 -07001056 out,
1057 InstrumentationEvent::CLIENT_API_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001058 method,
1059 superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001060
1061 out << "::android::hardware::Parcel _hidl_data;\n";
1062 out << "::android::hardware::Parcel _hidl_reply;\n";
1063 out << "::android::status_t _hidl_err;\n";
1064 out << "::android::hardware::Status _hidl_status;\n\n";
1065
1066 declareCppReaderLocals(
1067 out, method->results(), true /* forResults */);
1068
1069 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001070 out << klassName;
Yifan Hong068c5522016-10-31 14:07:25 -07001071 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001072 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1073
Martijn Coenenfff73352017-01-04 16:36:31 +01001074 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001075 // First DFS: write all buffers and resolve pointers for parent
1076 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001077 if (arg->type().isInterface()) {
1078 hasInterfaceArgument = true;
1079 }
Yifan Hong068c5522016-10-31 14:07:25 -07001080 emitCppReaderWriter(
1081 out,
1082 "_hidl_data",
1083 false /* parcelObjIsPointer */,
1084 arg,
1085 false /* reader */,
1086 Type::ErrorMode_Goto,
1087 false /* addPrefixToName */);
1088 }
1089
1090 // Second DFS: resolve references.
1091 for (const auto &arg : method->args()) {
1092 emitCppResolveReferences(
1093 out,
1094 "_hidl_data",
1095 false /* parcelObjIsPointer */,
1096 arg,
1097 false /* reader */,
1098 Type::ErrorMode_Goto,
1099 false /* addPrefixToName */);
1100 }
1101
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001102 if (hasInterfaceArgument) {
1103 // Start binder threadpool to handle incoming transactions
1104 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1105 }
Steven Morelandf16c5c02017-07-31 16:50:06 -07001106 out << "_hidl_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact("
Yifan Hong068c5522016-10-31 14:07:25 -07001107 << method->getSerialId()
1108 << " /* "
1109 << method->name()
1110 << " */, _hidl_data, &_hidl_reply";
1111
1112 if (method->isOneway()) {
Steven Moreland77943692018-08-09 12:53:42 -07001113 out << ", " << Interface::FLAG_ONE_WAY->cppValue();
Yifan Hong068c5522016-10-31 14:07:25 -07001114 }
1115 out << ");\n";
1116
1117 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1118
1119 if (!method->isOneway()) {
Yifan Hong859e53f2016-11-14 19:08:24 -08001120 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001121 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1122 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1123
1124
1125 // First DFS: write all buffers and resolve pointers for parent
1126 for (const auto &arg : method->results()) {
1127 emitCppReaderWriter(
1128 out,
1129 "_hidl_reply",
1130 false /* parcelObjIsPointer */,
1131 arg,
1132 true /* reader */,
1133 Type::ErrorMode_Goto,
1134 true /* addPrefixToName */);
1135 }
1136
1137 // Second DFS: resolve references.
1138 for (const auto &arg : method->results()) {
1139 emitCppResolveReferences(
1140 out,
1141 "_hidl_reply",
1142 false /* parcelObjIsPointer */,
1143 arg,
1144 true /* reader */,
1145 Type::ErrorMode_Goto,
1146 true /* addPrefixToName */);
1147 }
1148
1149 if (returnsValue && elidedReturn == nullptr) {
1150 out << "_hidl_cb(";
1151
Yifan Hong932464e2017-03-30 15:40:22 -07001152 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001153 if (arg->type().resultNeedsDeref()) {
1154 out << "*";
1155 }
1156 out << "_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001157 });
Yifan Hong068c5522016-10-31 14:07:25 -07001158
1159 out << ");\n\n";
1160 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001161 }
Steven Morelandf16c5c02017-07-31 16:50:06 -07001162
Steven Moreland92a08a72017-07-31 14:57:37 -07001163 generateCppInstrumentationCall(
Martijn Coenen7b295242016-11-04 16:52:56 +01001164 out,
1165 InstrumentationEvent::CLIENT_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001166 method,
1167 superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001168
1169 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001170 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1171 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001172 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001173 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1174 } else {
1175 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1176 out << "return ::android::hardware::Return<void>();\n\n";
1177 }
1178
1179 out.unindent();
1180 out << "_hidl_error:\n";
1181 out.indent();
1182 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1183 out << "return ::android::hardware::Return<";
1184 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001185 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001186 } else {
1187 out << "void";
1188 }
1189 out << ">(_hidl_status);\n";
1190
1191 out.unindent();
1192 out << "}\n\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001193}
1194
Steven Moreland368e4602018-02-16 14:21:49 -08001195void AST::generateProxySource(Formatter& out, const FQName& fqName) const {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001196 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001197
1198 out << klassName
1199 << "::"
1200 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001201 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001202
1203 out.indent();
1204 out.indent();
1205
1206 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001207 << "<"
1208 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001209 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001210 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001211 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001212 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001213 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001214 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001215
Andreas Huber881227d2016-08-02 14:20:21 -07001216 out.unindent();
1217 out.unindent();
1218 out << "}\n\n";
1219
Steven Moreland368e4602018-02-16 14:21:49 -08001220 generateMethods(out,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001221 [&](const Method* method, const Interface* superInterface) {
1222 generateStaticProxyMethodSource(out, klassName, method, superInterface);
Steven Moreland368e4602018-02-16 14:21:49 -08001223 },
1224 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -07001225
Steven Moreland368e4602018-02-16 14:21:49 -08001226 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1227 generateProxyMethodSource(out, klassName, method, superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001228 });
Andreas Huber881227d2016-08-02 14:20:21 -07001229}
1230
Steven Moreland368e4602018-02-16 14:21:49 -08001231void AST::generateStubSource(Formatter& out, const Interface* iface) const {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001232 const std::string interfaceName = iface->localName();
1233 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001234
Steven Moreland40786312016-08-16 10:29:40 -07001235 out << klassName
1236 << "::"
1237 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001238 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001239
1240 out.indent();
1241 out.indent();
1242
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001243 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001244 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001245 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001246 out << ": "
1247 << gIBaseFqName.getInterfaceStubFqName().cppName()
1248 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001249 }
1250
1251 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001252 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001253 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001254 << "\") { \n";
1255 out.indent();
1256 out << "_hidl_mImpl = _hidl_impl;\n";
Martijn Coenenb4d77952017-05-03 13:44:29 -07001257 out << "auto prio = ::android::hardware::details::gServicePrioMap.get("
1258 << "_hidl_impl, {SCHED_NORMAL, 0});\n";
1259 out << "mSchedPolicy = prio.sched_policy;\n";
1260 out << "mSchedPriority = prio.prio;\n";
Steven Moreland549499f2019-01-09 18:00:46 -08001261 out << "setRequestingSid(::android::hardware::details::gServiceSidMap.get(_hidl_impl, false));\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001262 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001263
1264 out.unindent();
1265 out.unindent();
1266 out << "}\n\n";
1267
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001268 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001269 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001270 // class properly.
1271 out << klassName
1272 << "::"
1273 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001274 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1275 << " const std::string &HidlInstrumentor_package,"
1276 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001277
1278 out.indent();
1279 out.indent();
1280
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001281 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001282 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001283 out.indent();
1284 out << "_hidl_mImpl = _hidl_impl;\n";
1285 out.unindent();
1286
1287 out.unindent();
1288 out.unindent();
1289 out << "}\n\n";
1290 }
1291
Steven Moreland57a89362017-07-21 19:29:54 +00001292 out << klassName << "::~" << klassName << "() ";
1293 out.block([&]() {
Martijn Coenence6fd192017-07-27 13:24:34 +02001294 out << "::android::hardware::details::gBnMap.eraseIfEqual(_hidl_mImpl.get(), this);\n";
Steven Moreland57a89362017-07-21 19:29:54 +00001295 }).endl().endl();
1296
Steven Moreland368e4602018-02-16 14:21:49 -08001297 generateMethods(out,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001298 [&](const Method* method, const Interface* superInterface) {
1299 return generateStaticStubMethodSource(out, iface->fqName(), method, superInterface);
Steven Moreland368e4602018-02-16 14:21:49 -08001300 },
1301 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -07001302
Steven Moreland368e4602018-02-16 14:21:49 -08001303 generateMethods(out, [&](const Method* method, const Interface*) {
Yifan Hongbcffce22017-02-01 15:52:06 -08001304 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001305 return;
Yifan Hongbcffce22017-02-01 15:52:06 -08001306 }
1307 method->generateCppSignature(out, iface->getStubName());
1308 out << " ";
1309 out.block([&] {
1310 method->cppImpl(IMPL_STUB_IMPL, out);
1311 }).endl();
Yifan Hongbcffce22017-02-01 15:52:06 -08001312 });
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001313
Andreas Huber881227d2016-08-02 14:20:21 -07001314 out << "::android::status_t " << klassName << "::onTransact(\n";
1315
1316 out.indent();
1317 out.indent();
1318
Iliyan Malchev549e2592016-08-10 08:59:12 -07001319 out << "uint32_t _hidl_code,\n"
1320 << "const ::android::hardware::Parcel &_hidl_data,\n"
1321 << "::android::hardware::Parcel *_hidl_reply,\n"
1322 << "uint32_t _hidl_flags,\n"
1323 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001324
1325 out.unindent();
1326
Iliyan Malchev549e2592016-08-10 08:59:12 -07001327 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001328 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001329 out.indent();
1330
Yifan Hong10fe0b52016-10-19 14:20:17 -07001331 for (const auto &tuple : iface->allMethodsFromRoot()) {
1332 const Method *method = tuple.method();
1333 const Interface *superInterface = tuple.interface();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001334
Howard Chen71f289f2017-08-29 17:35:01 +08001335 if (!isIBase() && method->isHidlReserved()) {
1336 continue;
1337 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001338 out << "case "
1339 << method->getSerialId()
1340 << " /* "
1341 << method->name()
1342 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001343
Yifan Hong10fe0b52016-10-19 14:20:17 -07001344 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001345
Steven Moreland77943692018-08-09 12:53:42 -07001346 out << "bool _hidl_is_oneway = _hidl_flags & " << Interface::FLAG_ONE_WAY->cppValue()
1347 << ";\n";
Steven Morelandebd8c722017-11-03 14:47:32 -07001348 out << "if (_hidl_is_oneway != " << (method->isOneway() ? "true" : "false") << ") ";
1349 out.block([&] { out << "return ::android::UNKNOWN_ERROR;\n"; }).endl().endl();
1350
Steven Moreland368e4602018-02-16 14:21:49 -08001351 generateStubSourceForMethod(out, method, superInterface);
Yifan Hong10fe0b52016-10-19 14:20:17 -07001352
1353 out.unindent();
1354 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001355 }
1356
1357 out << "default:\n{\n";
1358 out.indent();
1359
Martijn Coenen225bc922017-06-27 14:39:46 -07001360 if (iface->isIBase()) {
1361 out << "(void)_hidl_flags;\n";
1362 out << "return ::android::UNKNOWN_TRANSACTION;\n";
1363 } else {
1364 out << "return ";
1365 out << gIBaseFqName.getInterfaceStubFqName().cppName();
1366 out << "::onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001367
Martijn Coenen225bc922017-06-27 14:39:46 -07001368 out.indent();
1369 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001370
Martijn Coenen225bc922017-06-27 14:39:46 -07001371 out << "_hidl_code, _hidl_data, _hidl_reply, "
1372 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001373
Martijn Coenen225bc922017-06-27 14:39:46 -07001374 out.unindent();
1375 out.unindent();
1376 }
Andreas Huber881227d2016-08-02 14:20:21 -07001377
1378 out.unindent();
1379 out << "}\n";
1380
1381 out.unindent();
1382 out << "}\n\n";
1383
Yifan Honga018ed52016-12-13 16:35:08 -08001384 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1385 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1386 out.indent(2, [&] {
1387 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1388 out << "_hidl_reply);\n";
1389 });
1390 });
Andreas Huber881227d2016-08-02 14:20:21 -07001391
Iliyan Malchev549e2592016-08-10 08:59:12 -07001392 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001393
1394 out.unindent();
1395 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001396}
1397
Steven Moreland368e4602018-02-16 14:21:49 -08001398void AST::generateStubSourceForMethod(Formatter& out, const Method* method,
1399 const Interface* superInterface) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001400 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1401 method->cppImpl(IMPL_STUB, out);
1402 out << "break;\n";
Steven Moreland368e4602018-02-16 14:21:49 -08001403 return;
Martijn Coenen115d4282016-12-19 05:14:04 +01001404 }
1405
Steven Morelandf16c5c02017-07-31 16:50:06 -07001406 out << "_hidl_err = "
1407 << superInterface->fqName().cppNamespace()
1408 << "::"
1409 << superInterface->getStubName()
1410 << "::_hidl_"
1411 << method->name()
1412 << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
1413 out << "break;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001414}
1415
Steven Moreland368e4602018-02-16 14:21:49 -08001416void AST::generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001417 const Method* method, const Interface* superInterface) const {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001418 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001419 return;
Steven Morelandf16c5c02017-07-31 16:50:06 -07001420 }
1421
Steven Morelandf8197902018-01-30 15:38:37 -08001422 const std::string& klassName = fqName.getInterfaceStubName();
1423
Steven Morelandf16c5c02017-07-31 16:50:06 -07001424 out << "::android::status_t " << klassName << "::_hidl_" << method->name() << "(\n";
1425
1426 out.indent();
1427 out.indent();
1428
1429 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
1430 << "const ::android::hardware::Parcel &_hidl_data,\n"
1431 << "::android::hardware::Parcel *_hidl_reply,\n"
1432 << "TransactCallback _hidl_cb) {\n";
1433
1434 out.unindent();
1435
1436 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1437 out << "bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();\n";
1438 out << "const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();\n";
1439 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1440
1441 out << "::android::status_t _hidl_err = ::android::OK;\n";
1442
Yifan Hongeefe4f22017-01-04 15:32:42 -08001443 out << "if (!_hidl_data.enforceInterface("
Steven Morelandf16c5c02017-07-31 16:50:06 -07001444 << klassName
1445 << "::Pure::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001446
Andreas Huber881227d2016-08-02 14:20:21 -07001447 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001448 out << "_hidl_err = ::android::BAD_TYPE;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001449 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001450 out.unindent();
1451 out << "}\n\n";
1452
Andreas Huber5e44a292016-09-27 14:52:39 -07001453 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001454
Yifan Hongbf459bc2016-08-23 16:50:37 -07001455 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001456 for (const auto &arg : method->args()) {
1457 emitCppReaderWriter(
1458 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001459 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001460 false /* parcelObjIsPointer */,
1461 arg,
1462 true /* reader */,
Steven Morelandf16c5c02017-07-31 16:50:06 -07001463 Type::ErrorMode_Return,
Andreas Huber5e44a292016-09-27 14:52:39 -07001464 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001465 }
1466
Yifan Hongbf459bc2016-08-23 16:50:37 -07001467 // Second DFS: resolve references
1468 for (const auto &arg : method->args()) {
1469 emitCppResolveReferences(
1470 out,
1471 "_hidl_data",
1472 false /* parcelObjIsPointer */,
1473 arg,
1474 true /* reader */,
Steven Morelandf16c5c02017-07-31 16:50:06 -07001475 Type::ErrorMode_Return,
Yifan Hongbf459bc2016-08-23 16:50:37 -07001476 false /* addPrefixToName */);
1477 }
1478
Steven Moreland92a08a72017-07-31 14:57:37 -07001479 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001480 out,
1481 InstrumentationEvent::SERVER_API_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001482 method,
1483 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001484
Andreas Huber881227d2016-08-02 14:20:21 -07001485 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001486 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland3e787002017-08-16 14:59:54 -07001487
1488 std::string callee;
1489
1490 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL)) {
1491 callee = "_hidl_this";
1492 } else {
Steven Morelandf8197902018-01-30 15:38:37 -08001493 callee = "static_cast<" + fqName.getInterfaceName() + "*>(_hidl_this->getImpl().get())";
Steven Moreland3e787002017-08-16 14:59:54 -07001494 }
Andreas Huber881227d2016-08-02 14:20:21 -07001495
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001496 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001497 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001498 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001499 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001500 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001501 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001502 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001503
Yifan Hong932464e2017-03-30 15:40:22 -07001504 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001505 if (arg->type().resultNeedsDeref()) {
1506 out << "*";
1507 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001508 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001509 });
Andreas Huber881227d2016-08-02 14:20:21 -07001510
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001511 out << ");\n\n";
Yifan Hong859e53f2016-11-14 19:08:24 -08001512 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1513 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001514
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001515 elidedReturn->type().emitReaderWriter(
1516 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001517 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001518 "_hidl_reply",
1519 true, /* parcelObjIsPointer */
1520 false, /* isReader */
1521 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001522
Yifan Hongbf459bc2016-08-23 16:50:37 -07001523 emitCppResolveReferences(
1524 out,
1525 "_hidl_reply",
1526 true /* parcelObjIsPointer */,
1527 elidedReturn,
1528 false /* reader */,
1529 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001530 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001531
Steven Moreland92a08a72017-07-31 14:57:37 -07001532 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001533 out,
1534 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001535 method,
1536 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001537
Iliyan Malchev549e2592016-08-10 08:59:12 -07001538 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001539 } else {
1540 if (returnsValue) {
1541 out << "bool _hidl_callbackCalled = false;\n\n";
1542 }
Andreas Huber881227d2016-08-02 14:20:21 -07001543
Yifan Hongcd2ae452017-01-31 14:33:40 -08001544 out << callee << "->" << method->name() << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001545
Yifan Hong932464e2017-03-30 15:40:22 -07001546 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001547 if (arg->type().resultNeedsDeref()) {
1548 out << "*";
1549 }
1550
1551 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001552 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001553
1554 if (returnsValue) {
Yifan Hong932464e2017-03-30 15:40:22 -07001555 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001556 out << ", ";
1557 }
1558
1559 out << "[&](";
1560
Yifan Hong932464e2017-03-30 15:40:22 -07001561 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001562 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001563 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001564
1565 out << ") {\n";
1566 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001567 out << "if (_hidl_callbackCalled) {\n";
1568 out.indent();
1569 out << "LOG_ALWAYS_FATAL(\""
1570 << method->name()
1571 << ": _hidl_cb called a second time, but must be called once.\");\n";
1572 out.unindent();
1573 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001574 out << "_hidl_callbackCalled = true;\n\n";
1575
Yifan Hong859e53f2016-11-14 19:08:24 -08001576 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1577 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001578
Yifan Hongbf459bc2016-08-23 16:50:37 -07001579 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001580 for (const auto &arg : method->results()) {
1581 emitCppReaderWriter(
1582 out,
1583 "_hidl_reply",
1584 true /* parcelObjIsPointer */,
1585 arg,
1586 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001587 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001588 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001589 }
1590
Yifan Hongbf459bc2016-08-23 16:50:37 -07001591 // Second DFS: resolve references
1592 for (const auto &arg : method->results()) {
1593 emitCppResolveReferences(
1594 out,
1595 "_hidl_reply",
1596 true /* parcelObjIsPointer */,
1597 arg,
1598 false /* reader */,
1599 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001600 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001601 }
1602
Steven Moreland92a08a72017-07-31 14:57:37 -07001603 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001604 out,
1605 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001606 method,
1607 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001608
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001609 out << "_hidl_cb(*_hidl_reply);\n";
1610
1611 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001612 out << "});\n\n";
1613 } else {
1614 out << ");\n\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001615 out << "(void) _hidl_cb;\n\n";
Steven Moreland92a08a72017-07-31 14:57:37 -07001616 generateCppInstrumentationCall(
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001617 out,
1618 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001619 method,
1620 superInterface);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001621 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001622
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001623 if (returnsValue) {
1624 out << "if (!_hidl_callbackCalled) {\n";
1625 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001626 out << "LOG_ALWAYS_FATAL(\""
1627 << method->name()
1628 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001629 out.unindent();
1630 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001631 } else {
1632 out << "::android::hardware::writeToParcel("
1633 << "::android::hardware::Status::ok(), "
1634 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001635 }
Andreas Huber881227d2016-08-02 14:20:21 -07001636 }
1637
Steven Morelandf16c5c02017-07-31 16:50:06 -07001638 out << "return _hidl_err;\n";
1639 out.unindent();
1640 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001641}
1642
Steven Moreland368e4602018-02-16 14:21:49 -08001643void AST::generatePassthroughHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -07001644 if (!AST::isInterface()) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001645 // types.hal does not get a stub header.
Steven Moreland368e4602018-02-16 14:21:49 -08001646 return;
Steven Moreland69e7c702016-09-09 11:16:32 -07001647 }
1648
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001649 const Interface* iface = mRootScope.getInterface();
Steven Moreland19f11b52017-05-12 18:22:21 -07001650 CHECK(iface != nullptr);
Steven Moreland69e7c702016-09-09 11:16:32 -07001651
Yifan Hongeefe4f22017-01-04 15:32:42 -08001652 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001653
1654 bool supportOneway = iface->hasOnewayMethods();
1655
Steven Moreland69e7c702016-09-09 11:16:32 -07001656 const std::string guard = makeHeaderGuard(klassName);
1657
1658 out << "#ifndef " << guard << "\n";
1659 out << "#define " << guard << "\n\n";
1660
1661 std::vector<std::string> packageComponents;
1662 getPackageAndVersionComponents(
1663 &packageComponents, false /* cpp_compatible */);
1664
Steven Moreland61d3f4b2017-04-28 17:30:38 -07001665 out << "#include <android-base/macros.h>\n";
Yifan Hongb0949432016-12-15 15:32:24 -08001666 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001667 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001668
Steven Moreland19f11b52017-05-12 18:22:21 -07001669 generateCppPackageInclude(out, mPackage, iface->localName());
Steven Morelandee88eed2016-10-31 17:49:00 -07001670 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001671
Yifan Hong7a118f52016-12-07 11:21:15 -08001672 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001673 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001674 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001675 }
1676
1677 enterLeaveNamespace(out, true /* enter */);
1678 out << "\n";
1679
1680 out << "struct "
1681 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -07001682 << " : " << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001683 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001684
1685 out.indent();
1686 out << "explicit "
1687 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001688 << "(const ::android::sp<"
Steven Moreland19f11b52017-05-12 18:22:21 -07001689 << iface->localName()
Steven Moreland69e7c702016-09-09 11:16:32 -07001690 << "> impl);\n";
1691
Steven Moreland0b843772017-06-23 16:33:38 -07001692 out.endl();
1693 generateTemplatizationLink(out);
Steven Moreland1a52e822017-07-27 13:56:29 -07001694 generateCppTag(out, "android::hardware::details::bs_tag");
Steven Moreland0b843772017-06-23 16:33:38 -07001695
Steven Moreland616cf4d2018-10-02 13:52:18 -07001696 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1697 generatePassthroughMethod(out, method, superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001698 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001699
Steven Moreland69e7c702016-09-09 11:16:32 -07001700 out.unindent();
1701 out << "private:\n";
1702 out.indent();
Steven Moreland19f11b52017-05-12 18:22:21 -07001703 out << "const ::android::sp<" << iface->localName() << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001704
1705 if (supportOneway) {
Yifan Hongef91d362017-03-20 17:18:13 -07001706 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001707
1708 out << "\n";
1709
1710 out << "::android::hardware::Return<void> addOnewayTask("
1711 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001712 }
1713
1714 out.unindent();
1715
1716 out << "};\n\n";
1717
1718 enterLeaveNamespace(out, false /* enter */);
1719
1720 out << "\n#endif // " << guard << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001721}
1722
Steven Moreland368e4602018-02-16 14:21:49 -08001723void AST::generateInterfaceSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001724 const Interface* iface = mRootScope.getInterface();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001725
Yifan Hong2d7126b2016-10-20 15:12:57 -07001726 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001727 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001728
Steven Moreland368e4602018-02-16 14:21:49 -08001729 generateMethods(out, [&](const Method* method, const Interface*) {
Steven Morelandd4b068a2017-03-20 06:30:51 -07001730 bool reserved = method->isHidlReserved();
1731
1732 if (!reserved) {
1733 out << "// no default implementation for: ";
1734 }
1735 method->generateCppSignature(out, iface->localName());
1736 if (reserved) {
1737 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001738 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001739 }).endl();
1740 }
1741
1742 out << "\n";
1743
Steven Moreland368e4602018-02-16 14:21:49 -08001744 return;
Steven Morelandd4b068a2017-03-20 06:30:51 -07001745 });
Steven Morelandd4b068a2017-03-20 06:30:51 -07001746
Yifan Hong3d746092016-12-07 14:26:33 -08001747 for (const Interface *superType : iface->typeChain()) {
Steven Moreland23cc5fa2018-05-09 10:48:48 -07001748 out << "::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -08001749 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -07001750 << "> "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001751 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001752 << "::castFrom("
1753 << superType->getCppArgumentType()
Yifan Hong200209c2017-03-29 03:39:09 -07001754 << " parent, bool "
1755 << (iface == superType ? "/* emitError */" : "emitError")
1756 << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001757 out.indent();
1758 if (iface == superType) {
1759 out << "return parent;\n";
1760 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001761 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001762 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001763 << superType->fqName().cppName() << ", "
Steven Moreland57a89362017-07-21 19:29:54 +00001764 << iface->getProxyName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001765 << ">(\n";
1766 out.indent();
1767 out.indent();
1768 out << "parent, \""
1769 << iface->fqName().string()
Yifan Hong200209c2017-03-29 03:39:09 -07001770 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001771 out.unindent();
1772 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001773 }
Yifan Hong3d746092016-12-07 14:26:33 -08001774 out.unindent();
1775 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001776 }
Yifan Hongfe95aa22016-10-19 17:26:45 -07001777}
1778
Steven Moreland368e4602018-02-16 14:21:49 -08001779void AST::generatePassthroughSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001780 const Interface* iface = mRootScope.getInterface();
Steven Moreland69e7c702016-09-09 11:16:32 -07001781
Yifan Hongeefe4f22017-01-04 15:32:42 -08001782 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001783
1784 out << klassName
1785 << "::"
1786 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001787 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001788 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001789 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001790 << mPackage.string()
1791 << "\", \""
1792 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001793 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001794 if (iface->hasOnewayMethods()) {
1795 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001796 out.indent([&] {
Yifan Hongf01dad42017-03-20 19:03:11 -07001797 out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001798 });
1799 }
1800 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001801
1802 if (iface->hasOnewayMethods()) {
1803 out << "::android::hardware::Return<void> "
1804 << klassName
1805 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1806 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001807 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001808 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001809 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1810 out.indent();
1811 out.indent();
Steven Moreland610002f2017-06-16 13:02:49 -07001812 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
1813 << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
Steven Moreland67f67b42016-09-29 08:59:02 -07001814 out.unindent();
1815 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001816 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001817 out << "}\n";
1818
Steven Morelandd366c262016-10-11 15:29:10 -07001819 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001820
1821 out.unindent();
1822 out << "}\n\n";
1823
1824
1825 }
Steven Moreland69e7c702016-09-09 11:16:32 -07001826}
1827
Steven Moreland92a08a72017-07-31 14:57:37 -07001828void AST::generateCppAtraceCall(Formatter &out,
Martijn Coenen7b295242016-11-04 16:52:56 +01001829 InstrumentationEvent event,
1830 const Method *method) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001831 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001832 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001833 switch (event) {
1834 case SERVER_API_ENTRY:
1835 {
1836 out << "atrace_begin(ATRACE_TAG_HAL, \""
1837 << baseString + "::server\");\n";
1838 break;
1839 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001840 case PASSTHROUGH_ENTRY:
1841 {
1842 out << "atrace_begin(ATRACE_TAG_HAL, \""
1843 << baseString + "::passthrough\");\n";
1844 break;
1845 }
1846 case SERVER_API_EXIT:
Martijn Coenen7b295242016-11-04 16:52:56 +01001847 case PASSTHROUGH_EXIT:
1848 {
1849 out << "atrace_end(ATRACE_TAG_HAL);\n";
1850 break;
1851 }
Steven Moreland4607ef52018-05-09 10:52:47 -07001852 // client uses scope because of gotos
1853 // this isn't done for server because the profiled code isn't alone in its scope
1854 // this isn't done for passthrough becuase the profiled boundary isn't even in the same code
1855 case CLIENT_API_ENTRY: {
Michael Butler0a3d99a2018-07-26 13:47:10 -07001856 out << "::android::ScopedTrace PASTE(___tracer, __LINE__) (ATRACE_TAG_HAL, \""
1857 << baseString + "::client\");\n";
Steven Moreland4607ef52018-05-09 10:52:47 -07001858 break;
1859 }
1860 case CLIENT_API_EXIT:
1861 break;
Martijn Coenen7b295242016-11-04 16:52:56 +01001862 default:
1863 {
Steven Morelandcbff5612017-10-11 17:01:54 -07001864 CHECK(false) << "Unsupported instrumentation event: " << event;
Martijn Coenen7b295242016-11-04 16:52:56 +01001865 }
1866 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001867}
1868
Steven Moreland92a08a72017-07-31 14:57:37 -07001869void AST::generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001870 Formatter &out,
1871 InstrumentationEvent event,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001872 const Method *method,
1873 const Interface* superInterface) const {
Steven Moreland92a08a72017-07-31 14:57:37 -07001874 generateCppAtraceCall(out, event, method);
Martijn Coenen7b295242016-11-04 16:52:56 +01001875
Steven Moreland30b76e92017-06-02 18:52:24 -07001876 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001877 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1878 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001879 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001880 std::string event_str = "";
1881 switch (event) {
1882 case SERVER_API_ENTRY:
1883 {
1884 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1885 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001886 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001887 << (arg->type().resultNeedsDeref() ? "" : "&")
1888 << arg->name()
1889 << ");\n";
1890 }
1891 break;
1892 }
1893 case SERVER_API_EXIT:
1894 {
1895 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001896 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001897 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001898 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001899 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001900 }
1901 break;
1902 }
1903 case CLIENT_API_ENTRY:
1904 {
1905 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1906 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001907 out << "_hidl_args.push_back((void *)&"
1908 << arg->name()
1909 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001910 }
1911 break;
1912 }
1913 case CLIENT_API_EXIT:
1914 {
1915 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
1916 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001917 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001918 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001919 << "_hidl_out_"
1920 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001921 << ");\n";
1922 }
1923 break;
1924 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001925 case PASSTHROUGH_ENTRY:
1926 {
1927 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
1928 for (const auto &arg : method->args()) {
1929 out << "_hidl_args.push_back((void *)&"
1930 << arg->name()
1931 << ");\n";
1932 }
1933 break;
1934 }
1935 case PASSTHROUGH_EXIT:
1936 {
1937 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001938 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001939 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08001940 << arg->name()
1941 << ");\n";
1942 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001943 break;
1944 }
Steven Moreland031ccf12016-10-31 15:54:38 -07001945 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001946 {
Steven Morelandcbff5612017-10-11 17:01:54 -07001947 CHECK(false) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001948 }
1949 }
1950
Steven Moreland1ab31442016-11-03 18:37:51 -07001951 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001952 out.indent();
1953 out << "callback("
1954 << event_str
1955 << ", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07001956 << superInterface->fqName().package()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001957 << "\", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07001958 << superInterface->fqName().version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001959 << "\", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07001960 << superInterface->localName()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001961 << "\", \""
1962 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001963 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001964 out.unindent();
1965 out << "}\n";
1966 out.unindent();
Steven Moreland30b76e92017-06-02 18:52:24 -07001967 out << "}\n";
1968 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001969}
1970
Andreas Huber881227d2016-08-02 14:20:21 -07001971} // namespace android