blob: d7b59ebc7f0fdfc4e2750c84c8cdee40b2b39be8 [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 Moreland9b1cbdf2016-11-01 12:23:27 -0700479 generateCppInstrumentationCall(
480 out,
481 InstrumentationEvent::PASSTHROUGH_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700482 method,
483 superInterface);
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700484
Steven Moreland58a20c72018-10-09 12:30:51 -0700485 std::vector<std::string> wrappedArgNames;
Yifan Hong7a118f52016-12-07 11:21:15 -0800486 for (const auto &arg : method->args()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700487 std::string name = wrapPassthroughArg(out, arg, arg->name(), [&] {
Yifan Hong7a118f52016-12-07 11:21:15 -0800488 out << "return ::android::hardware::Status::fromExceptionCode(\n";
489 out.indent(2, [&] {
490 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
Yifan Hong0abd7392016-12-20 16:43:26 -0800491 << "\"Cannot wrap passthrough interface.\");\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800492 });
493 });
Steven Moreland58a20c72018-10-09 12:30:51 -0700494
495 wrappedArgNames.push_back(name);
Yifan Hong7a118f52016-12-07 11:21:15 -0800496 }
497
Steven Moreland58a20c72018-10-09 12:30:51 -0700498 out << "::android::hardware::Status _hidl_error = ::android::hardware::Status::ok();\n";
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700499 out << "auto _hidl_return = ";
Steven Moreland69e7c702016-09-09 11:16:32 -0700500
501 if (method->isOneway()) {
Steven Moreland836cb312017-06-05 17:25:55 -0700502 out << "addOnewayTask([mImpl = this->mImpl\n"
503 << "#ifdef __ANDROID_DEBUGGABLE__\n"
504 ", mEnableInstrumentation = this->mEnableInstrumentation, "
505 "mInstrumentationCallbacks = this->mInstrumentationCallbacks\n"
506 << "#endif // __ANDROID_DEBUGGABLE__\n";
Steven Moreland58a20c72018-10-09 12:30:51 -0700507 for (const std::string& arg : wrappedArgNames) {
508 out << ", " << arg;
Steven Moreland69e7c702016-09-09 11:16:32 -0700509 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700510 out << "] {\n";
511 out.indent();
Steven Moreland69e7c702016-09-09 11:16:32 -0700512 }
513
514 out << "mImpl->"
515 << method->name()
516 << "(";
517
Yifan Hong932464e2017-03-30 15:40:22 -0700518 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800519 out << (arg->type().isInterface() ? "_hidl_wrapped_" : "") << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700520 });
Steven Moreland58a20c72018-10-09 12:30:51 -0700521
522 std::function<void(void)> kHandlePassthroughError = [&] {
523 out << "_hidl_error = ::android::hardware::Status::fromExceptionCode(\n";
524 out.indent(2, [&] {
525 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
526 << "\"Cannot wrap passthrough interface.\");\n";
527 });
528 };
529
Steven Moreland69e7c702016-09-09 11:16:32 -0700530 if (returnsValue && elidedReturn == nullptr) {
Steven Moreland340c8822017-05-02 14:41:49 -0700531 // never true if oneway since oneway methods don't return values
532
Steven Moreland69e7c702016-09-09 11:16:32 -0700533 if (!method->args().empty()) {
534 out << ", ";
535 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800536 out << "[&](";
Yifan Hong932464e2017-03-30 15:40:22 -0700537 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Hong7a118f52016-12-07 11:21:15 -0800538 out << "const auto &_hidl_out_"
539 << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -0700540 });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800541
542 out << ") {\n";
543 out.indent();
Steven Moreland92a08a72017-07-31 14:57:37 -0700544 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800545 out,
546 InstrumentationEvent::PASSTHROUGH_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700547 method,
548 superInterface);
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800549
Steven Moreland58a20c72018-10-09 12:30:51 -0700550 std::vector<std::string> wrappedOutNames;
Yifan Hong7a118f52016-12-07 11:21:15 -0800551 for (const auto &arg : method->results()) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700552 wrappedOutNames.push_back(
553 wrapPassthroughArg(out, arg, "_hidl_out_" + arg->name(), kHandlePassthroughError));
Yifan Hong7a118f52016-12-07 11:21:15 -0800554 }
555
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800556 out << "_hidl_cb(";
Steven Moreland58a20c72018-10-09 12:30:51 -0700557 out.join(wrappedOutNames.begin(), wrappedOutNames.end(), ", ",
558 [&](const std::string& arg) { out << arg; });
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800559 out << ");\n";
560 out.unindent();
561 out << "});\n\n";
562 } else {
563 out << ");\n\n";
Steven Moreland30b76e92017-06-02 18:52:24 -0700564
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800565 if (elidedReturn != nullptr) {
Steven Moreland58a20c72018-10-09 12:30:51 -0700566 const std::string outName = "_hidl_out_" + elidedReturn->name();
567
568 out << elidedReturn->type().getCppResultType() << " " << outName
569 << " = _hidl_return;\n";
570 out << "(void) " << outName << ";\n";
571
572 const std::string wrappedName =
573 wrapPassthroughArg(out, elidedReturn, outName, kHandlePassthroughError);
574
575 if (outName != wrappedName) {
576 // update the original value since it is used by generateCppInstrumentationCall
577 out << outName << " = " << wrappedName << ";\n\n";
578
579 // update the value to be returned
580 out << "_hidl_return = " << outName << "\n;";
581 }
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800582 }
Steven Moreland92a08a72017-07-31 14:57:37 -0700583 generateCppInstrumentationCall(
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -0800584 out,
585 InstrumentationEvent::PASSTHROUGH_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -0700586 method,
587 superInterface);
Steven Moreland69e7c702016-09-09 11:16:32 -0700588 }
Steven Moreland69e7c702016-09-09 11:16:32 -0700589
590 if (method->isOneway()) {
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700591 out.unindent();
592 out << "});\n";
Steven Moreland58a20c72018-10-09 12:30:51 -0700593 } else {
594 out << "if (!_hidl_error.isOk()) return _hidl_error;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700595 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -0700596
597 out << "return _hidl_return;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700598
599 out.unindent();
600 out << "}\n";
Steven Moreland69e7c702016-09-09 11:16:32 -0700601}
602
Steven Moreland368e4602018-02-16 14:21:49 -0800603void AST::generateMethods(Formatter& out, const MethodGenerator& gen, bool includeParent) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700604 const Interface* iface = mRootScope.getInterface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700605
Yifan Hong10fe0b52016-10-19 14:20:17 -0700606 const Interface *prevIterface = nullptr;
607 for (const auto &tuple : iface->allMethodsFromRoot()) {
608 const Method *method = tuple.method();
609 const Interface *superInterface = tuple.interface();
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700610
Steven Morelandf16c5c02017-07-31 16:50:06 -0700611 if (!includeParent && superInterface != iface) {
612 continue;
613 }
614
Yifan Hong10fe0b52016-10-19 14:20:17 -0700615 if(prevIterface != superInterface) {
616 if (prevIterface != nullptr) {
617 out << "\n";
618 }
619 out << "// Methods from "
620 << superInterface->fullName()
621 << " follow.\n";
622 prevIterface = superInterface;
623 }
Steven Moreland368e4602018-02-16 14:21:49 -0800624 gen(method, superInterface);
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700625 }
626
Yifan Hong10fe0b52016-10-19 14:20:17 -0700627 out << "\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700628}
629
Steven Moreland0b843772017-06-23 16:33:38 -0700630void AST::generateTemplatizationLink(Formatter& out) const {
Steven Moreland7645fbd2019-03-12 18:49:28 -0700631 DocComment("The pure class is what this class wraps.").emit(out);
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700632 out << "typedef " << mRootScope.getInterface()->localName() << " Pure;\n\n";
Steven Moreland0b843772017-06-23 16:33:38 -0700633}
634
Steven Moreland1a52e822017-07-27 13:56:29 -0700635void AST::generateCppTag(Formatter& out, const std::string& tag) const {
636 out << "typedef " << tag << " _hidl_tag;\n\n";
637}
638
Steven Moreland368e4602018-02-16 14:21:49 -0800639void AST::generateStubHeader(Formatter& out) const {
Steven Moreland5abcf012018-02-08 18:50:18 -0800640 CHECK(AST::isInterface());
Andreas Huber881227d2016-08-02 14:20:21 -0700641
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700642 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800643 const std::string klassName = iface->getStubName();
Steven Moreland40786312016-08-16 10:29:40 -0700644 const std::string guard = makeHeaderGuard(klassName);
Andreas Huber881227d2016-08-02 14:20:21 -0700645
646 out << "#ifndef " << guard << "\n";
647 out << "#define " << guard << "\n\n";
648
Yifan Hongeefe4f22017-01-04 15:32:42 -0800649 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Moreland1a52e822017-07-27 13:56:29 -0700650
Steven Morelandee88eed2016-10-31 17:49:00 -0700651 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700652
653 enterLeaveNamespace(out, true /* enter */);
654 out << "\n";
655
656 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800657 << klassName;
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100658 if (iface->isIBase()) {
Yifan Hong96a79e22017-01-12 14:22:05 -0800659 out << " : public ::android::hardware::BHwBinder";
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000660 out << ", public ::android::hardware::details::HidlInstrumentor {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100661 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800662 out << " : public "
663 << gIBaseFqName.getInterfaceStubFqName().cppName()
664 << " {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100665 }
Andreas Huber881227d2016-08-02 14:20:21 -0700666
667 out.indent();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800668 out << "explicit "
669 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -0700670 << "(const ::android::sp<" << iface->localName() << "> &_hidl_impl);"
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100671 << "\n";
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,"
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -0800675 << " const std::string& HidlInstrumentor_package,"
676 << " const std::string& HidlInstrumentor_interface);"
Steven Moreland40786312016-08-16 10:29:40 -0700677 << "\n\n";
Steven Moreland57a89362017-07-21 19:29:54 +0000678 out << "virtual ~" << klassName << "();\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700679 out << "::android::status_t onTransact(\n";
680 out.indent();
681 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -0700682 out << "uint32_t _hidl_code,\n";
683 out << "const ::android::hardware::Parcel &_hidl_data,\n";
684 out << "::android::hardware::Parcel *_hidl_reply,\n";
685 out << "uint32_t _hidl_flags = 0,\n";
Iliyan Malchev62c3d182016-08-16 20:33:39 -0700686 out << "TransactCallback _hidl_cb = nullptr) override;\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700687 out.unindent();
688 out.unindent();
689
Steven Moreland0b843772017-06-23 16:33:38 -0700690 out.endl();
691 generateTemplatizationLink(out);
Steven Moreland7645fbd2019-03-12 18:49:28 -0700692 DocComment("Type tag for use in template logic that indicates this is a 'native' class.")
693 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700694 generateCppTag(out, "android::hardware::details::bnhw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700695
Steven Morelandcbcf9f72017-11-20 10:04:15 -0800696 out << "::android::sp<" << iface->localName() << "> getImpl() { return _hidl_mImpl; }\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700697
Steven Moreland173c4c92019-05-20 10:46:27 -0700698 // Because the Bn class hierarchy always inherits from BnHwBase (and no other parent classes)
699 // and also no HIDL-specific things exist in the base binder classes, whenever we want to do
700 // C++ HIDL things with a binder, we only have the choice to convert it into a BnHwBase.
701 // Other hwbinder C++ class hierarchies (namely the one used for Java binder) will still
702 // be libhwbinder binders, but they are not instances of BnHwBase.
703 if (isIBase()) {
704 out << "bool checkSubclass(const void* subclassID) const;\n";
705 }
706
Steven Moreland368e4602018-02-16 14:21:49 -0800707 generateMethods(out,
708 [&](const Method* method, const Interface*) {
709 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
710 return;
711 }
Steven Morelandf16c5c02017-07-31 16:50:06 -0700712
Steven Moreland368e4602018-02-16 14:21:49 -0800713 out << "static ::android::status_t _hidl_" << method->name() << "(\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700714
Steven Moreland368e4602018-02-16 14:21:49 -0800715 out.indent(2,
716 [&] {
717 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
718 << "const ::android::hardware::Parcel &_hidl_data,\n"
719 << "::android::hardware::Parcel *_hidl_reply,\n"
720 << "TransactCallback _hidl_cb);\n";
721 })
722 .endl()
723 .endl();
724 },
725 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -0700726
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100727 out.unindent();
728 out << "private:\n";
729 out.indent();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800730
Steven Moreland368e4602018-02-16 14:21:49 -0800731 generateMethods(out, [&](const Method* method, const Interface* iface) {
Yifan Hongcd2ae452017-01-31 14:33:40 -0800732 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
Steven Moreland368e4602018-02-16 14:21:49 -0800733 return;
Yifan Hongcd2ae452017-01-31 14:33:40 -0800734 }
735 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700736 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Yifan Hongcd2ae452017-01-31 14:33:40 -0800737
738 if (elidedReturn == nullptr && returnsValue) {
739 out << "using " << method->name() << "_cb = "
740 << iface->fqName().cppName()
741 << "::" << method->name() << "_cb;\n";
742 }
743 method->generateCppSignature(out);
Yifan Hongbcffce22017-02-01 15:52:06 -0800744 out << ";\n";
Yifan Hongcd2ae452017-01-31 14:33:40 -0800745 });
Yifan Hongcd2ae452017-01-31 14:33:40 -0800746
Steven Moreland19f11b52017-05-12 18:22:21 -0700747 out << "::android::sp<" << iface->localName() << "> _hidl_mImpl;\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700748 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700749 out << "};\n\n";
750
751 enterLeaveNamespace(out, false /* enter */);
752
753 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700754}
755
Steven Moreland368e4602018-02-16 14:21:49 -0800756void AST::generateProxyHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700757 if (!AST::isInterface()) {
Andreas Huber881227d2016-08-02 14:20:21 -0700758 // types.hal does not get a proxy header.
Steven Moreland368e4602018-02-16 14:21:49 -0800759 return;
Andreas Huber881227d2016-08-02 14:20:21 -0700760 }
761
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700762 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800763 const std::string proxyName = iface->getProxyName();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800764 const std::string guard = makeHeaderGuard(proxyName);
Andreas Huber881227d2016-08-02 14:20:21 -0700765
766 out << "#ifndef " << guard << "\n";
767 out << "#define " << guard << "\n\n";
768
Martijn Coenen115d4282016-12-19 05:14:04 +0100769 out << "#include <hidl/HidlTransportSupport.h>\n\n";
770
Andreas Huber881227d2016-08-02 14:20:21 -0700771 std::vector<std::string> packageComponents;
772 getPackageAndVersionComponents(
773 &packageComponents, false /* cpp_compatible */);
774
Yifan Hongeefe4f22017-01-04 15:32:42 -0800775 generateCppPackageInclude(out, mPackage, iface->getHwName());
Steven Morelandee88eed2016-10-31 17:49:00 -0700776 out << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700777
778 enterLeaveNamespace(out, true /* enter */);
779 out << "\n";
780
781 out << "struct "
Yifan Hongeefe4f22017-01-04 15:32:42 -0800782 << proxyName
783 << " : public ::android::hardware::BpInterface<"
784 << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +0000785 << ">, public ::android::hardware::details::HidlInstrumentor {\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700786
787 out.indent();
788
Yifan Hongeefe4f22017-01-04 15:32:42 -0800789 out << "explicit "
790 << proxyName
Iliyan Malchev549e2592016-08-10 08:59:12 -0700791 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);"
Andreas Huber881227d2016-08-02 14:20:21 -0700792 << "\n\n";
793
Steven Moreland0b843772017-06-23 16:33:38 -0700794 generateTemplatizationLink(out);
Steven Moreland7645fbd2019-03-12 18:49:28 -0700795 DocComment("Type tag for use in template logic that indicates this is a 'proxy' class.")
796 .emit(out);
Steven Moreland1a52e822017-07-27 13:56:29 -0700797 generateCppTag(out, "android::hardware::details::bphw_tag");
Steven Moreland0b843772017-06-23 16:33:38 -0700798
Yifan Hong10fe0b52016-10-19 14:20:17 -0700799 out << "virtual bool isRemote() const override { return true; }\n\n";
Steven Moreland40786312016-08-16 10:29:40 -0700800
Steven Moreland368e4602018-02-16 14:21:49 -0800801 generateMethods(
802 out,
803 [&](const Method* method, const Interface*) {
804 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
805 return;
806 }
Steven Morelandf16c5c02017-07-31 16:50:06 -0700807
Steven Moreland368e4602018-02-16 14:21:49 -0800808 out << "static ";
809 method->generateCppReturnType(out);
810 out << " _hidl_" << method->name() << "("
811 << "::android::hardware::IInterface* _hidl_this, "
812 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
Steven Morelandf16c5c02017-07-31 16:50:06 -0700813
Steven Moreland368e4602018-02-16 14:21:49 -0800814 if (!method->hasEmptyCppArgSignature()) {
815 out << ", ";
816 }
817 method->emitCppArgSignature(out);
818 out << ");\n";
819 },
820 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -0700821
Steven Moreland368e4602018-02-16 14:21:49 -0800822 generateMethods(out, [&](const Method* method, const Interface*) {
Yifan Hong068c5522016-10-31 14:07:25 -0700823 method->generateCppSignature(out);
824 out << " override;\n";
Yifan Hong068c5522016-10-31 14:07:25 -0700825 });
Steven Moreland9c387612016-09-07 09:54:26 -0700826
Andreas Huber881227d2016-08-02 14:20:21 -0700827 out.unindent();
Martijn Coenen115d4282016-12-19 05:14:04 +0100828 out << "private:\n";
829 out.indent();
830 out << "std::mutex _hidl_mMutex;\n"
831 << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
832 << " _hidl_mDeathRecipients;\n";
833 out.unindent();
Andreas Huber881227d2016-08-02 14:20:21 -0700834 out << "};\n\n";
835
836 enterLeaveNamespace(out, false /* enter */);
837
838 out << "\n#endif // " << guard << "\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700839}
840
Steven Moreland368e4602018-02-16 14:21:49 -0800841void AST::generateCppSource(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -0700842 std::string baseName = getBaseName();
843 const Interface *iface = getInterface();
Andreas Huber881227d2016-08-02 14:20:21 -0700844
Steven Morelanda885d252017-09-25 18:44:43 -0700845 const std::string klassName = baseName + (baseName == "types" ? "" : "All");
Andreas Huber881227d2016-08-02 14:20:21 -0700846
Steven Moreland623c0042017-01-13 14:42:29 -0800847 out << "#define LOG_TAG \""
848 << mPackage.string() << "::" << baseName
849 << "\"\n\n";
850
Steven Moreland5add34d2018-11-08 16:31:30 -0800851 out << "#include <log/log.h>\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +0100852 out << "#include <cutils/trace.h>\n";
853 out << "#include <hidl/HidlTransportSupport.h>\n\n";
Steven Moreland26896a92018-07-31 15:31:01 -0700854 out << "#include <hidl/Static.h>\n";
855 out << "#include <hwbinder/ProcessState.h>\n";
Steven Moreland4607ef52018-05-09 10:52:47 -0700856 out << "#include <utils/Trace.h>\n";
Steven Moreland19f11b52017-05-12 18:22:21 -0700857 if (iface) {
Steven Moreland19d5c172016-10-20 19:20:25 -0700858 // This is a no-op for IServiceManager itself.
859 out << "#include <android/hidl/manager/1.0/IServiceManager.h>\n";
860
Yifan Hongeefe4f22017-01-04 15:32:42 -0800861 generateCppPackageInclude(out, mPackage, iface->getProxyName());
862 generateCppPackageInclude(out, mPackage, iface->getStubName());
863 generateCppPackageInclude(out, mPackage, iface->getPassthroughName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700864
865 for (const Interface *superType : iface->superTypeChain()) {
Steven Morelandee88eed2016-10-31 17:49:00 -0700866 generateCppPackageInclude(out,
867 superType->fqName(),
Yifan Hongeefe4f22017-01-04 15:32:42 -0800868 superType->fqName().getInterfaceProxyName());
Yifan Hongfe95aa22016-10-19 17:26:45 -0700869 }
Yifan Hong2cbbdf92016-12-05 15:20:50 -0800870
871 out << "#include <hidl/ServiceManagement.h>\n";
Andreas Huber881227d2016-08-02 14:20:21 -0700872 } else {
Steven Morelandee88eed2016-10-31 17:49:00 -0700873 generateCppPackageInclude(out, mPackage, "types");
Yifan Hong244e82d2016-11-11 11:13:57 -0800874 generateCppPackageInclude(out, mPackage, "hwtypes");
Andreas Huber881227d2016-08-02 14:20:21 -0700875 }
876
877 out << "\n";
878
879 enterLeaveNamespace(out, true /* enter */);
880 out << "\n";
881
Steven Moreland368e4602018-02-16 14:21:49 -0800882 generateTypeSource(out, iface ? iface->localName() : "");
Andreas Huber881227d2016-08-02 14:20:21 -0700883
Steven Moreland368e4602018-02-16 14:21:49 -0800884 if (iface) {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -0700885 const Interface* iface = mRootScope.getInterface();
Yifan Hong10fe0b52016-10-19 14:20:17 -0700886
887 // need to be put here, generateStubSource is using this.
Yifan Hongeefe4f22017-01-04 15:32:42 -0800888 out << "const char* "
889 << iface->localName()
Yifan Hong10fe0b52016-10-19 14:20:17 -0700890 << "::descriptor(\""
891 << iface->fqName().string()
892 << "\");\n\n";
Yifan Hong91977fd2017-11-09 16:07:37 -0800893 out << "__attribute__((constructor)) ";
Martijn Coenen8adcb652017-02-03 17:37:36 +0100894 out << "static void static_constructor() {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800895 out.indent([&] {
Yifan Hong91977fd2017-11-09 16:07:37 -0800896 out << "::android::hardware::details::getBnConstructorMap().set("
Yifan Hongeefe4f22017-01-04 15:32:42 -0800897 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -0800898 << "::descriptor,\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800899 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -0800900 out << "[](void *iIntf) -> ::android::sp<::android::hardware::IBinder> {\n";
Yifan Hong33223ca2016-12-13 15:07:35 -0800901 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800902 out << "return new "
903 << iface->getStubName()
Yifan Hong341112d2017-04-20 18:12:05 -0700904 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -0800905 << iface->localName()
Yifan Hong158655a2016-11-08 12:34:07 -0800906 << " *>(iIntf));\n";
907 });
Yifan Hongb04de382017-02-06 15:31:52 -0800908 out << "});\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800909 });
Yifan Hong91977fd2017-11-09 16:07:37 -0800910 out << "::android::hardware::details::getBsConstructorMap().set("
Yifan Hongeefe4f22017-01-04 15:32:42 -0800911 << iface->localName()
Yifan Hongb04de382017-02-06 15:31:52 -0800912 << "::descriptor,\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800913 out.indent(2, [&] {
Yifan Hongb04de382017-02-06 15:31:52 -0800914 out << "[](void *iIntf) -> ::android::sp<"
Yifan Hong7a118f52016-12-07 11:21:15 -0800915 << gIBaseFqName.cppName()
916 << "> {\n";
917 out.indent([&] {
Yifan Hongeefe4f22017-01-04 15:32:42 -0800918 out << "return new "
919 << iface->getPassthroughName()
Yifan Hong341112d2017-04-20 18:12:05 -0700920 << "(static_cast<"
Yifan Hongeefe4f22017-01-04 15:32:42 -0800921 << iface->localName()
Yifan Hong7a118f52016-12-07 11:21:15 -0800922 << " *>(iIntf));\n";
923 });
Yifan Hongb04de382017-02-06 15:31:52 -0800924 out << "});\n";
Yifan Hong7a118f52016-12-07 11:21:15 -0800925 });
Yifan Hong158655a2016-11-08 12:34:07 -0800926 });
Martijn Coenen8adcb652017-02-03 17:37:36 +0100927 out << "};\n\n";
928 out << "__attribute__((destructor))";
929 out << "static void static_destructor() {\n";
930 out.indent([&] {
Yifan Hong91977fd2017-11-09 16:07:37 -0800931 out << "::android::hardware::details::getBnConstructorMap().erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +0100932 << iface->localName()
933 << "::descriptor);\n";
Yifan Hong91977fd2017-11-09 16:07:37 -0800934 out << "::android::hardware::details::getBsConstructorMap().erase("
Martijn Coenen8adcb652017-02-03 17:37:36 +0100935 << iface->localName()
936 << "::descriptor);\n";
937 });
938 out << "};\n\n";
Yifan Hong158655a2016-11-08 12:34:07 -0800939
Steven Moreland368e4602018-02-16 14:21:49 -0800940 generateInterfaceSource(out);
941 generateProxySource(out, iface->fqName());
942 generateStubSource(out, iface);
943 generatePassthroughSource(out);
Steven Moreland9c387612016-09-07 09:54:26 -0700944
Yifan Hongc8934042016-11-17 17:10:52 -0800945 if (isIBase()) {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800946 out << "// skipped getService, registerAsService, registerForNotifications\n";
Yifan Hongc8934042016-11-17 17:10:52 -0800947 } else {
Yifan Hong83c8e5f2016-12-13 14:33:53 -0800948 std::string package = iface->fqName().package()
949 + iface->fqName().atVersion();
950
Yifan Hongeefe4f22017-01-04 15:32:42 -0800951 implementServiceManagerInteractions(out, iface->fqName(), package);
Yifan Hongc8934042016-11-17 17:10:52 -0800952 }
Steven Moreland40786312016-08-16 10:29:40 -0700953 }
954
Andreas Huber6755e9d2017-04-06 11:09:07 -0700955 HidlTypeAssertion::EmitAll(out);
956 out << "\n";
957
Andreas Huber881227d2016-08-02 14:20:21 -0700958 enterLeaveNamespace(out, false /* enter */);
Andreas Huber881227d2016-08-02 14:20:21 -0700959}
960
Steven Moreland368e4602018-02-16 14:21:49 -0800961void AST::generateTypeSource(Formatter& out, const std::string& ifaceName) const {
962 mRootScope.emitTypeDefinitions(out, ifaceName);
Andreas Huber881227d2016-08-02 14:20:21 -0700963}
964
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700965void AST::declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& args,
966 bool forResults) const {
Andreas Hubere7ff2282016-08-16 13:50:03 -0700967 if (args.empty()) {
968 return;
969 }
970
971 for (const auto &arg : args) {
972 const Type &type = arg->type();
973
Yifan Hong3b320f82016-11-01 15:15:54 -0700974 out << type.getCppResultType()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700975 << " "
Yifan Hong3b320f82016-11-01 15:15:54 -0700976 << (forResults ? "_hidl_out_" : "") + arg->name()
Andreas Hubere7ff2282016-08-16 13:50:03 -0700977 << ";\n";
978 }
979
980 out << "\n";
981}
982
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700983void AST::emitCppReaderWriter(Formatter& out, const std::string& parcelObj, bool parcelObjIsPointer,
984 const NamedReference<Type>* arg, bool isReader, Type::ErrorMode mode,
985 bool addPrefixToName) const {
Andreas Huber881227d2016-08-02 14:20:21 -0700986 const Type &type = arg->type();
987
Andreas Huber881227d2016-08-02 14:20:21 -0700988 type.emitReaderWriter(
989 out,
Andreas Huber5e44a292016-09-27 14:52:39 -0700990 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
Andreas Huber881227d2016-08-02 14:20:21 -0700991 parcelObj,
992 parcelObjIsPointer,
993 isReader,
994 mode);
995}
996
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700997void AST::emitCppResolveReferences(Formatter& out, const std::string& parcelObj,
998 bool parcelObjIsPointer, const NamedReference<Type>* arg,
999 bool isReader, Type::ErrorMode mode,
1000 bool addPrefixToName) const {
Yifan Hongbf459bc2016-08-23 16:50:37 -07001001 const Type &type = arg->type();
1002 if(type.needsResolveReferences()) {
1003 type.emitResolveReferences(
1004 out,
1005 addPrefixToName ? ("_hidl_out_" + arg->name()) : arg->name(),
1006 isReader, // nameIsPointer
1007 parcelObj,
1008 parcelObjIsPointer,
1009 isReader,
1010 mode);
1011 }
1012}
1013
Steven Moreland368e4602018-02-16 14:21:49 -08001014void AST::generateProxyMethodSource(Formatter& out, const std::string& klassName,
1015 const Method* method, const Interface* superInterface) const {
Yifan Hong068c5522016-10-31 14:07:25 -07001016 method->generateCppSignature(out,
1017 klassName,
1018 true /* specify namespaces */);
1019
Martijn Coenen115d4282016-12-19 05:14:04 +01001020 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001021 out.block([&] {
1022 method->cppImpl(IMPL_PROXY, out);
1023 }).endl().endl();
Steven Moreland368e4602018-02-16 14:21:49 -08001024 return;
Martijn Coenen115d4282016-12-19 05:14:04 +01001025 }
1026
Steven Morelandf16c5c02017-07-31 16:50:06 -07001027 out.block([&] {
1028 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001029 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001030
1031 method->generateCppReturnType(out);
1032
1033 out << " _hidl_out = "
1034 << superInterface->fqName().cppNamespace()
1035 << "::"
1036 << superInterface->getProxyName()
1037 << "::_hidl_"
1038 << method->name()
1039 << "(this, this";
1040
1041 if (!method->hasEmptyCppArgSignature()) {
1042 out << ", ";
1043 }
1044
1045 out.join(method->args().begin(), method->args().end(), ", ", [&](const auto &arg) {
1046 out << arg->name();
1047 });
1048
1049 if (returnsValue && elidedReturn == nullptr) {
1050 if (!method->args().empty()) {
1051 out << ", ";
1052 }
1053 out << "_hidl_cb";
1054 }
1055
1056 out << ");\n\n";
1057
1058 out << "return _hidl_out;\n";
1059 }).endl().endl();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001060}
1061
Steven Moreland368e4602018-02-16 14:21:49 -08001062void AST::generateStaticProxyMethodSource(Formatter& out, const std::string& klassName,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001063 const Method* method, const Interface* superInterface) const {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001064 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001065 return;
Steven Morelandf16c5c02017-07-31 16:50:06 -07001066 }
1067
1068 method->generateCppReturnType(out);
1069
1070 out << klassName
1071 << "::_hidl_"
1072 << method->name()
1073 << "("
1074 << "::android::hardware::IInterface *_hidl_this, "
1075 << "::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor";
1076
1077 if (!method->hasEmptyCppArgSignature()) {
1078 out << ", ";
1079 }
1080
1081 method->emitCppArgSignature(out);
1082 out << ") {\n";
1083
1084 out.indent();
1085
1086 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1087 out << "bool mEnableInstrumentation = _hidl_this_instrumentor->isInstrumentationEnabled();\n";
1088 out << "const auto &mInstrumentationCallbacks = _hidl_this_instrumentor->getInstrumentationCallbacks();\n";
1089 out << "#else\n";
1090 out << "(void) _hidl_this_instrumentor;\n";
1091 out << "#endif // __ANDROID_DEBUGGABLE__\n";
1092
1093 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001094 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland48cc6042019-04-30 11:28:56 -07001095 const bool hasCallback = returnsValue && elidedReturn == nullptr;
1096
Steven Moreland92a08a72017-07-31 14:57:37 -07001097 generateCppInstrumentationCall(
Yifan Hong068c5522016-10-31 14:07:25 -07001098 out,
1099 InstrumentationEvent::CLIENT_API_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001100 method,
1101 superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001102
1103 out << "::android::hardware::Parcel _hidl_data;\n";
1104 out << "::android::hardware::Parcel _hidl_reply;\n";
1105 out << "::android::status_t _hidl_err;\n";
Steven Moreland48cc6042019-04-30 11:28:56 -07001106 out << "::android::status_t _hidl_transact_err;\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001107 out << "::android::hardware::Status _hidl_status;\n\n";
1108
Steven Moreland48cc6042019-04-30 11:28:56 -07001109 if (!hasCallback) {
1110 declareCppReaderLocals(
1111 out, method->results(), true /* forResults */);
1112 }
Yifan Hong068c5522016-10-31 14:07:25 -07001113
1114 out << "_hidl_err = _hidl_data.writeInterfaceToken(";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001115 out << klassName;
Yifan Hong068c5522016-10-31 14:07:25 -07001116 out << "::descriptor);\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001117 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
1118
Martijn Coenenfff73352017-01-04 16:36:31 +01001119 bool hasInterfaceArgument = false;
Yifan Hong068c5522016-10-31 14:07:25 -07001120 // First DFS: write all buffers and resolve pointers for parent
1121 for (const auto &arg : method->args()) {
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001122 if (arg->type().isInterface()) {
1123 hasInterfaceArgument = true;
1124 }
Yifan Hong068c5522016-10-31 14:07:25 -07001125 emitCppReaderWriter(
1126 out,
1127 "_hidl_data",
1128 false /* parcelObjIsPointer */,
1129 arg,
1130 false /* reader */,
1131 Type::ErrorMode_Goto,
1132 false /* addPrefixToName */);
1133 }
1134
1135 // Second DFS: resolve references.
1136 for (const auto &arg : method->args()) {
1137 emitCppResolveReferences(
1138 out,
1139 "_hidl_data",
1140 false /* parcelObjIsPointer */,
1141 arg,
1142 false /* reader */,
1143 Type::ErrorMode_Goto,
1144 false /* addPrefixToName */);
1145 }
1146
Martijn Coenenfa55d6e2016-12-20 06:08:31 +01001147 if (hasInterfaceArgument) {
1148 // Start binder threadpool to handle incoming transactions
1149 out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
1150 }
Steven Moreland48cc6042019-04-30 11:28:56 -07001151 out << "_hidl_transact_err = ::android::hardware::IInterface::asBinder(_hidl_this)->transact("
Yifan Hong068c5522016-10-31 14:07:25 -07001152 << method->getSerialId()
1153 << " /* "
1154 << method->name()
1155 << " */, _hidl_data, &_hidl_reply";
1156
1157 if (method->isOneway()) {
Steven Moreland77943692018-08-09 12:53:42 -07001158 out << ", " << Interface::FLAG_ONE_WAY->cppValue();
Steven Moreland48cc6042019-04-30 11:28:56 -07001159 } else {
1160 out << ", 0";
Yifan Hong068c5522016-10-31 14:07:25 -07001161 }
Yifan Hong068c5522016-10-31 14:07:25 -07001162
Steven Moreland48cc6042019-04-30 11:28:56 -07001163 if (hasCallback) {
1164 out << ", [&] (::android::hardware::Parcel& _hidl_reply) {\n";
1165 out.indent();
1166 declareCppReaderLocals(
1167 out, method->results(), true /* forResults */);
1168 out.endl();
1169 } else {
1170 out << ");\n";
1171 out << "if (_hidl_transact_err != ::android::OK) \n";
1172 out.block([&] {
1173 out << "_hidl_err = _hidl_transact_err;\n";
1174 out << "goto _hidl_error;\n";
1175 }).endl().endl();
1176 }
Yifan Hong068c5522016-10-31 14:07:25 -07001177
1178 if (!method->isOneway()) {
Steven Moreland48cc6042019-04-30 11:28:56 -07001179 Type::ErrorMode errorMode = hasCallback ? Type::ErrorMode_ReturnNothing : Type::ErrorMode_Goto;
Yifan Hong068c5522016-10-31 14:07:25 -07001180
Steven Moreland48cc6042019-04-30 11:28:56 -07001181 out << "_hidl_err = ::android::hardware::readFromParcel(&_hidl_status, _hidl_reply);\n";
1182 Type::handleError(out, errorMode);
1183
1184 if (hasCallback) {
1185 out << "if (!_hidl_status.isOk()) { return; }\n\n";
1186 } else {
1187 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n\n";
1188 }
Yifan Hong068c5522016-10-31 14:07:25 -07001189
1190 // First DFS: write all buffers and resolve pointers for parent
1191 for (const auto &arg : method->results()) {
1192 emitCppReaderWriter(
1193 out,
1194 "_hidl_reply",
1195 false /* parcelObjIsPointer */,
1196 arg,
1197 true /* reader */,
Steven Moreland48cc6042019-04-30 11:28:56 -07001198 errorMode,
Yifan Hong068c5522016-10-31 14:07:25 -07001199 true /* addPrefixToName */);
1200 }
1201
1202 // Second DFS: resolve references.
1203 for (const auto &arg : method->results()) {
1204 emitCppResolveReferences(
1205 out,
1206 "_hidl_reply",
1207 false /* parcelObjIsPointer */,
1208 arg,
1209 true /* reader */,
Steven Moreland48cc6042019-04-30 11:28:56 -07001210 errorMode,
Yifan Hong068c5522016-10-31 14:07:25 -07001211 true /* addPrefixToName */);
1212 }
1213
1214 if (returnsValue && elidedReturn == nullptr) {
1215 out << "_hidl_cb(";
1216
Yifan Hong932464e2017-03-30 15:40:22 -07001217 out.join(method->results().begin(), method->results().end(), ", ", [&] (const auto &arg) {
Yifan Hong068c5522016-10-31 14:07:25 -07001218 if (arg->type().resultNeedsDeref()) {
1219 out << "*";
1220 }
1221 out << "_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001222 });
Yifan Hong068c5522016-10-31 14:07:25 -07001223
1224 out << ");\n\n";
1225 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001226 }
Steven Morelandf16c5c02017-07-31 16:50:06 -07001227
Steven Moreland92a08a72017-07-31 14:57:37 -07001228 generateCppInstrumentationCall(
Martijn Coenen7b295242016-11-04 16:52:56 +01001229 out,
1230 InstrumentationEvent::CLIENT_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001231 method,
1232 superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001233
Steven Moreland48cc6042019-04-30 11:28:56 -07001234 if (hasCallback) {
1235 out.unindent();
1236 out << "});\n";
1237 out << "if (_hidl_transact_err != ::android::OK) ";
1238 out.block([&] {
1239 out << "_hidl_err = _hidl_transact_err;\n";
1240 out << "goto _hidl_error;\n";
1241 }).endl().endl();
1242 out << "if (!_hidl_status.isOk()) { return _hidl_status; }\n";
1243 }
1244
Yifan Hong068c5522016-10-31 14:07:25 -07001245 if (elidedReturn != nullptr) {
Yifan Hong068c5522016-10-31 14:07:25 -07001246 out << "return ::android::hardware::Return<";
Yifan Hong3b320f82016-11-01 15:15:54 -07001247 out << elidedReturn->type().getCppResultType()
Yifan Hong068c5522016-10-31 14:07:25 -07001248 << ">(_hidl_out_" << elidedReturn->name() << ");\n\n";
1249 } else {
Yifan Hong068c5522016-10-31 14:07:25 -07001250 out << "return ::android::hardware::Return<void>();\n\n";
1251 }
1252
1253 out.unindent();
1254 out << "_hidl_error:\n";
1255 out.indent();
1256 out << "_hidl_status.setFromStatusT(_hidl_err);\n";
1257 out << "return ::android::hardware::Return<";
1258 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001259 out << method->results().at(0)->type().getCppResultType();
Yifan Hong068c5522016-10-31 14:07:25 -07001260 } else {
1261 out << "void";
1262 }
1263 out << ">(_hidl_status);\n";
1264
1265 out.unindent();
1266 out << "}\n\n";
Yifan Hong068c5522016-10-31 14:07:25 -07001267}
1268
Steven Moreland368e4602018-02-16 14:21:49 -08001269void AST::generateProxySource(Formatter& out, const FQName& fqName) const {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001270 const std::string klassName = fqName.getInterfaceProxyName();
Andreas Huber881227d2016-08-02 14:20:21 -07001271
1272 out << klassName
1273 << "::"
1274 << klassName
Iliyan Malchev549e2592016-08-10 08:59:12 -07001275 << "(const ::android::sp<::android::hardware::IBinder> &_hidl_impl)\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001276
1277 out.indent();
1278 out.indent();
1279
1280 out << ": BpInterface"
Yifan Hongeefe4f22017-01-04 15:32:42 -08001281 << "<"
1282 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001283 << ">(_hidl_impl),\n"
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001284 << " ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001285 << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001286 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001287 << fqName.getInterfaceName()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001288 << "\") {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001289
Andreas Huber881227d2016-08-02 14:20:21 -07001290 out.unindent();
1291 out.unindent();
1292 out << "}\n\n";
1293
Steven Moreland368e4602018-02-16 14:21:49 -08001294 generateMethods(out,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001295 [&](const Method* method, const Interface* superInterface) {
1296 generateStaticProxyMethodSource(out, klassName, method, superInterface);
Steven Moreland368e4602018-02-16 14:21:49 -08001297 },
1298 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -07001299
Steven Moreland368e4602018-02-16 14:21:49 -08001300 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1301 generateProxyMethodSource(out, klassName, method, superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001302 });
Andreas Huber881227d2016-08-02 14:20:21 -07001303}
1304
Steven Moreland368e4602018-02-16 14:21:49 -08001305void AST::generateStubSource(Formatter& out, const Interface* iface) const {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001306 const std::string interfaceName = iface->localName();
1307 const std::string klassName = iface->getStubName();
Andreas Huber881227d2016-08-02 14:20:21 -07001308
Steven Moreland40786312016-08-16 10:29:40 -07001309 out << klassName
1310 << "::"
1311 << klassName
Yifan Hongeefe4f22017-01-04 15:32:42 -08001312 << "(const ::android::sp<" << interfaceName <<"> &_hidl_impl)\n";
Steven Moreland40786312016-08-16 10:29:40 -07001313
1314 out.indent();
1315 out.indent();
1316
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001317 if (iface->isIBase()) {
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001318 out << ": ::android::hardware::details::HidlInstrumentor(\"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001319 } else {
Yifan Hongeefe4f22017-01-04 15:32:42 -08001320 out << ": "
1321 << gIBaseFqName.getInterfaceStubFqName().cppName()
1322 << "(_hidl_impl, \"";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001323 }
1324
1325 out << mPackage.string()
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001326 << "\", \""
Yifan Hongeefe4f22017-01-04 15:32:42 -08001327 << interfaceName
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001328 << "\") { \n";
1329 out.indent();
1330 out << "_hidl_mImpl = _hidl_impl;\n";
Steven Morelandbd984412019-04-22 10:25:46 -07001331 out << "auto prio = ::android::hardware::details::gServicePrioMap->get("
Martijn Coenenb4d77952017-05-03 13:44:29 -07001332 << "_hidl_impl, {SCHED_NORMAL, 0});\n";
1333 out << "mSchedPolicy = prio.sched_policy;\n";
1334 out << "mSchedPriority = prio.prio;\n";
Steven Morelandbd984412019-04-22 10:25:46 -07001335 out << "setRequestingSid(::android::hardware::details::gServiceSidMap->get(_hidl_impl, "
1336 "false));\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001337 out.unindent();
Steven Moreland40786312016-08-16 10:29:40 -07001338
1339 out.unindent();
1340 out.unindent();
1341 out << "}\n\n";
1342
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001343 if (iface->isIBase()) {
Yifan Hong01e7cde2017-01-09 17:45:45 -08001344 // BnHwBase has a constructor to initialize the HidlInstrumentor
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001345 // class properly.
1346 out << klassName
1347 << "::"
1348 << klassName
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001349 << "(const ::android::sp<" << interfaceName << "> &_hidl_impl,"
1350 << " const std::string &HidlInstrumentor_package,"
1351 << " const std::string &HidlInstrumentor_interface)\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001352
1353 out.indent();
1354 out.indent();
1355
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001356 out << ": ::android::hardware::details::HidlInstrumentor("
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001357 << "HidlInstrumentor_package, HidlInstrumentor_interface) {\n";
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001358 out.indent();
1359 out << "_hidl_mImpl = _hidl_impl;\n";
1360 out.unindent();
1361
1362 out.unindent();
1363 out.unindent();
1364 out << "}\n\n";
1365 }
1366
Steven Moreland57a89362017-07-21 19:29:54 +00001367 out << klassName << "::~" << klassName << "() ";
1368 out.block([&]() {
Steven Morelandbd984412019-04-22 10:25:46 -07001369 out << "::android::hardware::details::gBnMap->eraseIfEqual(_hidl_mImpl.get(), this);\n";
1370 })
1371 .endl()
1372 .endl();
Steven Moreland57a89362017-07-21 19:29:54 +00001373
Steven Moreland173c4c92019-05-20 10:46:27 -07001374 if (isIBase()) {
1375 out << "bool " << klassName << "::checkSubclass(const void* subclassID) const ";
1376 out.block([&] { out << "return subclassID == " << interfaceName << "::descriptor;\n"; });
1377 }
1378
Steven Moreland368e4602018-02-16 14:21:49 -08001379 generateMethods(out,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001380 [&](const Method* method, const Interface* superInterface) {
1381 return generateStaticStubMethodSource(out, iface->fqName(), method, superInterface);
Steven Moreland368e4602018-02-16 14:21:49 -08001382 },
1383 false /* include parents */);
Steven Morelandf16c5c02017-07-31 16:50:06 -07001384
Steven Moreland368e4602018-02-16 14:21:49 -08001385 generateMethods(out, [&](const Method* method, const Interface*) {
Yifan Hongbcffce22017-02-01 15:52:06 -08001386 if (!method->isHidlReserved() || !method->overridesCppImpl(IMPL_STUB_IMPL)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001387 return;
Yifan Hongbcffce22017-02-01 15:52:06 -08001388 }
1389 method->generateCppSignature(out, iface->getStubName());
1390 out << " ";
1391 out.block([&] {
1392 method->cppImpl(IMPL_STUB_IMPL, out);
1393 }).endl();
Yifan Hongbcffce22017-02-01 15:52:06 -08001394 });
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001395
Andreas Huber881227d2016-08-02 14:20:21 -07001396 out << "::android::status_t " << klassName << "::onTransact(\n";
1397
1398 out.indent();
1399 out.indent();
1400
Iliyan Malchev549e2592016-08-10 08:59:12 -07001401 out << "uint32_t _hidl_code,\n"
1402 << "const ::android::hardware::Parcel &_hidl_data,\n"
1403 << "::android::hardware::Parcel *_hidl_reply,\n"
1404 << "uint32_t _hidl_flags,\n"
1405 << "TransactCallback _hidl_cb) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001406
1407 out.unindent();
1408
Iliyan Malchev549e2592016-08-10 08:59:12 -07001409 out << "::android::status_t _hidl_err = ::android::OK;\n\n";
Iliyan Malchev549e2592016-08-10 08:59:12 -07001410 out << "switch (_hidl_code) {\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001411 out.indent();
1412
Yifan Hong10fe0b52016-10-19 14:20:17 -07001413 for (const auto &tuple : iface->allMethodsFromRoot()) {
1414 const Method *method = tuple.method();
1415 const Interface *superInterface = tuple.interface();
Steven Morelandf16c5c02017-07-31 16:50:06 -07001416
Howard Chen71f289f2017-08-29 17:35:01 +08001417 if (!isIBase() && method->isHidlReserved()) {
1418 continue;
1419 }
Yifan Hong10fe0b52016-10-19 14:20:17 -07001420 out << "case "
1421 << method->getSerialId()
1422 << " /* "
1423 << method->name()
1424 << " */:\n{\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001425
Yifan Hong10fe0b52016-10-19 14:20:17 -07001426 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001427
Steven Moreland77943692018-08-09 12:53:42 -07001428 out << "bool _hidl_is_oneway = _hidl_flags & " << Interface::FLAG_ONE_WAY->cppValue()
1429 << ";\n";
Steven Morelandebd8c722017-11-03 14:47:32 -07001430 out << "if (_hidl_is_oneway != " << (method->isOneway() ? "true" : "false") << ") ";
1431 out.block([&] { out << "return ::android::UNKNOWN_ERROR;\n"; }).endl().endl();
1432
Steven Moreland368e4602018-02-16 14:21:49 -08001433 generateStubSourceForMethod(out, method, superInterface);
Yifan Hong10fe0b52016-10-19 14:20:17 -07001434
1435 out.unindent();
1436 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001437 }
1438
1439 out << "default:\n{\n";
1440 out.indent();
1441
Martijn Coenen225bc922017-06-27 14:39:46 -07001442 if (iface->isIBase()) {
1443 out << "(void)_hidl_flags;\n";
1444 out << "return ::android::UNKNOWN_TRANSACTION;\n";
1445 } else {
1446 out << "return ";
1447 out << gIBaseFqName.getInterfaceStubFqName().cppName();
1448 out << "::onTransact(\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001449
Martijn Coenen225bc922017-06-27 14:39:46 -07001450 out.indent();
1451 out.indent();
Andreas Huber881227d2016-08-02 14:20:21 -07001452
Martijn Coenen225bc922017-06-27 14:39:46 -07001453 out << "_hidl_code, _hidl_data, _hidl_reply, "
1454 << "_hidl_flags, _hidl_cb);\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001455
Martijn Coenen225bc922017-06-27 14:39:46 -07001456 out.unindent();
1457 out.unindent();
1458 }
Andreas Huber881227d2016-08-02 14:20:21 -07001459
1460 out.unindent();
1461 out << "}\n";
1462
1463 out.unindent();
1464 out << "}\n\n";
1465
Yifan Honga018ed52016-12-13 16:35:08 -08001466 out.sIf("_hidl_err == ::android::UNEXPECTED_NULL", [&] {
1467 out << "_hidl_err = ::android::hardware::writeToParcel(\n";
1468 out.indent(2, [&] {
1469 out << "::android::hardware::Status::fromExceptionCode(::android::hardware::Status::EX_NULL_POINTER),\n";
1470 out << "_hidl_reply);\n";
1471 });
1472 });
Andreas Huber881227d2016-08-02 14:20:21 -07001473
Iliyan Malchev549e2592016-08-10 08:59:12 -07001474 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001475
1476 out.unindent();
1477 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001478}
1479
Steven Moreland368e4602018-02-16 14:21:49 -08001480void AST::generateStubSourceForMethod(Formatter& out, const Method* method,
1481 const Interface* superInterface) const {
Martijn Coenen115d4282016-12-19 05:14:04 +01001482 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
1483 method->cppImpl(IMPL_STUB, out);
1484 out << "break;\n";
Steven Moreland368e4602018-02-16 14:21:49 -08001485 return;
Martijn Coenen115d4282016-12-19 05:14:04 +01001486 }
1487
Steven Morelandf16c5c02017-07-31 16:50:06 -07001488 out << "_hidl_err = "
1489 << superInterface->fqName().cppNamespace()
1490 << "::"
1491 << superInterface->getStubName()
1492 << "::_hidl_"
1493 << method->name()
1494 << "(this, _hidl_data, _hidl_reply, _hidl_cb);\n";
1495 out << "break;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001496}
1497
Steven Moreland368e4602018-02-16 14:21:49 -08001498void AST::generateStaticStubMethodSource(Formatter& out, const FQName& fqName,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001499 const Method* method, const Interface* superInterface) const {
Steven Morelandf16c5c02017-07-31 16:50:06 -07001500 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
Steven Moreland368e4602018-02-16 14:21:49 -08001501 return;
Steven Morelandf16c5c02017-07-31 16:50:06 -07001502 }
1503
Steven Morelandf8197902018-01-30 15:38:37 -08001504 const std::string& klassName = fqName.getInterfaceStubName();
1505
Steven Morelandf16c5c02017-07-31 16:50:06 -07001506 out << "::android::status_t " << klassName << "::_hidl_" << method->name() << "(\n";
1507
1508 out.indent();
1509 out.indent();
1510
1511 out << "::android::hidl::base::V1_0::BnHwBase* _hidl_this,\n"
1512 << "const ::android::hardware::Parcel &_hidl_data,\n"
1513 << "::android::hardware::Parcel *_hidl_reply,\n"
1514 << "TransactCallback _hidl_cb) {\n";
1515
1516 out.unindent();
1517
1518 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
1519 out << "bool mEnableInstrumentation = _hidl_this->isInstrumentationEnabled();\n";
1520 out << "const auto &mInstrumentationCallbacks = _hidl_this->getInstrumentationCallbacks();\n";
1521 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
1522
1523 out << "::android::status_t _hidl_err = ::android::OK;\n";
1524
Yifan Hongeefe4f22017-01-04 15:32:42 -08001525 out << "if (!_hidl_data.enforceInterface("
Steven Morelandf16c5c02017-07-31 16:50:06 -07001526 << klassName
1527 << "::Pure::descriptor)) {\n";
Andreas Huber6cb08cf2016-08-03 15:44:51 -07001528
Andreas Huber881227d2016-08-02 14:20:21 -07001529 out.indent();
Iliyan Malchev549e2592016-08-10 08:59:12 -07001530 out << "_hidl_err = ::android::BAD_TYPE;\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001531 out << "return _hidl_err;\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001532 out.unindent();
1533 out << "}\n\n";
1534
Andreas Huber5e44a292016-09-27 14:52:39 -07001535 declareCppReaderLocals(out, method->args(), false /* forResults */);
Andreas Hubere7ff2282016-08-16 13:50:03 -07001536
Yifan Hongbf459bc2016-08-23 16:50:37 -07001537 // First DFS: write buffers
Andreas Huber881227d2016-08-02 14:20:21 -07001538 for (const auto &arg : method->args()) {
1539 emitCppReaderWriter(
1540 out,
Iliyan Malchev549e2592016-08-10 08:59:12 -07001541 "_hidl_data",
Andreas Huber881227d2016-08-02 14:20:21 -07001542 false /* parcelObjIsPointer */,
1543 arg,
1544 true /* reader */,
Steven Morelandf16c5c02017-07-31 16:50:06 -07001545 Type::ErrorMode_Return,
Andreas Huber5e44a292016-09-27 14:52:39 -07001546 false /* addPrefixToName */);
Andreas Huber881227d2016-08-02 14:20:21 -07001547 }
1548
Yifan Hongbf459bc2016-08-23 16:50:37 -07001549 // Second DFS: resolve references
1550 for (const auto &arg : method->args()) {
1551 emitCppResolveReferences(
1552 out,
1553 "_hidl_data",
1554 false /* parcelObjIsPointer */,
1555 arg,
1556 true /* reader */,
Steven Morelandf16c5c02017-07-31 16:50:06 -07001557 Type::ErrorMode_Return,
Yifan Hongbf459bc2016-08-23 16:50:37 -07001558 false /* addPrefixToName */);
1559 }
1560
Steven Moreland92a08a72017-07-31 14:57:37 -07001561 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001562 out,
1563 InstrumentationEvent::SERVER_API_ENTRY,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001564 method,
1565 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001566
Andreas Huber881227d2016-08-02 14:20:21 -07001567 const bool returnsValue = !method->results().empty();
Timur Iskhakov7fa79f62017-08-09 11:04:54 -07001568 const NamedReference<Type>* elidedReturn = method->canElideCallback();
Steven Moreland3e787002017-08-16 14:59:54 -07001569
1570 std::string callee;
1571
1572 if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB_IMPL)) {
1573 callee = "_hidl_this";
1574 } else {
Steven Morelandf8197902018-01-30 15:38:37 -08001575 callee = "static_cast<" + fqName.getInterfaceName() + "*>(_hidl_this->getImpl().get())";
Steven Moreland3e787002017-08-16 14:59:54 -07001576 }
Andreas Huber881227d2016-08-02 14:20:21 -07001577
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001578 if (elidedReturn != nullptr) {
Yifan Hong3b320f82016-11-01 15:15:54 -07001579 out << elidedReturn->type().getCppResultType()
Yifan Honga47eef32016-12-12 10:38:54 -08001580 << " _hidl_out_"
Yifan Hong3b320f82016-11-01 15:15:54 -07001581 << elidedReturn->name()
Martijn Coenen6ec2f0b2016-12-11 01:04:55 +01001582 << " = "
Yifan Hongcd2ae452017-01-31 14:33:40 -08001583 << callee << "->" << method->name()
Yifan Hong3b320f82016-11-01 15:15:54 -07001584 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001585
Yifan Hong932464e2017-03-30 15:40:22 -07001586 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001587 if (arg->type().resultNeedsDeref()) {
1588 out << "*";
1589 }
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001590 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001591 });
Andreas Huber881227d2016-08-02 14:20:21 -07001592
Steven Moreland2ae5bca2016-12-01 05:56:49 +00001593 out << ");\n\n";
Steven Moreland30232dc2019-03-05 19:39:10 -08001594
Yifan Hong859e53f2016-11-14 19:08:24 -08001595 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1596 << "_hidl_reply);\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001597
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001598 elidedReturn->type().emitReaderWriter(
1599 out,
Yifan Honga47eef32016-12-12 10:38:54 -08001600 "_hidl_out_" + elidedReturn->name(),
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001601 "_hidl_reply",
1602 true, /* parcelObjIsPointer */
1603 false, /* isReader */
1604 Type::ErrorMode_Ignore);
Andreas Huber881227d2016-08-02 14:20:21 -07001605
Yifan Hongbf459bc2016-08-23 16:50:37 -07001606 emitCppResolveReferences(
1607 out,
1608 "_hidl_reply",
1609 true /* parcelObjIsPointer */,
1610 elidedReturn,
1611 false /* reader */,
1612 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001613 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001614
Steven Moreland92a08a72017-07-31 14:57:37 -07001615 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001616 out,
1617 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001618 method,
1619 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001620
Iliyan Malchev549e2592016-08-10 08:59:12 -07001621 out << "_hidl_cb(*_hidl_reply);\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001622 } else {
1623 if (returnsValue) {
1624 out << "bool _hidl_callbackCalled = false;\n\n";
1625 }
Andreas Huber881227d2016-08-02 14:20:21 -07001626
Steven Moreland30232dc2019-03-05 19:39:10 -08001627 out << "::android::hardware::Return<void> _hidl_ret = " << callee << "->" << method->name()
1628 << "(";
Andreas Huber881227d2016-08-02 14:20:21 -07001629
Yifan Hong932464e2017-03-30 15:40:22 -07001630 out.join(method->args().begin(), method->args().end(), ", ", [&] (const auto &arg) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001631 if (arg->type().resultNeedsDeref()) {
1632 out << "*";
1633 }
1634
1635 out << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001636 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001637
1638 if (returnsValue) {
Yifan Hong932464e2017-03-30 15:40:22 -07001639 if (!method->args().empty()) {
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001640 out << ", ";
1641 }
1642
1643 out << "[&](";
1644
Yifan Hong932464e2017-03-30 15:40:22 -07001645 out.join(method->results().begin(), method->results().end(), ", ", [&](const auto &arg) {
Yifan Honga47eef32016-12-12 10:38:54 -08001646 out << "const auto &_hidl_out_" << arg->name();
Yifan Hong932464e2017-03-30 15:40:22 -07001647 });
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001648
1649 out << ") {\n";
1650 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001651 out << "if (_hidl_callbackCalled) {\n";
1652 out.indent();
1653 out << "LOG_ALWAYS_FATAL(\""
1654 << method->name()
1655 << ": _hidl_cb called a second time, but must be called once.\");\n";
1656 out.unindent();
1657 out << "}\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001658 out << "_hidl_callbackCalled = true;\n\n";
1659
Yifan Hong859e53f2016-11-14 19:08:24 -08001660 out << "::android::hardware::writeToParcel(::android::hardware::Status::ok(), "
1661 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001662
Yifan Hongbf459bc2016-08-23 16:50:37 -07001663 // First DFS: buffers
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001664 for (const auto &arg : method->results()) {
1665 emitCppReaderWriter(
1666 out,
1667 "_hidl_reply",
1668 true /* parcelObjIsPointer */,
1669 arg,
1670 false /* reader */,
Andreas Huber5e44a292016-09-27 14:52:39 -07001671 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001672 true /* addPrefixToName */);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001673 }
1674
Yifan Hongbf459bc2016-08-23 16:50:37 -07001675 // Second DFS: resolve references
1676 for (const auto &arg : method->results()) {
1677 emitCppResolveReferences(
1678 out,
1679 "_hidl_reply",
1680 true /* parcelObjIsPointer */,
1681 arg,
1682 false /* reader */,
1683 Type::ErrorMode_Ignore,
Yifan Honga47eef32016-12-12 10:38:54 -08001684 true /* addPrefixToName */);
Yifan Hongbf459bc2016-08-23 16:50:37 -07001685 }
1686
Steven Moreland92a08a72017-07-31 14:57:37 -07001687 generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001688 out,
1689 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001690 method,
1691 superInterface);
Zhuoyao Zhangde578002016-09-07 18:24:17 -07001692
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001693 out << "_hidl_cb(*_hidl_reply);\n";
1694
1695 out.unindent();
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001696 out << "});\n\n";
1697 } else {
1698 out << ");\n\n";
Steven Morelandf16c5c02017-07-31 16:50:06 -07001699 out << "(void) _hidl_cb;\n\n";
Steven Moreland92a08a72017-07-31 14:57:37 -07001700 generateCppInstrumentationCall(
Martijn Coenen8e4fc842017-01-09 16:28:59 +01001701 out,
1702 InstrumentationEvent::SERVER_API_EXIT,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001703 method,
1704 superInterface);
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001705 }
Iliyan Malchevd57066f2016-09-08 13:59:38 -07001706
Steven Moreland30232dc2019-03-05 19:39:10 -08001707 out << "_hidl_ret.assertOk();\n";
1708
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001709 if (returnsValue) {
1710 out << "if (!_hidl_callbackCalled) {\n";
1711 out.indent();
Steven Moreland05cd4232016-11-21 16:01:12 -08001712 out << "LOG_ALWAYS_FATAL(\""
1713 << method->name()
1714 << ": _hidl_cb not called, but must be called once.\");\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001715 out.unindent();
1716 out << "}\n\n";
Steven Moreland05cd4232016-11-21 16:01:12 -08001717 } else {
1718 out << "::android::hardware::writeToParcel("
1719 << "::android::hardware::Status::ok(), "
1720 << "_hidl_reply);\n\n";
Iliyan Malchev40d474a2016-08-16 06:20:17 -07001721 }
Andreas Huber881227d2016-08-02 14:20:21 -07001722 }
1723
Steven Morelandf16c5c02017-07-31 16:50:06 -07001724 out << "return _hidl_err;\n";
1725 out.unindent();
1726 out << "}\n\n";
Andreas Huber881227d2016-08-02 14:20:21 -07001727}
1728
Steven Moreland368e4602018-02-16 14:21:49 -08001729void AST::generatePassthroughHeader(Formatter& out) const {
Steven Moreland19f11b52017-05-12 18:22:21 -07001730 if (!AST::isInterface()) {
Steven Moreland69e7c702016-09-09 11:16:32 -07001731 // types.hal does not get a stub header.
Steven Moreland368e4602018-02-16 14:21:49 -08001732 return;
Steven Moreland69e7c702016-09-09 11:16:32 -07001733 }
1734
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001735 const Interface* iface = mRootScope.getInterface();
Steven Moreland19f11b52017-05-12 18:22:21 -07001736 CHECK(iface != nullptr);
Steven Moreland69e7c702016-09-09 11:16:32 -07001737
Yifan Hongeefe4f22017-01-04 15:32:42 -08001738 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001739
1740 bool supportOneway = iface->hasOnewayMethods();
1741
Steven Moreland69e7c702016-09-09 11:16:32 -07001742 const std::string guard = makeHeaderGuard(klassName);
1743
1744 out << "#ifndef " << guard << "\n";
1745 out << "#define " << guard << "\n\n";
1746
1747 std::vector<std::string> packageComponents;
1748 getPackageAndVersionComponents(
1749 &packageComponents, false /* cpp_compatible */);
1750
Steven Moreland61d3f4b2017-04-28 17:30:38 -07001751 out << "#include <android-base/macros.h>\n";
Yifan Hongb0949432016-12-15 15:32:24 -08001752 out << "#include <cutils/trace.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001753 out << "#include <future>\n";
Steven Morelandee88eed2016-10-31 17:49:00 -07001754
Steven Moreland19f11b52017-05-12 18:22:21 -07001755 generateCppPackageInclude(out, mPackage, iface->localName());
Steven Morelandee88eed2016-10-31 17:49:00 -07001756 out << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001757
Yifan Hong7a118f52016-12-07 11:21:15 -08001758 out << "#include <hidl/HidlPassthroughSupport.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001759 if (supportOneway) {
Yifan Hong2cbc1472016-10-25 19:02:40 -07001760 out << "#include <hidl/TaskRunner.h>\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001761 }
1762
1763 enterLeaveNamespace(out, true /* enter */);
1764 out << "\n";
1765
1766 out << "struct "
1767 << klassName
Steven Moreland19f11b52017-05-12 18:22:21 -07001768 << " : " << iface->localName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001769 << ", ::android::hardware::details::HidlInstrumentor {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001770
1771 out.indent();
1772 out << "explicit "
1773 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001774 << "(const ::android::sp<"
Steven Moreland19f11b52017-05-12 18:22:21 -07001775 << iface->localName()
Steven Moreland69e7c702016-09-09 11:16:32 -07001776 << "> impl);\n";
1777
Steven Moreland0b843772017-06-23 16:33:38 -07001778 out.endl();
1779 generateTemplatizationLink(out);
Steven Moreland1a52e822017-07-27 13:56:29 -07001780 generateCppTag(out, "android::hardware::details::bs_tag");
Steven Moreland0b843772017-06-23 16:33:38 -07001781
Steven Moreland616cf4d2018-10-02 13:52:18 -07001782 generateMethods(out, [&](const Method* method, const Interface* superInterface) {
1783 generatePassthroughMethod(out, method, superInterface);
Yifan Hong068c5522016-10-31 14:07:25 -07001784 });
Steven Moreland69e7c702016-09-09 11:16:32 -07001785
Steven Moreland69e7c702016-09-09 11:16:32 -07001786 out.unindent();
1787 out << "private:\n";
1788 out.indent();
Steven Moreland19f11b52017-05-12 18:22:21 -07001789 out << "const ::android::sp<" << iface->localName() << "> mImpl;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001790
1791 if (supportOneway) {
Yifan Hongef91d362017-03-20 17:18:13 -07001792 out << "::android::hardware::details::TaskRunner mOnewayQueue;\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001793
1794 out << "\n";
1795
1796 out << "::android::hardware::Return<void> addOnewayTask("
1797 "std::function<void(void)>);\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001798 }
1799
1800 out.unindent();
1801
1802 out << "};\n\n";
1803
1804 enterLeaveNamespace(out, false /* enter */);
1805
1806 out << "\n#endif // " << guard << "\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001807}
1808
Steven Moreland368e4602018-02-16 14:21:49 -08001809void AST::generateInterfaceSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001810 const Interface* iface = mRootScope.getInterface();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001811
Yifan Hong2d7126b2016-10-20 15:12:57 -07001812 // generate castFrom functions
Yifan Hong3d746092016-12-07 14:26:33 -08001813 std::string childTypeResult = iface->getCppResultType();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001814
Steven Moreland368e4602018-02-16 14:21:49 -08001815 generateMethods(out, [&](const Method* method, const Interface*) {
Steven Morelandd4b068a2017-03-20 06:30:51 -07001816 bool reserved = method->isHidlReserved();
1817
1818 if (!reserved) {
1819 out << "// no default implementation for: ";
1820 }
1821 method->generateCppSignature(out, iface->localName());
1822 if (reserved) {
1823 out.block([&]() {
Steven Moreland937408a2017-03-20 09:54:18 -07001824 method->cppImpl(IMPL_INTERFACE, out);
Steven Morelandd4b068a2017-03-20 06:30:51 -07001825 }).endl();
1826 }
1827
1828 out << "\n";
1829
Steven Moreland368e4602018-02-16 14:21:49 -08001830 return;
Steven Morelandd4b068a2017-03-20 06:30:51 -07001831 });
Steven Morelandd4b068a2017-03-20 06:30:51 -07001832
Yifan Hong3d746092016-12-07 14:26:33 -08001833 for (const Interface *superType : iface->typeChain()) {
Steven Moreland23cc5fa2018-05-09 10:48:48 -07001834 out << "::android::hardware::Return<"
Yifan Hong3d746092016-12-07 14:26:33 -08001835 << childTypeResult
Yifan Hong200209c2017-03-29 03:39:09 -07001836 << "> "
Yifan Hongeefe4f22017-01-04 15:32:42 -08001837 << iface->localName()
Yifan Hong3d746092016-12-07 14:26:33 -08001838 << "::castFrom("
1839 << superType->getCppArgumentType()
Yifan Hong200209c2017-03-29 03:39:09 -07001840 << " parent, bool "
1841 << (iface == superType ? "/* emitError */" : "emitError")
1842 << ") {\n";
Yifan Hong3d746092016-12-07 14:26:33 -08001843 out.indent();
1844 if (iface == superType) {
1845 out << "return parent;\n";
1846 } else {
Yifan Hong33e78012017-03-13 17:46:33 -07001847 out << "return ::android::hardware::details::castInterface<";
Yifan Hongeefe4f22017-01-04 15:32:42 -08001848 out << iface->localName() << ", "
Yifan Hongfe95aa22016-10-19 17:26:45 -07001849 << superType->fqName().cppName() << ", "
Steven Moreland57a89362017-07-21 19:29:54 +00001850 << iface->getProxyName()
Yifan Hongfe95aa22016-10-19 17:26:45 -07001851 << ">(\n";
1852 out.indent();
1853 out.indent();
1854 out << "parent, \""
1855 << iface->fqName().string()
Yifan Hong200209c2017-03-29 03:39:09 -07001856 << "\", emitError);\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001857 out.unindent();
1858 out.unindent();
Yifan Hongfe95aa22016-10-19 17:26:45 -07001859 }
Yifan Hong3d746092016-12-07 14:26:33 -08001860 out.unindent();
1861 out << "}\n\n";
Yifan Hongfe95aa22016-10-19 17:26:45 -07001862 }
Yifan Hongfe95aa22016-10-19 17:26:45 -07001863}
1864
Steven Moreland368e4602018-02-16 14:21:49 -08001865void AST::generatePassthroughSource(Formatter& out) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001866 const Interface* iface = mRootScope.getInterface();
Steven Moreland69e7c702016-09-09 11:16:32 -07001867
Yifan Hongeefe4f22017-01-04 15:32:42 -08001868 const std::string klassName = iface->getPassthroughName();
Steven Moreland69e7c702016-09-09 11:16:32 -07001869
1870 out << klassName
1871 << "::"
1872 << klassName
Steven Morelandc46e9842016-11-02 13:21:26 -07001873 << "(const ::android::sp<"
Steven Moreland69e7c702016-09-09 11:16:32 -07001874 << iface->fullName()
Zhuoyao Zhang7d3ac802017-02-15 21:05:49 +00001875 << "> impl) : ::android::hardware::details::HidlInstrumentor(\""
Zhuoyao Zhangd10feea2017-01-23 17:29:58 -08001876 << mPackage.string()
1877 << "\", \""
1878 << iface->localName()
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07001879 << "\"), mImpl(impl) {";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001880 if (iface->hasOnewayMethods()) {
1881 out << "\n";
Yifan Hong33223ca2016-12-13 15:07:35 -08001882 out.indent([&] {
Yifan Hongf01dad42017-03-20 19:03:11 -07001883 out << "mOnewayQueue.start(3000 /* similar limit to binderized */);\n";
Yifan Hong2cbc1472016-10-25 19:02:40 -07001884 });
1885 }
1886 out << "}\n\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001887
1888 if (iface->hasOnewayMethods()) {
1889 out << "::android::hardware::Return<void> "
1890 << klassName
1891 << "::addOnewayTask(std::function<void(void)> fun) {\n";
1892 out.indent();
Yifan Hong2cbc1472016-10-25 19:02:40 -07001893 out << "if (!mOnewayQueue.push(fun)) {\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001894 out.indent();
Steven Moreland67f67b42016-09-29 08:59:02 -07001895 out << "return ::android::hardware::Status::fromExceptionCode(\n";
1896 out.indent();
1897 out.indent();
Steven Moreland610002f2017-06-16 13:02:49 -07001898 out << "::android::hardware::Status::EX_TRANSACTION_FAILED,\n"
1899 << "\"Passthrough oneway function queue exceeds maximum size.\");\n";
Steven Moreland67f67b42016-09-29 08:59:02 -07001900 out.unindent();
1901 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001902 out.unindent();
Steven Moreland69e7c702016-09-09 11:16:32 -07001903 out << "}\n";
1904
Steven Morelandd366c262016-10-11 15:29:10 -07001905 out << "return ::android::hardware::Status();\n";
Steven Moreland69e7c702016-09-09 11:16:32 -07001906
1907 out.unindent();
1908 out << "}\n\n";
1909
1910
1911 }
Steven Moreland69e7c702016-09-09 11:16:32 -07001912}
1913
Steven Moreland92a08a72017-07-31 14:57:37 -07001914void AST::generateCppAtraceCall(Formatter &out,
Martijn Coenen7b295242016-11-04 16:52:56 +01001915 InstrumentationEvent event,
1916 const Method *method) const {
Timur Iskhakovcb0ba522017-07-17 20:01:37 -07001917 const Interface* iface = mRootScope.getInterface();
Yifan Hongeefe4f22017-01-04 15:32:42 -08001918 std::string baseString = "HIDL::" + iface->localName() + "::" + method->name();
Martijn Coenen7b295242016-11-04 16:52:56 +01001919 switch (event) {
1920 case SERVER_API_ENTRY:
1921 {
1922 out << "atrace_begin(ATRACE_TAG_HAL, \""
1923 << baseString + "::server\");\n";
1924 break;
1925 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001926 case PASSTHROUGH_ENTRY:
1927 {
1928 out << "atrace_begin(ATRACE_TAG_HAL, \""
1929 << baseString + "::passthrough\");\n";
1930 break;
1931 }
1932 case SERVER_API_EXIT:
Martijn Coenen7b295242016-11-04 16:52:56 +01001933 case PASSTHROUGH_EXIT:
1934 {
1935 out << "atrace_end(ATRACE_TAG_HAL);\n";
1936 break;
1937 }
Steven Moreland4607ef52018-05-09 10:52:47 -07001938 // client uses scope because of gotos
1939 // this isn't done for server because the profiled code isn't alone in its scope
1940 // this isn't done for passthrough becuase the profiled boundary isn't even in the same code
1941 case CLIENT_API_ENTRY: {
Michael Butler0a3d99a2018-07-26 13:47:10 -07001942 out << "::android::ScopedTrace PASTE(___tracer, __LINE__) (ATRACE_TAG_HAL, \""
1943 << baseString + "::client\");\n";
Steven Moreland4607ef52018-05-09 10:52:47 -07001944 break;
1945 }
1946 case CLIENT_API_EXIT:
1947 break;
Martijn Coenen7b295242016-11-04 16:52:56 +01001948 default:
1949 {
Steven Morelandcbff5612017-10-11 17:01:54 -07001950 CHECK(false) << "Unsupported instrumentation event: " << event;
Martijn Coenen7b295242016-11-04 16:52:56 +01001951 }
1952 }
Martijn Coenen7b295242016-11-04 16:52:56 +01001953}
1954
Steven Moreland92a08a72017-07-31 14:57:37 -07001955void AST::generateCppInstrumentationCall(
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001956 Formatter &out,
1957 InstrumentationEvent event,
Steven Moreland616cf4d2018-10-02 13:52:18 -07001958 const Method *method,
1959 const Interface* superInterface) const {
Steven Moreland92a08a72017-07-31 14:57:37 -07001960 generateCppAtraceCall(out, event, method);
Martijn Coenen7b295242016-11-04 16:52:56 +01001961
Steven Moreland30b76e92017-06-02 18:52:24 -07001962 out << "#ifdef __ANDROID_DEBUGGABLE__\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001963 out << "if (UNLIKELY(mEnableInstrumentation)) {\n";
1964 out.indent();
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001965 out << "std::vector<void *> _hidl_args;\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001966 std::string event_str = "";
1967 switch (event) {
1968 case SERVER_API_ENTRY:
1969 {
1970 event_str = "InstrumentationEvent::SERVER_API_ENTRY";
1971 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001972 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001973 << (arg->type().resultNeedsDeref() ? "" : "&")
1974 << arg->name()
1975 << ");\n";
1976 }
1977 break;
1978 }
1979 case SERVER_API_EXIT:
1980 {
1981 event_str = "InstrumentationEvent::SERVER_API_EXIT";
Steven Moreland031ccf12016-10-31 15:54:38 -07001982 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08001983 out << "_hidl_args.push_back((void *)&_hidl_out_"
Steven Moreland031ccf12016-10-31 15:54:38 -07001984 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001985 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001986 }
1987 break;
1988 }
1989 case CLIENT_API_ENTRY:
1990 {
1991 event_str = "InstrumentationEvent::CLIENT_API_ENTRY";
1992 for (const auto &arg : method->args()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07001993 out << "_hidl_args.push_back((void *)&"
1994 << arg->name()
1995 << ");\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07001996 }
1997 break;
1998 }
1999 case CLIENT_API_EXIT:
2000 {
2001 event_str = "InstrumentationEvent::CLIENT_API_EXIT";
2002 for (const auto &arg : method->results()) {
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002003 out << "_hidl_args.push_back((void *)"
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002004 << (arg->type().resultNeedsDeref() ? "" : "&")
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002005 << "_hidl_out_"
2006 << arg->name()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002007 << ");\n";
2008 }
2009 break;
2010 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002011 case PASSTHROUGH_ENTRY:
2012 {
2013 event_str = "InstrumentationEvent::PASSTHROUGH_ENTRY";
2014 for (const auto &arg : method->args()) {
2015 out << "_hidl_args.push_back((void *)&"
2016 << arg->name()
2017 << ");\n";
2018 }
2019 break;
2020 }
2021 case PASSTHROUGH_EXIT:
2022 {
2023 event_str = "InstrumentationEvent::PASSTHROUGH_EXIT";
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002024 for (const auto &arg : method->results()) {
Yifan Honga47eef32016-12-12 10:38:54 -08002025 out << "_hidl_args.push_back((void *)&_hidl_out_"
Zhuoyao Zhang085a8c32016-11-17 15:35:49 -08002026 << arg->name()
2027 << ");\n";
2028 }
Steven Moreland9b1cbdf2016-11-01 12:23:27 -07002029 break;
2030 }
Steven Moreland031ccf12016-10-31 15:54:38 -07002031 default:
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002032 {
Steven Morelandcbff5612017-10-11 17:01:54 -07002033 CHECK(false) << "Unsupported instrumentation event: " << event;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002034 }
2035 }
2036
Steven Moreland1ab31442016-11-03 18:37:51 -07002037 out << "for (const auto &callback: mInstrumentationCallbacks) {\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002038 out.indent();
2039 out << "callback("
2040 << event_str
2041 << ", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07002042 << superInterface->fqName().package()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002043 << "\", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07002044 << superInterface->fqName().version()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002045 << "\", \""
Steven Moreland616cf4d2018-10-02 13:52:18 -07002046 << superInterface->localName()
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002047 << "\", \""
2048 << method->name()
Zhuoyao Zhang964f72f2016-10-21 11:12:03 -07002049 << "\", &_hidl_args);\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002050 out.unindent();
2051 out << "}\n";
2052 out.unindent();
Steven Moreland30b76e92017-06-02 18:52:24 -07002053 out << "}\n";
2054 out << "#endif // __ANDROID_DEBUGGABLE__\n\n";
Zhuoyao Zhang8f492942016-09-28 14:27:56 -07002055}
2056
Andreas Huber881227d2016-08-02 14:20:21 -07002057} // namespace android