blob: 2b70cac02a33c5b8b2b78f740acacf28ea0ed411 [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
Steven Moreland7645fbd2019-03-12 18:49:28 -0700106 if (isTry) {
107 DocComment(
108 "This gets the service of this type with the specified instance name. If the\n"
109 "service is currently not available or not in the VINTF manifest on a Trebilized\n"
110 "device, this will return nullptr. This is useful when you don't want to block\n"
111 "during device boot. If getStub is true, this will try to return an unwrapped\n"
112 "passthrough implementation in the same process. This is useful when getting an\n"
113 "implementation from the same partition/compilation group.\n\n"
114 "In general, prefer getService(std::string,bool)")
115 .emit(out);
116 } else {
117 DocComment(
118 "This gets the service of this type with the specified instance name. If the\n"
119 "service is not in the VINTF manifest on a Trebilized device, this will return\n"
120 "nullptr. If the service is not available, this will wait for the service to\n"
121 "become available. If the service is a lazy service, this will start the service\n"
122 "and return when it becomes available. If getStub is true, this will try to\n"
123 "return an unwrapped passthrough implementation in the same process. This is\n"
124 "useful when getting an implementation from the same partition/compilation group.")
125 .emit(out);
126 }
Steven Moreland038903b2017-03-30 12:11:24 -0700127 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800128 << "const std::string &serviceName=\"default\", bool getStub=false);\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700129 DocComment("Deprecated. See " + functionName + "(std::string, bool)").emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700130 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800131 << "const char serviceName[], bool getStub=false)"
132 << " { std::string str(serviceName ? serviceName : \"\");"
Steven Moreland038903b2017-03-30 12:11:24 -0700133 << " return " << functionName << "(str, getStub); }\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700134 DocComment("Deprecated. See " + functionName + "(std::string, bool)").emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700135 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
Chris Phoenixdb0d6342017-01-11 16:10:00 -0800136 << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
137 // without c_str the std::string constructor is ambiguous
138 << " { std::string str(serviceName.c_str());"
Steven Moreland038903b2017-03-30 12:11:24 -0700139 << " return " << functionName << "(str, getStub); }\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700140 DocComment("Calls " + functionName +
141 "(\"default\", bool). This is the recommended instance name for singleton services.")
142 .emit(out);
Steven Moreland038903b2017-03-30 12:11:24 -0700143 out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
144 << "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
145}
146
147static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
148 declareGetService(out, interfaceName, true /* isTry */);
149 declareGetService(out, interfaceName, false /* isTry */);
150
Steven Moreland7645fbd2019-03-12 18:49:28 -0700151 DocComment(
152 "Registers a service with the service manager. For Trebilized devices, the service\n"
153 "must also be in the VINTF manifest.")
154 .emit(out);
Steven Moreland90831502017-03-27 12:08:40 -0700155 out << "__attribute__ ((warn_unused_result))"
156 << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
Steven Moreland7645fbd2019-03-12 18:49:28 -0700157 DocComment("Registers for notifications for when a service is registered.").emit(out);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800158 out << "static bool registerForNotifications(\n";
159 out.indent(2, [&] {
160 out << "const std::string &serviceName,\n"
161 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
162 << "&notification);\n";
163 });
164
165}
166
Steven Moreland038903b2017-03-30 12:11:24 -0700167static void implementGetService(Formatter &out,
168 const FQName &fqName,
169 bool isTry) {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800170
171 const std::string interfaceName = fqName.getInterfaceName();
Steven Moreland038903b2017-03-30 12:11:24 -0700172 const std::string functionName = isTry ? "tryGetService" : "getService";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800173
Steven Moreland23cc5fa2018-05-09 10:48:48 -0700174 out << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
Yifan Hong31f07ff2017-03-21 18:56:35 +0000175 << "const std::string &serviceName, const bool getStub) ";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800176 out.block([&] {
Steven Moreland78f95f92017-10-06 17:07:40 -0700177 out << "return ::android::hardware::details::getServiceInternal<"
178 << fqName.getInterfaceProxyName()
179 << ">(serviceName, "
180 << (!isTry ? "true" : "false") // retry
181 << ", getStub);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800182 }).endl().endl();
Steven Moreland038903b2017-03-30 12:11:24 -0700183}
184
185static void implementServiceManagerInteractions(Formatter &out,
186 const FQName &fqName, const std::string &package) {
187
188 const std::string interfaceName = fqName.getInterfaceName();
189
190 implementGetService(out, fqName, true /* isTry */);
191 implementGetService(out, fqName, false /* isTry */);
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800192
Yifan Hongeefe4f22017-01-04 15:32:42 -0800193 out << "::android::status_t " << interfaceName << "::registerAsService("
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800194 << "const std::string &serviceName) ";
195 out.block([&] {
Steven Moreland5f84b382018-10-11 12:10:35 -0700196 out << "return ::android::hardware::details::registerAsServiceInternal(this, serviceName);\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800197 }).endl().endl();
198
Yifan Hongeefe4f22017-01-04 15:32:42 -0800199 out << "bool " << interfaceName << "::registerForNotifications(\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800200 out.indent(2, [&] {
201 out << "const std::string &serviceName,\n"
202 << "const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification> "
203 << "&notification) ";
204 });
205 out.block([&] {
206 out << "const ::android::sp<::android::hidl::manager::V1_0::IServiceManager> sm\n";
207 out.indent(2, [&] {
208 out << "= ::android::hardware::defaultServiceManager();\n";
209 });
210 out.sIf("sm == nullptr", [&] {
211 out << "return false;\n";
212 }).endl();
213 out << "::android::hardware::Return<bool> success =\n";
214 out.indent(2, [&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800215 out << "sm->registerForNotifications(\"" << package << "::" << interfaceName << "\",\n";
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800216 out.indent(2, [&] {
217 out << "serviceName, notification);\n";
218 });
219 });
220 out << "return success.isOk() && success;\n";
221 }).endl().endl();
222}
223
Steven Moreland368e4602018-02-16 14:21:49 -0800224void AST::generateInterfaceHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700225 const Interface *iface = getInterface();
226 std::string ifaceName = iface ? iface->localName() : "types";
Andreas Huber881227d2016-08-02 14:20:21 -0700227 const std::string guard = makeHeaderGuard(ifaceName);
228
229 out << "#ifndef " << guard << "\n";
230 out << "#define " << guard << "\n\n";
231
Andreas Huber737080b2016-08-02 15:38:04 -0700232 for (const auto &item : mImportedNames) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700233 generateCppPackageInclude(out, item, item.name());
Andreas Huber737080b2016-08-02 15:38:04 -0700234 }
235
236 if (!mImportedNames.empty()) {
237 out << "\n";
238 }
239
Steven Moreland19f11b52017-05-12 18:22:21 -0700240 if (iface) {
Yifan Hongc8934042016-11-17 17:10:52 -0800241 if (isIBase()) {
242 out << "// skipped #include IServiceNotification.h\n\n";
243 } else {
244 out << "#include <android/hidl/manager/1.0/IServiceNotification.h>\n\n";
245 }
Steven Moreland0693f312016-11-09 15:06:14 -0800246 }
247
Yifan Hongc8934042016-11-17 17:10:52 -0800248 out << "#include <hidl/HidlSupport.h>\n";
Andreas Huber4bcf97d2016-08-30 11:27:49 -0700249 out << "#include <hidl/MQDescriptor.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700250
Steven Moreland19f11b52017-05-12 18:22:21 -0700251 if (iface) {
Martijn Coenen93915102016-09-01 01:35:52 +0200252 out << "#include <hidl/Status.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700253 }
254
Martijn Coenenaf712c02016-11-16 15:26:27 +0100255 out << "#include <utils/NativeHandle.h>\n";
256 out << "#include <utils/misc.h>\n\n"; /* for report_sysprop_change() */
Andreas Huber881227d2016-08-02 14:20:21 -0700257
258 enterLeaveNamespace(out, true /* enter */);
259 out << "\n";
260
Steven Moreland19f11b52017-05-12 18:22:21 -0700261 if (iface) {
Steven Moreland70cb55e2019-03-12 17:20:54 -0700262 iface->emitDocComment(out);
263
Andreas Huber881227d2016-08-02 14:20:21 -0700264 out << "struct "
Steven Moreland40786312016-08-16 10:29:40 -0700265 << ifaceName;
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700266
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700267 const Interface *superType = iface->superType();
268
Yi Kong56758da2018-07-24 16:21:37 -0700269 if (superType == nullptr) {
Yifan Hongc8934042016-11-17 17:10:52 -0800270 out << " : virtual public ::android::RefBase";
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700271 } else {
Steven Morelandd916a702016-10-26 22:23:09 +0000272 out << " : public "
Steven Moreland40786312016-08-16 10:29:40 -0700273 << superType->fullName();
Andreas Huber6cb08cf2016-08-03 15:44:51 -0700274 }
275
276 out << " {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700277
278 out.indent();
279
Steven Moreland7645fbd2019-03-12 18:49:28 -0700280 DocComment("Type tag for use in template logic that indicates this is a 'pure' class.")
281 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700282 generateCppTag(out, "android::hardware::details::i_tag");
Andreas Huber881227d2016-08-02 14:20:21 -0700283
Steven Moreland7645fbd2019-03-12 18:49:28 -0700284 DocComment("Fully qualified interface name: \"" + iface->fqName().string() + "\"")
285 .emit(out);
286 out << "static const char* descriptor;\n\n";
287
Steven Moreland70cb55e2019-03-12 17:20:54 -0700288 iface->emitTypeDeclarations(out);
289 } else {
290 mRootScope.emitTypeDeclarations(out);
291 }
Andreas Huber881227d2016-08-02 14:20:21 -0700292
Steven Moreland19f11b52017-05-12 18:22:21 -0700293 if (iface) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700294 DocComment(
295 "Returns whether this object's implementation is outside of the current process.")
296 .emit(out);
Yifan Hongc8934042016-11-17 17:10:52 -0800297 out << "virtual bool isRemote() const ";
298 if (!isIBase()) {
299 out << "override ";
300 }
Steven Moreland7645fbd2019-03-12 18:49:28 -0700301 out << "{ return false; }\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800302
Steven Morelandf7f2a9a2017-07-21 18:05:38 -0700303 for (const auto& tuple : iface->allMethodsFromRoot()) {
304 const Method* method = tuple.method();
305
Andreas Huber881227d2016-08-02 14:20:21 -0700306 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700307
Andreas Huber881227d2016-08-02 14:20:21 -0700308 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700309 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Morelandd732ea12016-11-08 17:12:06 -0800310
311 if (elidedReturn == nullptr && returnsValue) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700312 DocComment("Return callback for " + method->name()).emit(out);
Steven Morelandd732ea12016-11-08 17:12:06 -0800313 out << "using "
314 << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700315 << "_cb = std::function<void(";
316 method->emitCppResultSignature(out, true /* specify namespaces */);
317 out << ")>;\n";
Steven Morelandd732ea12016-11-08 17:12:06 -0800318 }
Andreas Huber881227d2016-08-02 14:20:21 -0700319
Andreas Huber3599d922016-08-09 10:42:57 -0700320 method->dumpAnnotations(out);
321
Steven Moreland49bad8d2018-05-17 15:45:26 -0700322 method->emitDocComment(out);
323
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700324 if (elidedReturn) {
Iliyan Malchev2b6591b2016-08-18 19:15:19 -0700325 out << "virtual ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -0700326 out << elidedReturn->type().getCppResultType() << "> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700327 } else {
Iliyan Malchevd57066f2016-09-08 13:59:38 -0700328 out << "virtual ::android::hardware::Return<void> ";
Iliyan Malchev40d474a2016-08-16 06:20:17 -0700329 }
330
331 out << method->name()
Yifan Hong932464e2017-03-30 15:40:22 -0700332 << "(";
333 method->emitCppArgSignature(out, true /* specify namespaces */);
Yifan Hong10fe0b52016-10-19 14:20:17 -0700334 out << ")";
335 if (method->isHidlReserved()) {
Yifan Hongc8934042016-11-17 17:10:52 -0800336 if (!isIBase()) {
337 out << " override";
338 }
Yifan Hong10fe0b52016-10-19 14:20:17 -0700339 } else {
Steven Morelandd4b068a2017-03-20 06:30:51 -0700340 out << " = 0";
Yifan Hong10fe0b52016-10-19 14:20:17 -0700341 }
Steven Morelandd4b068a2017-03-20 06:30:51 -0700342 out << ";\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700343 }
Steven Moreland40786312016-08-16 10:29:40 -0700344
Steven Moreland7645fbd2019-03-12 18:49:28 -0700345 out << "\n// cast static functions\n";
Yifan Hong3d746092016-12-07 14:26:33 -0800346 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -0700347
Yifan Hong3d746092016-12-07 14:26:33 -0800348 for (const Interface *superType : iface->typeChain()) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700349 DocComment(
350 "This performs a checked cast based on what the underlying implementation "
351 "actually is.")
352 .emit(out);
Yifan Hong200209c2017-03-29 03:39:09 -0700353 out << "static ::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -0800354 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -0700355 << "> castFrom("
Yifan Hong3d746092016-12-07 14:26:33 -0800356 << superType->getCppArgumentType()
357 << " parent"
Yifan Hong200209c2017-03-29 03:39:09 -0700358 << ", bool emitError = false);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -0700359 }
360
Yifan Hongc8934042016-11-17 17:10:52 -0800361 if (isIBase()) {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700362 out << "\n// skipped getService, registerAsService, registerForNotifications\n\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800363 } else {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700364 out << "\n// helper methods for interactions with the hwservicemanager\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800365 declareServiceManagerInteractions(out, iface->localName());
Yifan Hongc8934042016-11-17 17:10:52 -0800366 }
Andreas Huber881227d2016-08-02 14:20:21 -0700367 }
368
Steven Moreland19f11b52017-05-12 18:22:21 -0700369 if (iface) {
Andreas Huber881227d2016-08-02 14:20:21 -0700370 out.unindent();
371
Andreas Hubere3f769a2016-10-10 10:54:44 -0700372 out << "};\n\n";
373 }
374
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700375 out << "//\n";
376 out << "// type declarations for package\n";
377 out << "//\n\n";
Steven Moreland368e4602018-02-16 14:21:49 -0800378 mRootScope.emitPackageTypeDeclarations(out);
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700379 out << "//\n";
380 out << "// type header definitions for package\n";
381 out << "//\n\n";
382 mRootScope.emitPackageTypeHeaderDefinitions(out);
Andreas Huber881227d2016-08-02 14:20:21 -0700383
384 out << "\n";
385 enterLeaveNamespace(out, false /* enter */);
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700386 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700387
Steven Moreland09c6ebe2018-10-09 10:15:48 -0700388 out << "//\n";
389 out << "// global type declarations for package\n";
390 out << "//\n\n";
Steven Moreland8e61c5a2017-11-17 15:55:28 -0800391 mRootScope.emitGlobalTypeDeclarations(out);
392
Andreas Huber881227d2016-08-02 14:20:21 -0700393 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700394}
395
Steven Moreland368e4602018-02-16 14:21:49 -0800396void AST::generateHwBinderHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700397 const Interface *iface = getInterface();
398 std::string klassName = iface ? iface->getHwName() : "hwtypes";
Steven Moreland40786312016-08-16 10:29:40 -0700399
Steven Moreland40786312016-08-16 10:29:40 -0700400 const std::string guard = makeHeaderGuard(klassName);
401
402 out << "#ifndef " << guard << "\n";
403 out << "#define " << guard << "\n\n";
404
Steven Moreland19f11b52017-05-12 18:22:21 -0700405 generateCppPackageInclude(out, mPackage, iface ? iface->localName() : "types");
Steven Moreland40786312016-08-16 10:29:40 -0700406
Steven Morelandee88eed2016-10-31 17:49:00 -0700407 out << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700408
409 for (const auto &item : mImportedNames) {
410 if (item.name() == "types") {
Yifan Hong244e82d2016-11-11 11:13:57 -0800411 generateCppPackageInclude(out, item, "hwtypes");
412 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800413 generateCppPackageInclude(out, item, item.getInterfaceStubName());
414 generateCppPackageInclude(out, item, item.getInterfaceProxyName());
Steven Moreland40786312016-08-16 10:29:40 -0700415 }
Steven Moreland40786312016-08-16 10:29:40 -0700416 }
417
418 out << "\n";
419
Martijn Coenen93915102016-09-01 01:35:52 +0200420 out << "#include <hidl/Status.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700421 out << "#include <hwbinder/IBinder.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100422 out << "#include <hwbinder/Parcel.h>\n";
Steven Moreland40786312016-08-16 10:29:40 -0700423
424 out << "\n";
425
426 enterLeaveNamespace(out, true /* enter */);
Steven Moreland40786312016-08-16 10:29:40 -0700427
Steven Moreland368e4602018-02-16 14:21:49 -0800428 mRootScope.emitPackageHwDeclarations(out);
Steven Moreland40786312016-08-16 10:29:40 -0700429
430 enterLeaveNamespace(out, false /* enter */);
431
432 out << "\n#endif // " << guard << "\n";
Steven Moreland40786312016-08-16 10:29:40 -0700433}
434
Steven Moreland58a20c72018-10-09 12:30:51 -0700435static std::string wrapPassthroughArg(Formatter& out, const NamedReference<Type>* arg,
436 std::string name, std::function<void(void)> handleError) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800437 if (!arg->type().isInterface()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700438 return name;
Yifan Hong7a118f52016-12-07 11:21:15 -0800439 }
Steven Moreland58a20c72018-10-09 12:30:51 -0700440 std::string wrappedName = "_hidl_wrapped_" + name;
Yifan Hong7a118f52016-12-07 11:21:15 -0800441 const Interface &iface = static_cast<const Interface &>(arg->type());
442 out << iface.getCppStackType() << " " << wrappedName << ";\n";
443 // TODO(elsk): b/33754152 Should not wrap this if object is Bs*
444 out.sIf(name + " != nullptr && !" + name + "->isRemote()", [&] {
445 out << wrappedName
446 << " = "
Steven Morelandbff4bd22017-10-02 14:46:06 -0700447 << "::android::hardware::details::wrapPassthrough("
448 << name
449 << ");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800450 out.sIf(wrappedName + " == nullptr", [&] {
451 // Fatal error. Happens when the BsFoo class is not found in the binary
452 // or any dynamic libraries.
453 handleError();
454 }).endl();
455 }).sElse([&] {
456 out << wrappedName << " = " << name << ";\n";
457 }).endl().endl();
Steven Moreland58a20c72018-10-09 12:30:51 -0700458
459 return wrappedName;
Yifan Hong7a118f52016-12-07 11:21:15 -0800460}
461
Steven Moreland616cf4d2018-10-02 13:52:18 -0700462void AST::generatePassthroughMethod(Formatter& out, const Method* method, const Interface* superInterface) const {
Yifan Hong068c5522016-10-31 14:07:25 -0700463 method->generateCppSignature(out);
Steven Moreland69e7c702016-09-09 11:16:32 -0700464
Steven Moreland58a20c72018-10-09 12:30:51 -0700465 out << " override {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700466 out.indent();
467
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800468 if (method->isHidlReserved()
469 && method->overridesCppImpl(IMPL_PASSTHROUGH)) {
470 method->cppImpl(IMPL_PASSTHROUGH, out);
471 out.unindent();
472 out << "}\n\n";
Steven Moreland368e4602018-02-16 14:21:49 -0800473 return;
Zhuoyao Zhangdd85c5c2017-01-03 17:30:24 -0800474 }
475
Steven Moreland69e7c702016-09-09 11:16:32 -0700476 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700477 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland69e7c702016-09-09 11:16:32 -0700478
Steven Moreland67f67b42016-09-29 08:59:02 -0700479 if (returnsValue && elidedReturn == nullptr) {
480 generateCheckNonNull(out, "_hidl_cb");
481 }
482
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700483 generateCppInstrumentationCall(
484 out,
485 InstrumentationEvent::PASSTHROUGH_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700486 method,
487 superInterface);
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700488
Steven Moreland58a20c72018-10-09 12:30:51 -0700489 std::vector<std::string> wrappedArgNames;
Yifan Hong7a118f52016-12-07 11:21:15 -0800490 for (const auto &arg : method->args()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700491 std::string name = wrapPassthroughArg(out, arg, arg->name(), [&] {
Yifan Hong7a118f52016-12-07 11:21:15 -0800492 out << "return ::android::hardware::Status::fromExceptionCode(\n";
493 out.indent(2, [&] {
494 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800495 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800496 });
497 });
Steven Moreland58a20c72018-10-09 12:30:51 -0700498
499 wrappedArgNames.push_back(name);
Yifan Hong7a118f52016-12-07 11:21:15 -0800500 }
501
Steven Moreland58a20c72018-10-09 12:30:51 -0700502 out << "::android::hardware::Status _hidl_error = ::android::hardware::Status::ok();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700503 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700504
505 if (method->isOneway()) {
Steven Moreland836cb312017-06-05 17:25:55 -0700506 out << "addOnewayTask([mImpl = this->mImpl\n"
507 << "#ifdef __ANDROID_DEBUGGABLE__\n"
508 ", mEnableInstrumentation = this->mEnableInstrumentation, "
509 "mInstrumentationCallbacks = this->mInstrumentationCallbacks\n"
510 << "#endif // __ANDROID_DEBUGGABLE__\n";
Steven Moreland58a20c72018-10-09 12:30:51 -0700511 for (const std::string& arg : wrappedArgNames) {
512 out << ", " << arg;
Steven Moreland69e7c702016-09-09 11:16:32 -0700513 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700514 out << "] {\n";
515 out.indent();
Steven Moreland69e7c702016-09-09 11:16:32 -0700516 }
517
518 out << "mImpl->"
519 << method->name()
520 << "(";
521
Yifan Hong932464e2017-03-30 15:40:22 -0700522 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800523 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700524 });
Steven Moreland58a20c72018-10-09 12:30:51 -0700525
526 std::function<void(void)> kHandlePassthroughError = [&] {
527 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
528 out.indent(2, [&] {
529 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
530 << "\"Cannot wrap passthrough interface.\");\n";
531 });
532 };
533
Steven Moreland69e7c702016-09-09 11:16:32 -0700534 if (returnsValue && elidedReturn == nullptr) {
Steven Moreland340c8822017-05-02 14:41:49 -0700535 // never true if oneway since oneway methods don't return values
536
Steven Moreland69e7c702016-09-09 11:16:32 -0700537 if (!method->args().empty()) {
538 out << ", ";
539 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800540 out << "[&](";
Yifan Hong932464e2017-03-30 15:40:22 -0700541 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800542 out << "const auto &_hidl_out_"
543 << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700544 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800545
546 out << ") {\n";
547 out.indent();
Steven Moreland92a08a72017-07-31 14:57:37 -0700548 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800549 out,
550 InstrumentationEvent::PASSTHROUGH_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700551 method,
552 superInterface);
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800553
Steven Moreland58a20c72018-10-09 12:30:51 -0700554 std::vector<std::string> wrappedOutNames;
Yifan Hong7a118f52016-12-07 11:21:15 -0800555 for (const auto &arg : method->results()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700556 wrappedOutNames.push_back(
557 wrapPassthroughArg(out, arg, "_hidl_out_" + arg->name(), kHandlePassthroughError));
Yifan Hong7a118f52016-12-07 11:21:15 -0800558 }
559
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800560 out << "_hidl_cb(";
Steven Moreland58a20c72018-10-09 12:30:51 -0700561 out.join(wrappedOutNames.begin(), wrappedOutNames.end(), ", ",
562 [&](const std::string& arg) { out << arg; });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800563 out << ");\n";
564 out.unindent();
565 out << "});\n\n";
566 } else {
567 out << ");\n\n";
Steven Moreland30b76e92017-06-02 18:52:24 -0700568
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800569 if (elidedReturn != nullptr) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700570 const std::string outName = "_hidl_out_" + elidedReturn->name();
571
572 out << elidedReturn->type().getCppResultType() << " " << outName
573 << " = _hidl_return;\n";
574 out << "(void) " << outName << ";\n";
575
576 const std::string wrappedName =
577 wrapPassthroughArg(out, elidedReturn, outName, kHandlePassthroughError);
578
579 if (outName != wrappedName) {
580 // update the original value since it is used by generateCppInstrumentationCall
581 out << outName << " = " << wrappedName << ";\n\n";
582
583 // update the value to be returned
584 out << "_hidl_return = " << outName << "\n;";
585 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800586 }
Steven Moreland92a08a72017-07-31 14:57:37 -0700587 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800588 out,
589 InstrumentationEvent::PASSTHROUGH_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700590 method,
591 superInterface);
Steven Moreland69e7c702016-09-09 11:16:32 -0700592 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700593
594 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700595 out.unindent();
596 out << "});\n";
Steven Moreland58a20c72018-10-09 12:30:51 -0700597 } else {
598 out << "if (!_hidl_error.isOk()) return _hidl_error;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700599 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700600
601 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700602
603 out.unindent();
604 out << "}\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700605}
606
Steven Moreland368e4602018-02-16 14:21:49 -0800607void AST::generateMethods(Formatter& out, const MethodGenerator& gen, bool includeParent) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700608 const Interface* iface = mRootScope.getInterface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700609
Yifan Hong10fe0b52016-10-19 14:20:17 -0700610 const Interface *prevIterface = nullptr;
611 for (const auto &tuple : iface->allMethodsFromRoot()) {
612 const Method *method = tuple.method();
613 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700614
Steven Morelandf16c5c02017-07-31 16:50:06 -0700615 if (!includeParent && superInterface != iface) {
616 continue;
617 }
618
Yifan Hong10fe0b52016-10-19 14:20:17 -0700619 if(prevIterface != superInterface) {
620 if (prevIterface != nullptr) {
621 out << "\n";
622 }
623 out << "// Methods from "
624 << superInterface->fullName()
625 << " follow.\n";
626 prevIterface = superInterface;
627 }
Steven Moreland368e4602018-02-16 14:21:49 -0800628 gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700629 }
630
Yifan Hong10fe0b52016-10-19 14:20:17 -0700631 out << "\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700632}
633
Steven Moreland0b843772017-06-23 16:33:38 -0700634void AST::generateTemplatizationLink(Formatter& out) const {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700635 DocComment("The pure class is what this class wraps.").emit(out);
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700636 out << "typedef " << mRootScope.getInterface()->localName() << " Pure;\n\n";
Steven Moreland0b843772017-06-23 16:33:38 -0700637}
638
Steven Moreland1a52e822017-07-27 13:56:29 -0700639void AST::generateCppTag(Formatter& out, const std::string& tag) const {
640 out << "typedef " << tag << " _hidl_tag;\n\n";
641}
642
Steven Moreland368e4602018-02-16 14:21:49 -0800643void AST::generateStubHeader(Formatter& out) const {
Steven Moreland5abcf012018-02-08 18:50:18 -0800644 CHECK(AST::isInterface());
Andreas Huber881227d2016-08-02 14:20:21 -0700645
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700646 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800647 const std::string klassName = iface->getStubName();
Steven Moreland40786312016-08-16 10:29:40 -0700648 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700649
650 out << "#ifndef " << guard << "\n";
651 out << "#define " << guard << "\n\n";
652
Yifan Hongeefe4f22017-01-04 15:32:42 -0800653 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Moreland1a52e822017-07-27 13:56:29 -0700654
Steven Morelandee88eed2016-10-31 17:49:00 -0700655 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700656
657 enterLeaveNamespace(out, true /* enter */);
658 out << "\n";
659
660 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800661 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100662 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800663 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000664 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100665 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800666 out << " : public "
667 << gIBaseFqName.getInterfaceStubFqName().cppName()
668 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100669 }
Andreas Huber881227d2016-08-02 14:20:21 -0700670
671 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800672 out << "explicit "
673 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -0700674 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100675 << "\n";
Yifan Hongeefe4f22017-01-04 15:32:42 -0800676 out << "explicit "
677 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -0700678 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800679 << " const std::string& HidlInstrumentor_package,"
680 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700681 << "\n\n";
Steven Moreland57a89362017-07-21 19:29:54 +0000682 out << "virtual ~" << klassName << "();\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700683 out << "::android::status_t onTransact(\n";
684 out.indent();
685 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700686 out << "uint32_t _hidl_code,\n";
687 out << "const ::android::hardware::Parcel &_hidl_data,\n";
688 out << "::android::hardware::Parcel *_hidl_reply,\n";
689 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700690 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700691 out.unindent();
692 out.unindent();
693
Steven Moreland0b843772017-06-23 16:33:38 -0700694 out.endl();
695 generateTemplatizationLink(out);
Steven Moreland7645fbd2019-03-12 18:49:28 -0700696 DocComment("Type tag for use in template logic that indicates this is a 'native' class.")
697 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700698 generateCppTag(out, "android::hardware::details::bnhw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700699
Steven Morelandcbcf9f72017-11-20 10:04:15 -0800700 out << "::android::sp<" << iface->localName() << "> getImpl() { return _hidl_mImpl; }\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700701
Steven Moreland368e4602018-02-16 14:21:49 -0800702 generateMethods(out,
703 [&](const Method* method, const Interface*) {
704 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
705 return;
706 }
Steven Morelandf16c5c02017-07-31 16:50:06 -0700707
Steven Moreland368e4602018-02-16 14:21:49 -0800708 out << "static ::android::status_t _hidl_" << method->name() << "(\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700709
Steven Moreland368e4602018-02-16 14:21:49 -0800710 out.indent(2,
711 [&] {
712 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
713 << "const ::android::hardware::Parcel &_hidl_data,\n"
714 << "::android::hardware::Parcel *_hidl_reply,\n"
715 << "TransactCallback _hidl_cb);\n";
716 })
717 .endl()
718 .endl();
719 },
720 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -0700721
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100722 out.unindent();
723 out << "private:\n";
724 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800725
Steven Moreland368e4602018-02-16 14:21:49 -0800726 generateMethods(out, [&](const Method* method, const Interface* iface) {
Yifan Hongcd2ae452017-01-31 14:33:40 -0800727 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
Steven Moreland368e4602018-02-16 14:21:49 -0800728 return;
Yifan Hongcd2ae452017-01-31 14:33:40 -0800729 }
730 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700731 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800732
733 if (elidedReturn == nullptr && returnsValue) {
734 out << "using " << method->name() << "_cb = "
735 << iface->fqName().cppName()
736 << "::" << method->name() << "_cb;\n";
737 }
738 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800739 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800740 });
Yifan Hongcd2ae452017-01-31 14:33:40 -0800741
Steven Moreland19f11b52017-05-12 18:22:21 -0700742 out << "::android::sp<" << iface->localName() << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700743 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700744 out << "};\n\n";
745
746 enterLeaveNamespace(out, false /* enter */);
747
748 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700749}
750
Steven Moreland368e4602018-02-16 14:21:49 -0800751void AST::generateProxyHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700752 if (!AST::isInterface()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700753 // types.hal does not get a proxy header.
Steven Moreland368e4602018-02-16 14:21:49 -0800754 return;
Andreas Huber881227d2016-08-02 14:20:21 -0700755 }
756
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700757 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800758 const std::string proxyName = iface->getProxyName();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800759 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700760
761 out << "#ifndef " << guard << "\n";
762 out << "#define " << guard << "\n\n";
763
Martijn Coenen115d4282016-12-19 05:14:04 +0100764 out << "#include <hidl/HidlTransportSupport.h>\n\n";
765
Andreas Huber881227d2016-08-02 14:20:21 -0700766 std::vector<std::string> packageComponents;
767 getPackageAndVersionComponents(
768 &packageComponents, false /* cpp_compatible */);
769
Yifan Hongeefe4f22017-01-04 15:32:42 -0800770 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700771 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700772
773 enterLeaveNamespace(out, true /* enter */);
774 out << "\n";
775
776 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800777 << proxyName
778 << " : public ::android::hardware::BpInterface<"
779 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000780 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700781
782 out.indent();
783
Yifan Hongeefe4f22017-01-04 15:32:42 -0800784 out << "explicit "
785 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700786 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700787 << "\n\n";
788
Steven Moreland0b843772017-06-23 16:33:38 -0700789 generateTemplatizationLink(out);
Steven Moreland7645fbd2019-03-12 18:49:28 -0700790 DocComment("Type tag for use in template logic that indicates this is a 'proxy' class.")
791 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700792 generateCppTag(out, "android::hardware::details::bphw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700793
Yifan Hong10fe0b52016-10-19 14:20:17 -0700794 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700795
Steven Moreland368e4602018-02-16 14:21:49 -0800796 generateMethods(
797 out,
798 [&](const Method* method, const Interface*) {
799 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
800 return;
801 }
Steven Morelandf16c5c02017-07-31 16:50:06 -0700802
Steven Moreland368e4602018-02-16 14:21:49 -0800803 out << "static ";
804 method->generateCppReturnType(out);
805 out << " _hidl_" << method->name() << "("
806 << "::android::hardware::IInterface* _hidl_this, "
807 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700808
Steven Moreland368e4602018-02-16 14:21:49 -0800809 if (!method->hasEmptyCppArgSignature()) {
810 out << ", ";
811 }
812 method->emitCppArgSignature(out);
813 out << ");\n";
814 },
815 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -0700816
Steven Moreland368e4602018-02-16 14:21:49 -0800817 generateMethods(out, [&](const Method* method, const Interface*) {
Yifan Hong068c5522016-10-31 14:07:25 -0700818 method->generateCppSignature(out);
819 out << " override;\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700820 });
Steven Moreland9c387612016-09-07 09:54:26 -0700821
Andreas Huber881227d2016-08-02 14:20:21 -0700822 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100823 out << "private:\n";
824 out.indent();
825 out << "std::mutex _hidl_mMutex;\n"
826 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
827 << " _hidl_mDeathRecipients;\n";
828 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700829 out << "};\n\n";
830
831 enterLeaveNamespace(out, false /* enter */);
832
833 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700834}
835
Steven Moreland368e4602018-02-16 14:21:49 -0800836void AST::generateCppSource(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700837 std::string baseName = getBaseName();
838 const Interface *iface = getInterface();
Andreas Huber881227d2016-08-02 14:20:21 -0700839
Steven Morelanda885d252017-09-25 18:44:43 -0700840 const std::string klassName = baseName + (baseName == "types" ? "" : "All");
Andreas Huber881227d2016-08-02 14:20:21 -0700841
Steven Moreland623c0042017-01-13 14:42:29 -0800842 out << "#define LOG_TAG \""
843 << mPackage.string() << "::" << baseName
844 << "\"\n\n";
845
Steven Moreland5add34d2018-11-08 16:31:30 -0800846 out << "#include <log/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100847 out << "#include <cutils/trace.h>\n";
848 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Steven Moreland26896a92018-07-31 15:31:01 -0700849 out << "#include <hidl/Static.h>\n";
850 out << "#include <hwbinder/ProcessState.h>\n";
Steven Moreland4607ef52018-05-09 10:52:47 -0700851 out << "#include <utils/Trace.h>\n";
Steven Moreland19f11b52017-05-12 18:22:21 -0700852 if (iface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700853 // This is a no-op for IServiceManager itself.
854 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
855
Yifan Hongeefe4f22017-01-04 15:32:42 -0800856 generateCppPackageInclude(out, mPackage, iface->getProxyName());
857 generateCppPackageInclude(out, mPackage, iface->getStubName());
858 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700859
860 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700861 generateCppPackageInclude(out,
862 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800863 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700864 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800865
866 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700867 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700868 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800869 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700870 }
871
872 out << "\n";
873
874 enterLeaveNamespace(out, true /* enter */);
875 out << "\n";
876
Steven Moreland368e4602018-02-16 14:21:49 -0800877 generateTypeSource(out, iface ? iface->localName() : "");
Andreas Huber881227d2016-08-02 14:20:21 -0700878
Steven Moreland368e4602018-02-16 14:21:49 -0800879 if (iface) {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700880 const Interface* iface = mRootScope.getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700881
882 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -0800883 out << "const char* "
884 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -0700885 << "::descriptor(\""
886 << iface->fqName().string()
887 << "\");\n\n";
Yifan Hong91977fd2017-11-09 16:07:37 -0800888 out << "__attribute__((constructor)) ";
Martijn Coenen8adcb652017-02-03 17:37:36 +0100889 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800890 out.indent([&] {
Yifan Hong91977fd2017-11-09 16:07:37 -0800891 out << "::android::hardware::details::getBnConstructorMap().set("
Yifan Hongeefe4f22017-01-04 15:32:42 -0800892 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -0800893 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800894 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -0800895 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800896 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800897 out << "return new "
898 << iface->getStubName()
Yifan Hong341112d2017-04-20 18:12:05 -0700899 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -0800900 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -0800901 << " *>(iIntf));\n";
902 });
Yifan Hongb04de382017-02-06 15:31:52 -0800903 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800904 });
Yifan Hong91977fd2017-11-09 16:07:37 -0800905 out << "::android::hardware::details::getBsConstructorMap().set("
Yifan Hongeefe4f22017-01-04 15:32:42 -0800906 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -0800907 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800908 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -0800909 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -0800910 << gIBaseFqName.cppName()
911 << "> {\n";
912 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800913 out << "return new "
914 << iface->getPassthroughName()
Yifan Hong341112d2017-04-20 18:12:05 -0700915 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -0800916 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -0800917 << " *>(iIntf));\n";
918 });
Yifan Hongb04de382017-02-06 15:31:52 -0800919 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800920 });
Yifan Hong158655a2016-11-08 12:34:07 -0800921 });
Martijn Coenen8adcb652017-02-03 17:37:36 +0100922 out << "};\n\n";
923 out << "__attribute__((destructor))";
924 out << "static void static_destructor() {\n";
925 out.indent([&] {
Yifan Hong91977fd2017-11-09 16:07:37 -0800926 out << "::android::hardware::details::getBnConstructorMap().erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +0100927 << iface->localName()
928 << "::descriptor);\n";
Yifan Hong91977fd2017-11-09 16:07:37 -0800929 out << "::android::hardware::details::getBsConstructorMap().erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +0100930 << iface->localName()
931 << "::descriptor);\n";
932 });
933 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800934
Steven Moreland368e4602018-02-16 14:21:49 -0800935 generateInterfaceSource(out);
936 generateProxySource(out, iface->fqName());
937 generateStubSource(out, iface);
938 generatePassthroughSource(out);
Steven Moreland9c387612016-09-07 09:54:26 -0700939
Yifan Hongc8934042016-11-17 17:10:52 -0800940 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800941 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800942 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800943 std::string package = iface->fqName().package()
944 + iface->fqName().atVersion();
945
Yifan Hongeefe4f22017-01-04 15:32:42 -0800946 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -0800947 }
Steven Moreland40786312016-08-16 10:29:40 -0700948 }
949
Andreas Huber6755e9d2017-04-06 11:09:07 -0700950 HidlTypeAssertion::EmitAll(out);
951 out << "\n";
952
Andreas Huber881227d2016-08-02 14:20:21 -0700953 enterLeaveNamespace(out, false /* enter */);
Andreas Huber881227d2016-08-02 14:20:21 -0700954}
955
Steven Moreland67f67b42016-09-29 08:59:02 -0700956void AST::generateCheckNonNull(Formatter &out, const std::string &nonNull) {
Yifan Honga018ed52016-12-13 16:35:08 -0800957 out.sIf(nonNull + " == nullptr", [&] {
958 out << "return ::android::hardware::Status::fromExceptionCode(\n";
959 out.indent(2, [&] {
Steven Moreland610002f2017-06-16 13:02:49 -0700960 out << "::android::hardware::Status::EX_ILLEGAL_ARGUMENT,\n"
961 << "\"Null synchronous callback passed.\");\n";
Yifan Honga018ed52016-12-13 16:35:08 -0800962 });
963 }).endl().endl();
Steven Moreland67f67b42016-09-29 08:59:02 -0700964}
965
Steven Moreland368e4602018-02-16 14:21:49 -0800966void AST::generateTypeSource(Formatter& out, const std::string& ifaceName) const {
967 mRootScope.emitTypeDefinitions(out, ifaceName);
Andreas Huber881227d2016-08-02 14:20:21 -0700968}
969
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700970void AST::declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& args,
971 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700972 if (args.empty()) {
973 return;
974 }
975
976 for (const auto &arg : args) {
977 const Type &type = arg->type();
978
Yifan Hong3b320f82016-11-01 15:15:54 -0700979 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700980 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700981 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700982 << ";\n";
983 }
984
985 out << "\n";
986}
987
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700988void AST::emitCppReaderWriter(Formatter& out, const std::string& parcelObj, bool parcelObjIsPointer,
989 const NamedReference<Type>* arg, bool isReader, Type::ErrorMode mode,
990 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700991 const Type &type = arg->type();
992
Andreas Huber881227d2016-08-02 14:20:21 -0700993 type.emitReaderWriter(
994 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700995 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700996 parcelObj,
997 parcelObjIsPointer,
998 isReader,
999 mode);
1000}
1001
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001002void AST::emitCppResolveReferences(Formatter& out, const std::string& parcelObj,
1003 bool parcelObjIsPointer, const NamedReference<Type>* arg,
1004 bool isReader, Type::ErrorMode mode,
1005 bool addPrefixToName) const {
Yifan Hongbf459bc2016-08-23 16:50:37 -07001006 const Type &type = arg->type();
1007 if(type.needsResolveReferences()) {
1008 type.emitResolveReferences(
1009 out,
1010 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1011 isReader, // nameIsPointer
1012 parcelObj,
1013 parcelObjIsPointer,
1014 isReader,
1015 mode);
1016 }
1017}
1018
Steven Moreland368e4602018-02-16 14:21:49 -08001019void AST::generateProxyMethodSource(Formatter& out, const std::string& klassName,
1020 const Method* method, const Interface* superInterface) const {
Yifan Hong068c5522016-10-31 14:07:25 -07001021 method->generateCppSignature(out,
1022 klassName,
1023 true /* specify namespaces */);
1024
Martijn Coenen115d4282016-12-19 05:14:04 +01001025 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001026 out.block([&] {
1027 method->cppImpl(IMPL_PROXY, out);
1028 }).endl().endl();
Steven Moreland368e4602018-02-16 14:21:49 -08001029 return;
Martijn Coenen115d4282016-12-19 05:14:04 +01001030 }
1031
Steven Morelandf16c5c02017-07-31 16:50:06 -07001032 out.block([&] {
1033 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001034 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001035
1036 method->generateCppReturnType(out);
1037
1038 out << " _hidl_out = "
1039 << superInterface->fqName().cppNamespace()
1040 << "::"
1041 << superInterface->getProxyName()
1042 << "::_hidl_"
1043 << method->name()
1044 << "(this, this";
1045
1046 if (!method->hasEmptyCppArgSignature()) {
1047 out << ", ";
1048 }
1049
1050 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
1051 out << arg->name();
1052 });
1053
1054 if (returnsValue && elidedReturn == nullptr) {
1055 if (!method->args().empty()) {
1056 out << ", ";
1057 }
1058 out << "_hidl_cb";
1059 }
1060
1061 out << ");\n\n";
1062
1063 out << "return _hidl_out;\n";
1064 }).endl().endl();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001065}
1066
Steven Moreland368e4602018-02-16 14:21:49 -08001067void AST::generateStaticProxyMethodSource(Formatter& out, const std::string& klassName,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001068 const Method* method, const Interface* superInterface) const {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001069 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001070 return;
Steven Morelandf16c5c02017-07-31 16:50:06 -07001071 }
1072
1073 method->generateCppReturnType(out);
1074
1075 out << klassName
1076 << "::_hidl_"
1077 << method->name()
1078 << "("
1079 << "::android::hardware::IInterface *_hidl_this, "
1080 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
1081
1082 if (!method->hasEmptyCppArgSignature()) {
1083 out << ", ";
1084 }
1085
1086 method->emitCppArgSignature(out);
1087 out << ") {\n";
1088
1089 out.indent();
1090
1091 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1092 out << "bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();\n";
1093 out << "const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();\n";
1094 out << "#else\n";
1095 out << "(void) _hidl_this_instrumentor;\n";
1096 out << "#endif // __ANDROID_DEBUGGABLE__\n";
1097
1098 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001099 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland48cc6042019-04-30 11:28:56 -07001100 const bool hasCallback = returnsValue && elidedReturn == nullptr;
1101
1102 if (hasCallback) {
Yifan Hong068c5522016-10-31 14:07:25 -07001103 generateCheckNonNull(out, "_hidl_cb");
1104 }
1105
Steven Moreland92a08a72017-07-31 14:57:37 -07001106 generateCppInstrumentationCall(
Yifan Hong068c5522016-10-31 14:07:25 -07001107 out,
1108 InstrumentationEvent::CLIENT_API_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001109 method,
1110 superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001111
1112 out << "::android::hardware::Parcel _hidl_data;\n";
1113 out << "::android::hardware::Parcel _hidl_reply;\n";
1114 out << "::android::status_t _hidl_err;\n";
Steven Moreland48cc6042019-04-30 11:28:56 -07001115 out << "::android::status_t _hidl_transact_err;\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001116 out << "::android::hardware::Status _hidl_status;\n\n";
1117
Steven Moreland48cc6042019-04-30 11:28:56 -07001118 if (!hasCallback) {
1119 declareCppReaderLocals(
1120 out, method->results(), true /* forResults */);
1121 }
Yifan Hong068c5522016-10-31 14:07:25 -07001122
1123 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001124 out << klassName;
Yifan Hong068c5522016-10-31 14:07:25 -07001125 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001126 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1127
Martijn Coenenfff73352017-01-04 16:36:31 +01001128 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001129 // First DFS: write all buffers and resolve pointers for parent
1130 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001131 if (arg->type().isInterface()) {
1132 hasInterfaceArgument = true;
1133 }
Yifan Hong068c5522016-10-31 14:07:25 -07001134 emitCppReaderWriter(
1135 out,
1136 "_hidl_data",
1137 false /* parcelObjIsPointer */,
1138 arg,
1139 false /* reader */,
1140 Type::ErrorMode_Goto,
1141 false /* addPrefixToName */);
1142 }
1143
1144 // Second DFS: resolve references.
1145 for (const auto &arg : method->args()) {
1146 emitCppResolveReferences(
1147 out,
1148 "_hidl_data",
1149 false /* parcelObjIsPointer */,
1150 arg,
1151 false /* reader */,
1152 Type::ErrorMode_Goto,
1153 false /* addPrefixToName */);
1154 }
1155
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001156 if (hasInterfaceArgument) {
1157 // Start binder threadpool to handle incoming transactions
1158 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1159 }
Steven Moreland48cc6042019-04-30 11:28:56 -07001160 out << "_hidl_transact_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact("
Yifan Hong068c5522016-10-31 14:07:25 -07001161 << method->getSerialId()
1162 << " /* "
1163 << method->name()
1164 << " */, _hidl_data, &_hidl_reply";
1165
1166 if (method->isOneway()) {
Steven Moreland77943692018-08-09 12:53:42 -07001167 out << ", " << Interface::FLAG_ONE_WAY->cppValue();
Steven Moreland48cc6042019-04-30 11:28:56 -07001168 } else {
1169 out << ", 0";
Yifan Hong068c5522016-10-31 14:07:25 -07001170 }
Yifan Hong068c5522016-10-31 14:07:25 -07001171
Steven Moreland48cc6042019-04-30 11:28:56 -07001172 if (hasCallback) {
1173 out << ", [&] (::android::hardware::Parcel& _hidl_reply) {\n";
1174 out.indent();
1175 declareCppReaderLocals(
1176 out, method->results(), true /* forResults */);
1177 out.endl();
1178 } else {
1179 out << ");\n";
1180 out << "if (_hidl_transact_err != ::android::OK) \n";
1181 out.block([&] {
1182 out << "_hidl_err = _hidl_transact_err;\n";
1183 out << "goto _hidl_error;\n";
1184 }).endl().endl();
1185 }
Yifan Hong068c5522016-10-31 14:07:25 -07001186
1187 if (!method->isOneway()) {
Steven Moreland48cc6042019-04-30 11:28:56 -07001188 Type::ErrorMode errorMode = hasCallback ? Type::ErrorMode_ReturnNothing : Type::ErrorMode_Goto;
Yifan Hong068c5522016-10-31 14:07:25 -07001189
Steven Moreland48cc6042019-04-30 11:28:56 -07001190 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
1191 Type::handleError(out, errorMode);
1192
1193 if (hasCallback) {
1194 out << "if (!_hidl_status.isOk()) { return; }\n\n";
1195 } else {
1196 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1197 }
Yifan Hong068c5522016-10-31 14:07:25 -07001198
1199 // First DFS: write all buffers and resolve pointers for parent
1200 for (const auto &arg : method->results()) {
1201 emitCppReaderWriter(
1202 out,
1203 "_hidl_reply",
1204 false /* parcelObjIsPointer */,
1205 arg,
1206 true /* reader */,
Steven Moreland48cc6042019-04-30 11:28:56 -07001207 errorMode,
Yifan Hong068c5522016-10-31 14:07:25 -07001208 true /* addPrefixToName */);
1209 }
1210
1211 // Second DFS: resolve references.
1212 for (const auto &arg : method->results()) {
1213 emitCppResolveReferences(
1214 out,
1215 "_hidl_reply",
1216 false /* parcelObjIsPointer */,
1217 arg,
1218 true /* reader */,
Steven Moreland48cc6042019-04-30 11:28:56 -07001219 errorMode,
Yifan Hong068c5522016-10-31 14:07:25 -07001220 true /* addPrefixToName */);
1221 }
1222
1223 if (returnsValue && elidedReturn == nullptr) {
1224 out << "_hidl_cb(";
1225
Yifan Hong932464e2017-03-30 15:40:22 -07001226 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001227 if (arg->type().resultNeedsDeref()) {
1228 out << "*";
1229 }
1230 out << "_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001231 });
Yifan Hong068c5522016-10-31 14:07:25 -07001232
1233 out << ");\n\n";
1234 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001235 }
Steven Morelandf16c5c02017-07-31 16:50:06 -07001236
Steven Moreland92a08a72017-07-31 14:57:37 -07001237 generateCppInstrumentationCall(
Martijn Coenen7b295242016-11-04 16:52:56 +01001238 out,
1239 InstrumentationEvent::CLIENT_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001240 method,
1241 superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001242
Steven Moreland48cc6042019-04-30 11:28:56 -07001243 if (hasCallback) {
1244 out.unindent();
1245 out << "});\n";
1246 out << "if (_hidl_transact_err != ::android::OK) ";
1247 out.block([&] {
1248 out << "_hidl_err = _hidl_transact_err;\n";
1249 out << "goto _hidl_error;\n";
1250 }).endl().endl();
1251 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n";
1252 }
1253
Yifan Hong068c5522016-10-31 14:07:25 -07001254 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001255 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1256 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001257 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001258 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1259 } else {
1260 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1261 out << "return ::android::hardware::Return<void>();\n\n";
1262 }
1263
1264 out.unindent();
1265 out << "_hidl_error:\n";
1266 out.indent();
1267 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1268 out << "return ::android::hardware::Return<";
1269 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001270 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001271 } else {
1272 out << "void";
1273 }
1274 out << ">(_hidl_status);\n";
1275
1276 out.unindent();
1277 out << "}\n\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001278}
1279
Steven Moreland368e4602018-02-16 14:21:49 -08001280void AST::generateProxySource(Formatter& out, const FQName& fqName) const {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001281 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001282
1283 out << klassName
1284 << "::"
1285 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001286 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001287
1288 out.indent();
1289 out.indent();
1290
1291 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001292 << "<"
1293 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001294 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001295 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001296 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001297 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001298 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001299 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001300
Andreas Huber881227d2016-08-02 14:20:21 -07001301 out.unindent();
1302 out.unindent();
1303 out << "}\n\n";
1304
Steven Moreland368e4602018-02-16 14:21:49 -08001305 generateMethods(out,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001306 [&](const Method* method, const Interface* superInterface) {
1307 generateStaticProxyMethodSource(out, klassName, method, superInterface);
Steven Moreland368e4602018-02-16 14:21:49 -08001308 },
1309 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -07001310
Steven Moreland368e4602018-02-16 14:21:49 -08001311 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1312 generateProxyMethodSource(out, klassName, method, superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001313 });
Andreas Huber881227d2016-08-02 14:20:21 -07001314}
1315
Steven Moreland368e4602018-02-16 14:21:49 -08001316void AST::generateStubSource(Formatter& out, const Interface* iface) const {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001317 const std::string interfaceName = iface->localName();
1318 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001319
Steven Moreland40786312016-08-16 10:29:40 -07001320 out << klassName
1321 << "::"
1322 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001323 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001324
1325 out.indent();
1326 out.indent();
1327
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001328 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001329 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001330 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001331 out << ": "
1332 << gIBaseFqName.getInterfaceStubFqName().cppName()
1333 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001334 }
1335
1336 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001337 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001338 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001339 << "\") { \n";
1340 out.indent();
1341 out << "_hidl_mImpl = _hidl_impl;\n";
Steven Morelandbd984412019-04-22 10:25:46 -07001342 out << "auto prio = ::android::hardware::details::gServicePrioMap->get("
Martijn Coenenb4d77952017-05-03 13:44:29 -07001343 << "_hidl_impl, {SCHED_NORMAL, 0});\n";
1344 out << "mSchedPolicy = prio.sched_policy;\n";
1345 out << "mSchedPriority = prio.prio;\n";
Steven Morelandbd984412019-04-22 10:25:46 -07001346 out << "setRequestingSid(::android::hardware::details::gServiceSidMap->get(_hidl_impl, "
1347 "false));\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001348 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001349
1350 out.unindent();
1351 out.unindent();
1352 out << "}\n\n";
1353
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001354 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001355 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001356 // class properly.
1357 out << klassName
1358 << "::"
1359 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001360 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1361 << " const std::string &HidlInstrumentor_package,"
1362 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001363
1364 out.indent();
1365 out.indent();
1366
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001367 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001368 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001369 out.indent();
1370 out << "_hidl_mImpl = _hidl_impl;\n";
1371 out.unindent();
1372
1373 out.unindent();
1374 out.unindent();
1375 out << "}\n\n";
1376 }
1377
Steven Moreland57a89362017-07-21 19:29:54 +00001378 out << klassName << "::~" << klassName << "() ";
1379 out.block([&]() {
Steven Morelandbd984412019-04-22 10:25:46 -07001380 out << "::android::hardware::details::gBnMap->eraseIfEqual(_hidl_mImpl.get(), this);\n";
1381 })
1382 .endl()
1383 .endl();
Steven Moreland57a89362017-07-21 19:29:54 +00001384
Steven Moreland368e4602018-02-16 14:21:49 -08001385 generateMethods(out,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001386 [&](const Method* method, const Interface* superInterface) {
1387 return generateStaticStubMethodSource(out, iface->fqName(), method, superInterface);
Steven Moreland368e4602018-02-16 14:21:49 -08001388 },
1389 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -07001390
Steven Moreland368e4602018-02-16 14:21:49 -08001391 generateMethods(out, [&](const Method* method, const Interface*) {
Yifan Hongbcffce22017-02-01 15:52:06 -08001392 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001393 return;
Yifan Hongbcffce22017-02-01 15:52:06 -08001394 }
1395 method->generateCppSignature(out, iface->getStubName());
1396 out << " ";
1397 out.block([&] {
1398 method->cppImpl(IMPL_STUB_IMPL, out);
1399 }).endl();
Yifan Hongbcffce22017-02-01 15:52:06 -08001400 });
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001401
Andreas Huber881227d2016-08-02 14:20:21 -07001402 out << "::android::status_t " << klassName << "::onTransact(\n";
1403
1404 out.indent();
1405 out.indent();
1406
Iliyan Malchev549e2592016-08-10 08:59:12 -07001407 out << "uint32_t _hidl_code,\n"
1408 << "const ::android::hardware::Parcel &_hidl_data,\n"
1409 << "::android::hardware::Parcel *_hidl_reply,\n"
1410 << "uint32_t _hidl_flags,\n"
1411 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001412
1413 out.unindent();
1414
Iliyan Malchev549e2592016-08-10 08:59:12 -07001415 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001416 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001417 out.indent();
1418
Yifan Hong10fe0b52016-10-19 14:20:17 -07001419 for (const auto &tuple : iface->allMethodsFromRoot()) {
1420 const Method *method = tuple.method();
1421 const Interface *superInterface = tuple.interface();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001422
Howard Chen71f289f2017-08-29 17:35:01 +08001423 if (!isIBase() && method->isHidlReserved()) {
1424 continue;
1425 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001426 out << "case "
1427 << method->getSerialId()
1428 << " /* "
1429 << method->name()
1430 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001431
Yifan Hong10fe0b52016-10-19 14:20:17 -07001432 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001433
Steven Moreland77943692018-08-09 12:53:42 -07001434 out << "bool _hidl_is_oneway = _hidl_flags & " << Interface::FLAG_ONE_WAY->cppValue()
1435 << ";\n";
Steven Morelandebd8c722017-11-03 14:47:32 -07001436 out << "if (_hidl_is_oneway != " << (method->isOneway() ? "true" : "false") << ") ";
1437 out.block([&] { out << "return ::android::UNKNOWN_ERROR;\n"; }).endl().endl();
1438
Steven Moreland368e4602018-02-16 14:21:49 -08001439 generateStubSourceForMethod(out, method, superInterface);
Yifan Hong10fe0b52016-10-19 14:20:17 -07001440
1441 out.unindent();
1442 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001443 }
1444
1445 out << "default:\n{\n";
1446 out.indent();
1447
Martijn Coenen225bc922017-06-27 14:39:46 -07001448 if (iface->isIBase()) {
1449 out << "(void)_hidl_flags;\n";
1450 out << "return ::android::UNKNOWN_TRANSACTION;\n";
1451 } else {
1452 out << "return ";
1453 out << gIBaseFqName.getInterfaceStubFqName().cppName();
1454 out << "::onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001455
Martijn Coenen225bc922017-06-27 14:39:46 -07001456 out.indent();
1457 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001458
Martijn Coenen225bc922017-06-27 14:39:46 -07001459 out << "_hidl_code, _hidl_data, _hidl_reply, "
1460 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001461
Martijn Coenen225bc922017-06-27 14:39:46 -07001462 out.unindent();
1463 out.unindent();
1464 }
Andreas Huber881227d2016-08-02 14:20:21 -07001465
1466 out.unindent();
1467 out << "}\n";
1468
1469 out.unindent();
1470 out << "}\n\n";
1471
Yifan Honga018ed52016-12-13 16:35:08 -08001472 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1473 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1474 out.indent(2, [&] {
1475 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1476 out << "_hidl_reply);\n";
1477 });
1478 });
Andreas Huber881227d2016-08-02 14:20:21 -07001479
Iliyan Malchev549e2592016-08-10 08:59:12 -07001480 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001481
1482 out.unindent();
1483 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001484}
1485
Steven Moreland368e4602018-02-16 14:21:49 -08001486void AST::generateStubSourceForMethod(Formatter& out, const Method* method,
1487 const Interface* superInterface) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001488 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1489 method->cppImpl(IMPL_STUB, out);
1490 out << "break;\n";
Steven Moreland368e4602018-02-16 14:21:49 -08001491 return;
Martijn Coenen115d4282016-12-19 05:14:04 +01001492 }
1493
Steven Morelandf16c5c02017-07-31 16:50:06 -07001494 out << "_hidl_err = "
1495 << superInterface->fqName().cppNamespace()
1496 << "::"
1497 << superInterface->getStubName()
1498 << "::_hidl_"
1499 << method->name()
1500 << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
1501 out << "break;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001502}
1503
Steven Moreland368e4602018-02-16 14:21:49 -08001504void AST::generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001505 const Method* method, const Interface* superInterface) const {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001506 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001507 return;
Steven Morelandf16c5c02017-07-31 16:50:06 -07001508 }
1509
Steven Morelandf8197902018-01-30 15:38:37 -08001510 const std::string& klassName = fqName.getInterfaceStubName();
1511
Steven Morelandf16c5c02017-07-31 16:50:06 -07001512 out << "::android::status_t " << klassName << "::_hidl_" << method->name() << "(\n";
1513
1514 out.indent();
1515 out.indent();
1516
1517 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
1518 << "const ::android::hardware::Parcel &_hidl_data,\n"
1519 << "::android::hardware::Parcel *_hidl_reply,\n"
1520 << "TransactCallback _hidl_cb) {\n";
1521
1522 out.unindent();
1523
1524 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1525 out << "bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();\n";
1526 out << "const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();\n";
1527 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1528
1529 out << "::android::status_t _hidl_err = ::android::OK;\n";
1530
Yifan Hongeefe4f22017-01-04 15:32:42 -08001531 out << "if (!_hidl_data.enforceInterface("
Steven Morelandf16c5c02017-07-31 16:50:06 -07001532 << klassName
1533 << "::Pure::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001534
Andreas Huber881227d2016-08-02 14:20:21 -07001535 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001536 out << "_hidl_err = ::android::BAD_TYPE;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001537 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001538 out.unindent();
1539 out << "}\n\n";
1540
Andreas Huber5e44a292016-09-27 14:52:39 -07001541 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001542
Yifan Hongbf459bc2016-08-23 16:50:37 -07001543 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001544 for (const auto &arg : method->args()) {
1545 emitCppReaderWriter(
1546 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001547 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001548 false /* parcelObjIsPointer */,
1549 arg,
1550 true /* reader */,
Steven Morelandf16c5c02017-07-31 16:50:06 -07001551 Type::ErrorMode_Return,
Andreas Huber5e44a292016-09-27 14:52:39 -07001552 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001553 }
1554
Yifan Hongbf459bc2016-08-23 16:50:37 -07001555 // Second DFS: resolve references
1556 for (const auto &arg : method->args()) {
1557 emitCppResolveReferences(
1558 out,
1559 "_hidl_data",
1560 false /* parcelObjIsPointer */,
1561 arg,
1562 true /* reader */,
Steven Morelandf16c5c02017-07-31 16:50:06 -07001563 Type::ErrorMode_Return,
Yifan Hongbf459bc2016-08-23 16:50:37 -07001564 false /* addPrefixToName */);
1565 }
1566
Steven Moreland92a08a72017-07-31 14:57:37 -07001567 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001568 out,
1569 InstrumentationEvent::SERVER_API_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001570 method,
1571 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001572
Andreas Huber881227d2016-08-02 14:20:21 -07001573 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001574 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland3e787002017-08-16 14:59:54 -07001575
1576 std::string callee;
1577
1578 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL)) {
1579 callee = "_hidl_this";
1580 } else {
Steven Morelandf8197902018-01-30 15:38:37 -08001581 callee = "static_cast<" + fqName.getInterfaceName() + "*>(_hidl_this->getImpl().get())";
Steven Moreland3e787002017-08-16 14:59:54 -07001582 }
Andreas Huber881227d2016-08-02 14:20:21 -07001583
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001584 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001585 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001586 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001587 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001588 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001589 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001590 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001591
Yifan Hong932464e2017-03-30 15:40:22 -07001592 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001593 if (arg->type().resultNeedsDeref()) {
1594 out << "*";
1595 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001596 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001597 });
Andreas Huber881227d2016-08-02 14:20:21 -07001598
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001599 out << ");\n\n";
Steven Moreland30232dc2019-03-05 19:39:10 -08001600
Yifan Hong859e53f2016-11-14 19:08:24 -08001601 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1602 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001603
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001604 elidedReturn->type().emitReaderWriter(
1605 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001606 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001607 "_hidl_reply",
1608 true, /* parcelObjIsPointer */
1609 false, /* isReader */
1610 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001611
Yifan Hongbf459bc2016-08-23 16:50:37 -07001612 emitCppResolveReferences(
1613 out,
1614 "_hidl_reply",
1615 true /* parcelObjIsPointer */,
1616 elidedReturn,
1617 false /* reader */,
1618 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001619 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001620
Steven Moreland92a08a72017-07-31 14:57:37 -07001621 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001622 out,
1623 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001624 method,
1625 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001626
Iliyan Malchev549e2592016-08-10 08:59:12 -07001627 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001628 } else {
1629 if (returnsValue) {
1630 out << "bool _hidl_callbackCalled = false;\n\n";
1631 }
Andreas Huber881227d2016-08-02 14:20:21 -07001632
Steven Moreland30232dc2019-03-05 19:39:10 -08001633 out << "::android::hardware::Return<void> _hidl_ret = " << callee << "->" << method->name()
1634 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001635
Yifan Hong932464e2017-03-30 15:40:22 -07001636 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001637 if (arg->type().resultNeedsDeref()) {
1638 out << "*";
1639 }
1640
1641 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001642 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001643
1644 if (returnsValue) {
Yifan Hong932464e2017-03-30 15:40:22 -07001645 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001646 out << ", ";
1647 }
1648
1649 out << "[&](";
1650
Yifan Hong932464e2017-03-30 15:40:22 -07001651 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001652 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001653 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001654
1655 out << ") {\n";
1656 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001657 out << "if (_hidl_callbackCalled) {\n";
1658 out.indent();
1659 out << "LOG_ALWAYS_FATAL(\""
1660 << method->name()
1661 << ": _hidl_cb called a second time, but must be called once.\");\n";
1662 out.unindent();
1663 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001664 out << "_hidl_callbackCalled = true;\n\n";
1665
Yifan Hong859e53f2016-11-14 19:08:24 -08001666 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1667 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001668
Yifan Hongbf459bc2016-08-23 16:50:37 -07001669 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001670 for (const auto &arg : method->results()) {
1671 emitCppReaderWriter(
1672 out,
1673 "_hidl_reply",
1674 true /* parcelObjIsPointer */,
1675 arg,
1676 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001677 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001678 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001679 }
1680
Yifan Hongbf459bc2016-08-23 16:50:37 -07001681 // Second DFS: resolve references
1682 for (const auto &arg : method->results()) {
1683 emitCppResolveReferences(
1684 out,
1685 "_hidl_reply",
1686 true /* parcelObjIsPointer */,
1687 arg,
1688 false /* reader */,
1689 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001690 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001691 }
1692
Steven Moreland92a08a72017-07-31 14:57:37 -07001693 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001694 out,
1695 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001696 method,
1697 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001698
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001699 out << "_hidl_cb(*_hidl_reply);\n";
1700
1701 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001702 out << "});\n\n";
1703 } else {
1704 out << ");\n\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001705 out << "(void) _hidl_cb;\n\n";
Steven Moreland92a08a72017-07-31 14:57:37 -07001706 generateCppInstrumentationCall(
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001707 out,
1708 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001709 method,
1710 superInterface);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001711 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001712
Steven Moreland30232dc2019-03-05 19:39:10 -08001713 out << "_hidl_ret.assertOk();\n";
1714
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001715 if (returnsValue) {
1716 out << "if (!_hidl_callbackCalled) {\n";
1717 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001718 out << "LOG_ALWAYS_FATAL(\""
1719 << method->name()
1720 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001721 out.unindent();
1722 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001723 } else {
1724 out << "::android::hardware::writeToParcel("
1725 << "::android::hardware::Status::ok(), "
1726 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001727 }
Andreas Huber881227d2016-08-02 14:20:21 -07001728 }
1729
Steven Morelandf16c5c02017-07-31 16:50:06 -07001730 out << "return _hidl_err;\n";
1731 out.unindent();
1732 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001733}
1734
Steven Moreland368e4602018-02-16 14:21:49 -08001735void AST::generatePassthroughHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -07001736 if (!AST::isInterface()) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001737 // types.hal does not get a stub header.
Steven Moreland368e4602018-02-16 14:21:49 -08001738 return;
Steven Moreland69e7c702016-09-09 11:16:32 -07001739 }
1740
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001741 const Interface* iface = mRootScope.getInterface();
Steven Moreland19f11b52017-05-12 18:22:21 -07001742 CHECK(iface != nullptr);
Steven Moreland69e7c702016-09-09 11:16:32 -07001743
Yifan Hongeefe4f22017-01-04 15:32:42 -08001744 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001745
1746 bool supportOneway = iface->hasOnewayMethods();
1747
Steven Moreland69e7c702016-09-09 11:16:32 -07001748 const std::string guard = makeHeaderGuard(klassName);
1749
1750 out << "#ifndef " << guard << "\n";
1751 out << "#define " << guard << "\n\n";
1752
1753 std::vector<std::string> packageComponents;
1754 getPackageAndVersionComponents(
1755 &packageComponents, false /* cpp_compatible */);
1756
Steven Moreland61d3f4b2017-04-28 17:30:38 -07001757 out << "#include <android-base/macros.h>\n";
Yifan Hongb0949432016-12-15 15:32:24 -08001758 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001759 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001760
Steven Moreland19f11b52017-05-12 18:22:21 -07001761 generateCppPackageInclude(out, mPackage, iface->localName());
Steven Morelandee88eed2016-10-31 17:49:00 -07001762 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001763
Yifan Hong7a118f52016-12-07 11:21:15 -08001764 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001765 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001766 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001767 }
1768
1769 enterLeaveNamespace(out, true /* enter */);
1770 out << "\n";
1771
1772 out << "struct "
1773 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -07001774 << " : " << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001775 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001776
1777 out.indent();
1778 out << "explicit "
1779 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001780 << "(const ::android::sp<"
Steven Moreland19f11b52017-05-12 18:22:21 -07001781 << iface->localName()
Steven Moreland69e7c702016-09-09 11:16:32 -07001782 << "> impl);\n";
1783
Steven Moreland0b843772017-06-23 16:33:38 -07001784 out.endl();
1785 generateTemplatizationLink(out);
Steven Moreland1a52e822017-07-27 13:56:29 -07001786 generateCppTag(out, "android::hardware::details::bs_tag");
Steven Moreland0b843772017-06-23 16:33:38 -07001787
Steven Moreland616cf4d2018-10-02 13:52:18 -07001788 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1789 generatePassthroughMethod(out, method, superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001790 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001791
Steven Moreland69e7c702016-09-09 11:16:32 -07001792 out.unindent();
1793 out << "private:\n";
1794 out.indent();
Steven Moreland19f11b52017-05-12 18:22:21 -07001795 out << "const ::android::sp<" << iface->localName() << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001796
1797 if (supportOneway) {
Yifan Hongef91d362017-03-20 17:18:13 -07001798 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001799
1800 out << "\n";
1801
1802 out << "::android::hardware::Return<void> addOnewayTask("
1803 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001804 }
1805
1806 out.unindent();
1807
1808 out << "};\n\n";
1809
1810 enterLeaveNamespace(out, false /* enter */);
1811
1812 out << "\n#endif // " << guard << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001813}
1814
Steven Moreland368e4602018-02-16 14:21:49 -08001815void AST::generateInterfaceSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001816 const Interface* iface = mRootScope.getInterface();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001817
Yifan Hong2d7126b2016-10-20 15:12:57 -07001818 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001819 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001820
Steven Moreland368e4602018-02-16 14:21:49 -08001821 generateMethods(out, [&](const Method* method, const Interface*) {
Steven Morelandd4b068a2017-03-20 06:30:51 -07001822 bool reserved = method->isHidlReserved();
1823
1824 if (!reserved) {
1825 out << "// no default implementation for: ";
1826 }
1827 method->generateCppSignature(out, iface->localName());
1828 if (reserved) {
1829 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001830 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001831 }).endl();
1832 }
1833
1834 out << "\n";
1835
Steven Moreland368e4602018-02-16 14:21:49 -08001836 return;
Steven Morelandd4b068a2017-03-20 06:30:51 -07001837 });
Steven Morelandd4b068a2017-03-20 06:30:51 -07001838
Yifan Hong3d746092016-12-07 14:26:33 -08001839 for (const Interface *superType : iface->typeChain()) {
Steven Moreland23cc5fa2018-05-09 10:48:48 -07001840 out << "::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -08001841 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -07001842 << "> "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001843 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001844 << "::castFrom("
1845 << superType->getCppArgumentType()
Yifan Hong200209c2017-03-29 03:39:09 -07001846 << " parent, bool "
1847 << (iface == superType ? "/* emitError */" : "emitError")
1848 << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001849 out.indent();
1850 if (iface == superType) {
1851 out << "return parent;\n";
1852 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001853 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001854 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001855 << superType->fqName().cppName() << ", "
Steven Moreland57a89362017-07-21 19:29:54 +00001856 << iface->getProxyName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001857 << ">(\n";
1858 out.indent();
1859 out.indent();
1860 out << "parent, \""
1861 << iface->fqName().string()
Yifan Hong200209c2017-03-29 03:39:09 -07001862 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001863 out.unindent();
1864 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001865 }
Yifan Hong3d746092016-12-07 14:26:33 -08001866 out.unindent();
1867 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001868 }
Yifan Hongfe95aa22016-10-19 17:26:45 -07001869}
1870
Steven Moreland368e4602018-02-16 14:21:49 -08001871void AST::generatePassthroughSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001872 const Interface* iface = mRootScope.getInterface();
Steven Moreland69e7c702016-09-09 11:16:32 -07001873
Yifan Hongeefe4f22017-01-04 15:32:42 -08001874 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001875
1876 out << klassName
1877 << "::"
1878 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001879 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001880 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001881 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001882 << mPackage.string()
1883 << "\", \""
1884 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001885 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001886 if (iface->hasOnewayMethods()) {
1887 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001888 out.indent([&] {
Yifan Hongf01dad42017-03-20 19:03:11 -07001889 out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001890 });
1891 }
1892 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001893
1894 if (iface->hasOnewayMethods()) {
1895 out << "::android::hardware::Return<void> "
1896 << klassName
1897 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1898 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001899 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001900 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001901 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1902 out.indent();
1903 out.indent();
Steven Moreland610002f2017-06-16 13:02:49 -07001904 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
1905 << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
Steven Moreland67f67b42016-09-29 08:59:02 -07001906 out.unindent();
1907 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001908 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001909 out << "}\n";
1910
Steven Morelandd366c262016-10-11 15:29:10 -07001911 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001912
1913 out.unindent();
1914 out << "}\n\n";
1915
1916
1917 }
Steven Moreland69e7c702016-09-09 11:16:32 -07001918}
1919
Steven Moreland92a08a72017-07-31 14:57:37 -07001920void AST::generateCppAtraceCall(Formatter &out,
Martijn Coenen7b295242016-11-04 16:52:56 +01001921 InstrumentationEvent event,
1922 const Method *method) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001923 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001924 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001925 switch (event) {
1926 case SERVER_API_ENTRY:
1927 {
1928 out << "atrace_begin(ATRACE_TAG_HAL, \""
1929 << baseString + "::server\");\n";
1930 break;
1931 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001932 case PASSTHROUGH_ENTRY:
1933 {
1934 out << "atrace_begin(ATRACE_TAG_HAL, \""
1935 << baseString + "::passthrough\");\n";
1936 break;
1937 }
1938 case SERVER_API_EXIT:
Martijn Coenen7b295242016-11-04 16:52:56 +01001939 case PASSTHROUGH_EXIT:
1940 {
1941 out << "atrace_end(ATRACE_TAG_HAL);\n";
1942 break;
1943 }
Steven Moreland4607ef52018-05-09 10:52:47 -07001944 // client uses scope because of gotos
1945 // this isn't done for server because the profiled code isn't alone in its scope
1946 // this isn't done for passthrough becuase the profiled boundary isn't even in the same code
1947 case CLIENT_API_ENTRY: {
Michael Butler0a3d99a2018-07-26 13:47:10 -07001948 out << "::android::ScopedTrace PASTE(___tracer, __LINE__) (ATRACE_TAG_HAL, \""
1949 << baseString + "::client\");\n";
Steven Moreland4607ef52018-05-09 10:52:47 -07001950 break;
1951 }
1952 case CLIENT_API_EXIT:
1953 break;
Martijn Coenen7b295242016-11-04 16:52:56 +01001954 default:
1955 {
Steven Morelandcbff5612017-10-11 17:01:54 -07001956 CHECK(false) << "Unsupported instrumentation event: " << event;
Martijn Coenen7b295242016-11-04 16:52:56 +01001957 }
1958 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001959}
1960
Steven Moreland92a08a72017-07-31 14:57:37 -07001961void AST::generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001962 Formatter &out,
1963 InstrumentationEvent event,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001964 const Method *method,
1965 const Interface* superInterface) const {
Steven Moreland92a08a72017-07-31 14:57:37 -07001966 generateCppAtraceCall(out, event, method);
Martijn Coenen7b295242016-11-04 16:52:56 +01001967
Steven Moreland30b76e92017-06-02 18:52:24 -07001968 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001969 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1970 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001971 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001972 std::string event_str = "";
1973 switch (event) {
1974 case SERVER_API_ENTRY:
1975 {
1976 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1977 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001978 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001979 << (arg->type().resultNeedsDeref() ? "" : "&")
1980 << arg->name()
1981 << ");\n";
1982 }
1983 break;
1984 }
1985 case SERVER_API_EXIT:
1986 {
1987 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001988 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001989 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001990 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001991 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001992 }
1993 break;
1994 }
1995 case CLIENT_API_ENTRY:
1996 {
1997 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1998 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001999 out << "_hidl_args.push_back((void *)&"
2000 << arg->name()
2001 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002002 }
2003 break;
2004 }
2005 case CLIENT_API_EXIT:
2006 {
2007 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2008 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002009 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002010 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002011 << "_hidl_out_"
2012 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002013 << ");\n";
2014 }
2015 break;
2016 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002017 case PASSTHROUGH_ENTRY:
2018 {
2019 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2020 for (const auto &arg : method->args()) {
2021 out << "_hidl_args.push_back((void *)&"
2022 << arg->name()
2023 << ");\n";
2024 }
2025 break;
2026 }
2027 case PASSTHROUGH_EXIT:
2028 {
2029 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002030 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002031 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002032 << arg->name()
2033 << ");\n";
2034 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002035 break;
2036 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002037 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002038 {
Steven Morelandcbff5612017-10-11 17:01:54 -07002039 CHECK(false) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002040 }
2041 }
2042
Steven Moreland1ab31442016-11-03 18:37:51 -07002043 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002044 out.indent();
2045 out << "callback("
2046 << event_str
2047 << ", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07002048 << superInterface->fqName().package()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002049 << "\", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07002050 << superInterface->fqName().version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002051 << "\", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07002052 << superInterface->localName()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002053 << "\", \""
2054 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002055 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002056 out.unindent();
2057 out << "}\n";
2058 out.unindent();
Steven Moreland30b76e92017-06-02 18:52:24 -07002059 out << "}\n";
2060 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002061}
2062
Andreas Huber881227d2016-08-02 14:20:21 -07002063} // namespace android